mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Move type editors into their own files
This commit is contained in:
		| @@ -150,6 +150,7 @@ module.exports = function(grunt) { | ||||
|                     "editor/js/ui/tab-config.js", | ||||
|                     "editor/js/ui/palette-editor.js", | ||||
|                     "editor/js/ui/editor.js", | ||||
|                     "editor/js/ui/editors/*.js", | ||||
|                     "editor/js/ui/tray.js", | ||||
|                     "editor/js/ui/clipboard.js", | ||||
|                     "editor/js/ui/library.js", | ||||
|   | ||||
| @@ -1818,658 +1818,22 @@ RED.editor = (function() { | ||||
|         RED.tray.show(trayOptions); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     var expressionTestCache = {}; | ||||
|  | ||||
|     function editExpression(options) { | ||||
|         var expressionTestCacheId = "_"; | ||||
|         if (editStack.length > 0) { | ||||
|             expressionTestCacheId = editStack[editStack.length-1].id; | ||||
|         } | ||||
|  | ||||
|         var value = options.value; | ||||
|         var onComplete = options.complete; | ||||
|         var type = "_expression" | ||||
|         editStack.push({type:type}); | ||||
|         RED.view.state(RED.state.EDITING); | ||||
|         var expressionEditor; | ||||
|         var testDataEditor; | ||||
|         var testResultEditor | ||||
|         var panels; | ||||
|  | ||||
|         var trayOptions = { | ||||
|             title: getEditStackTitle(), | ||||
|             width: "inherit", | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     id: "node-dialog-cancel", | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     id: "node-dialog-ok", | ||||
|                     text: RED._("common.label.done"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         $("#node-input-expression-help").html(""); | ||||
|                         onComplete(expressionEditor.getValue()); | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             resize: function(dimensions) { | ||||
|                 if (dimensions) { | ||||
|                     editTrayWidthCache[type] = dimensions.width; | ||||
|                 } | ||||
|                 var height = $("#dialog-form").height(); | ||||
|                 if (panels) { | ||||
|                     panels.resize(height); | ||||
|                 } | ||||
|  | ||||
|             }, | ||||
|             open: function(tray) { | ||||
|                 var trayBody = tray.find('.editor-tray-body'); | ||||
|                 trayBody.addClass("node-input-expression-editor") | ||||
|                 var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form','_expression','editor'); | ||||
|                 var funcSelect = $("#node-input-expression-func"); | ||||
|                 Object.keys(jsonata.functions).forEach(function(f) { | ||||
|                     funcSelect.append($("<option></option>").val(f).text(f)); | ||||
|                 }) | ||||
|                 funcSelect.change(function(e) { | ||||
|                     var f = $(this).val(); | ||||
|                     var args = RED._('jsonata:'+f+".args",{defaultValue:''}); | ||||
|                     var title = "<h5>"+f+"("+args+")</h5>"; | ||||
|                     var body = marked(RED._('jsonata:'+f+'.desc',{defaultValue:''})); | ||||
|                     $("#node-input-expression-help").html(title+"<p>"+body+"</p>"); | ||||
|  | ||||
|                 }) | ||||
|                 expressionEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-expression', | ||||
|                     value: "", | ||||
|                     mode:"ace/mode/jsonata", | ||||
|                     options: { | ||||
|                         enableBasicAutocompletion:true, | ||||
|                         enableSnippets:true, | ||||
|                         enableLiveAutocompletion: true | ||||
|                     } | ||||
|                 }); | ||||
|                 var currentToken = null; | ||||
|                 var currentTokenPos = -1; | ||||
|                 var currentFunctionMarker = null; | ||||
|  | ||||
|                 expressionEditor.getSession().setValue(value||"",-1); | ||||
|                 expressionEditor.on("changeSelection", function() { | ||||
|                     var c = expressionEditor.getCursorPosition(); | ||||
|                     var token = expressionEditor.getSession().getTokenAt(c.row,c.column); | ||||
|                     if (token !== currentToken || (token && /paren/.test(token.type) && c.column !== currentTokenPos)) { | ||||
|                         currentToken = token; | ||||
|                         var r,p; | ||||
|                         var scopedFunction = null; | ||||
|                         if (token && token.type === 'keyword') { | ||||
|                             r = c.row; | ||||
|                             scopedFunction = token; | ||||
|                         } else { | ||||
|                             var depth = 0; | ||||
|                             var next = false; | ||||
|                             if (token) { | ||||
|                                 if (token.type === 'paren.rparen') { | ||||
|                                     // If this is a block of parens ')))', set | ||||
|                                     // depth to offset against the cursor position | ||||
|                                     // within the block | ||||
|                                     currentTokenPos = c.column; | ||||
|                                     depth = c.column - (token.start + token.value.length); | ||||
|                                 } | ||||
|                                 r = c.row; | ||||
|                                 p = token.index; | ||||
|                             } else { | ||||
|                                 r = c.row-1; | ||||
|                                 p = -1; | ||||
|                             } | ||||
|                             while ( scopedFunction === null && r > -1) { | ||||
|                                 var rowTokens = expressionEditor.getSession().getTokens(r); | ||||
|                                 if (p === -1) { | ||||
|                                     p = rowTokens.length-1; | ||||
|                                 } | ||||
|                                 while (p > -1) { | ||||
|                                     var type = rowTokens[p].type; | ||||
|                                     if (next) { | ||||
|                                         if (type === 'keyword') { | ||||
|                                             scopedFunction = rowTokens[p]; | ||||
|                                             // console.log("HIT",scopedFunction); | ||||
|                                             break; | ||||
|                                         } | ||||
|                                         next = false; | ||||
|                                     } | ||||
|                                     if (type === 'paren.lparen') { | ||||
|                                         depth-=rowTokens[p].value.length; | ||||
|                                     } else if (type === 'paren.rparen') { | ||||
|                                         depth+=rowTokens[p].value.length; | ||||
|                                     } | ||||
|                                     if (depth < 0) { | ||||
|                                         next = true; | ||||
|                                         depth = 0; | ||||
|                                     } | ||||
|                                     // console.log(r,p,depth,next,rowTokens[p]); | ||||
|                                     p--; | ||||
|                                 } | ||||
|                                 if (!scopedFunction) { | ||||
|                                     r--; | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         expressionEditor.session.removeMarker(currentFunctionMarker); | ||||
|                         if (scopedFunction) { | ||||
|                         //console.log(token,.map(function(t) { return t.type})); | ||||
|                             funcSelect.val(scopedFunction.value).change(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 dialogForm.i18n(); | ||||
|                 $("#node-input-expression-func-insert").click(function(e) { | ||||
|                     e.preventDefault(); | ||||
|                     var pos = expressionEditor.getCursorPosition(); | ||||
|                     var f = funcSelect.val(); | ||||
|                     var snippet = jsonata.getFunctionSnippet(f); | ||||
|                     expressionEditor.insertSnippet(snippet); | ||||
|                     expressionEditor.focus(); | ||||
|                 }); | ||||
|                 $("#node-input-expression-reformat").click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     var v = expressionEditor.getValue()||""; | ||||
|                     try { | ||||
|                         v = jsonata.format(v); | ||||
|                     } catch(err) { | ||||
|                         // TODO: do an optimistic auto-format | ||||
|                     } | ||||
|                     expressionEditor.getSession().setValue(v||"",-1); | ||||
|                 }); | ||||
|  | ||||
|                 var tabs = RED.tabs.create({ | ||||
|                     element: $("#node-input-expression-tabs"), | ||||
|                     onchange:function(tab) { | ||||
|                         $(".node-input-expression-tab-content").hide(); | ||||
|                         tab.content.show(); | ||||
|                         trayOptions.resize(); | ||||
|                     } | ||||
|                 }) | ||||
|  | ||||
|                 tabs.addTab({ | ||||
|                     id: 'expression-help', | ||||
|                     label: RED._('expressionEditor.functionReference'), | ||||
|                     content: $("#node-input-expression-tab-help") | ||||
|                 }); | ||||
|                 tabs.addTab({ | ||||
|                     id: 'expression-tests', | ||||
|                     label: RED._('expressionEditor.test'), | ||||
|                     content: $("#node-input-expression-tab-test") | ||||
|                 }); | ||||
|                 testDataEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-expression-test-data', | ||||
|                     value: expressionTestCache[expressionTestCacheId] || '{\n    "payload": "hello world"\n}', | ||||
|                     mode:"ace/mode/json", | ||||
|                     lineNumbers: false | ||||
|                 }); | ||||
|                 var changeTimer; | ||||
|                 $(".node-input-expression-legacy").click(function(e) { | ||||
|                     e.preventDefault(); | ||||
|                     RED.sidebar.info.set(RED._("expressionEditor.compatModeDesc")); | ||||
|                     RED.sidebar.info.show(); | ||||
|                 }) | ||||
|                 var testExpression = function() { | ||||
|                     var value = testDataEditor.getValue(); | ||||
|                     var parsedData; | ||||
|                     var currentExpression = expressionEditor.getValue(); | ||||
|                     var expr; | ||||
|                     var usesContext = false; | ||||
|                     var legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(currentExpression); | ||||
|                     $(".node-input-expression-legacy").toggle(legacyMode); | ||||
|                     try { | ||||
|                         expr = jsonata(currentExpression); | ||||
|                         expr.assign('flowContext',function(val) { | ||||
|                             usesContext = true; | ||||
|                             return null; | ||||
|                         }); | ||||
|                         expr.assign('globalContext',function(val) { | ||||
|                             usesContext = true; | ||||
|                             return null; | ||||
|                         }); | ||||
|                     } catch(err) { | ||||
|                         testResultEditor.setValue(RED._("expressionEditor.errors.invalid-expr",{message:err.message}),-1); | ||||
|                         return; | ||||
|                     } | ||||
|                     try { | ||||
|                         parsedData = JSON.parse(value); | ||||
|                     } catch(err) { | ||||
|                         testResultEditor.setValue(RED._("expressionEditor.errors.invalid-msg",{message:err.toString()})) | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     try { | ||||
|                         var result = expr.evaluate(legacyMode?{msg:parsedData}:parsedData); | ||||
|                         if (usesContext) { | ||||
|                             testResultEditor.setValue(RED._("expressionEditor.errors.context-unsupported"),-1); | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         var formattedResult; | ||||
|                         if (result !== undefined) { | ||||
|                             formattedResult = JSON.stringify(result,null,4); | ||||
|                         } else { | ||||
|                             formattedResult = RED._("expressionEditor.noMatch"); | ||||
|                         } | ||||
|                         testResultEditor.setValue(formattedResult,-1); | ||||
|                     } catch(err) { | ||||
|                         testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 testDataEditor.getSession().on('change', function() { | ||||
|                     clearTimeout(changeTimer); | ||||
|                     changeTimer = setTimeout(testExpression,200); | ||||
|                     expressionTestCache[expressionTestCacheId] = testDataEditor.getValue(); | ||||
|                 }); | ||||
|                 expressionEditor.getSession().on('change', function() { | ||||
|                     clearTimeout(changeTimer); | ||||
|                     changeTimer = setTimeout(testExpression,200); | ||||
|                 }); | ||||
|  | ||||
|                 testResultEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-expression-test-result', | ||||
|                     value: "", | ||||
|                     mode:"ace/mode/json", | ||||
|                     lineNumbers: false, | ||||
|                     readOnly: true | ||||
|                 }); | ||||
|                 panels = RED.panels.create({ | ||||
|                     id:"node-input-expression-panels", | ||||
|                     resize: function(p1Height,p2Height) { | ||||
|                         var p1 = $("#node-input-expression-panel-expr"); | ||||
|                         p1Height -= $(p1.children()[0]).outerHeight(true); | ||||
|                         var editorRow = $(p1.children()[1]); | ||||
|                         p1Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); | ||||
|                         $("#node-input-expression").css("height",(p1Height-5)+"px"); | ||||
|                         expressionEditor.resize(); | ||||
|  | ||||
|                         var p2 = $("#node-input-expression-panel-info > .form-row > div:first-child"); | ||||
|                         p2Height -= p2.outerHeight(true) + 20; | ||||
|                         $(".node-input-expression-tab-content").height(p2Height); | ||||
|                         $("#node-input-expression-test-data").css("height",(p2Height-5)+"px"); | ||||
|                         testDataEditor.resize(); | ||||
|                         $("#node-input-expression-test-result").css("height",(p2Height-5)+"px"); | ||||
|                         testResultEditor.resize(); | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 $("#node-input-example-reformat").click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     var v = testDataEditor.getValue()||""; | ||||
|                     try { | ||||
|                         v = JSON.stringify(JSON.parse(v),null,4); | ||||
|                     } catch(err) { | ||||
|                         // TODO: do an optimistic auto-format | ||||
|                     } | ||||
|                     testDataEditor.getSession().setValue(v||"",-1); | ||||
|                 }); | ||||
|  | ||||
|                 testExpression(); | ||||
|             }, | ||||
|             close: function() { | ||||
|                 editStack.pop(); | ||||
|                 expressionEditor.destroy(); | ||||
|                 testDataEditor.destroy(); | ||||
|             }, | ||||
|             show: function() {} | ||||
|         } | ||||
|         RED.tray.show(trayOptions); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function editJSON(options) { | ||||
|         var value = options.value; | ||||
|         var onComplete = options.complete; | ||||
|         var type = "_json" | ||||
|         editStack.push({type:type}); | ||||
|         RED.view.state(RED.state.EDITING); | ||||
|         var expressionEditor; | ||||
|         var changeTimer; | ||||
|  | ||||
|         var checkValid = function() { | ||||
|             var v = expressionEditor.getValue(); | ||||
|             try { | ||||
|                 JSON.parse(v); | ||||
|                 $("#node-dialog-ok").removeClass('disabled'); | ||||
|                 return true; | ||||
|             } catch(err) { | ||||
|                 $("#node-dialog-ok").addClass('disabled'); | ||||
|                 return false; | ||||
|     function showTypeEditor(type, options) { | ||||
|         if (RED.editor.types.hasOwnProperty(type)) { | ||||
|             if (editStack.length > 0) { | ||||
|                 options.parent = editStack[editStack.length-1].id; | ||||
|             } | ||||
|         } | ||||
|         var trayOptions = { | ||||
|             title: options.title || getEditStackTitle(), | ||||
|             width: "inherit", | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     id: "node-dialog-cancel", | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     id: "node-dialog-ok", | ||||
|                     text: RED._("common.label.done"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         if (options.requireValid && !checkValid()) { | ||||
|                             return; | ||||
|                         } | ||||
|                         onComplete(expressionEditor.getValue()); | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             resize: function(dimensions) { | ||||
|                 editTrayWidthCache[type] = dimensions.width; | ||||
|  | ||||
|                 var rows = $("#dialog-form>div:not(.node-text-editor-row)"); | ||||
|                 var editorRow = $("#dialog-form>div.node-text-editor-row"); | ||||
|                 var height = $("#dialog-form").height(); | ||||
|                 for (var i=0;i<rows.size();i++) { | ||||
|                     height -= $(rows[i]).outerHeight(true); | ||||
|                 } | ||||
|                 height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); | ||||
|                 $(".node-text-editor").css("height",height+"px"); | ||||
|                 expressionEditor.resize(); | ||||
|             }, | ||||
|             open: function(tray) { | ||||
|                 var trayBody = tray.find('.editor-tray-body'); | ||||
|                 var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor'); | ||||
|                 expressionEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-json', | ||||
|                     value: "", | ||||
|                     mode:"ace/mode/json" | ||||
|                 }); | ||||
|                 expressionEditor.getSession().setValue(value||"",-1); | ||||
|                 if (options.requireValid) { | ||||
|                     expressionEditor.getSession().on('change', function() { | ||||
|                         clearTimeout(changeTimer); | ||||
|                         changeTimer = setTimeout(checkValid,200); | ||||
|                     }); | ||||
|                     checkValid(); | ||||
|                 } | ||||
|                 $("#node-input-json-reformat").click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     var v = expressionEditor.getValue()||""; | ||||
|                     try { | ||||
|                         v = JSON.stringify(JSON.parse(v),null,4); | ||||
|                     } catch(err) { | ||||
|                         // TODO: do an optimistic auto-format | ||||
|                     } | ||||
|                     expressionEditor.getSession().setValue(v||"",-1); | ||||
|                 }); | ||||
|                 dialogForm.i18n(); | ||||
|             }, | ||||
|             close: function() { | ||||
|             editStack.push({type:type}); | ||||
|             options.title = options.title || getEditStackTitle(); | ||||
|             options.onclose = function() { | ||||
|                 editStack.pop(); | ||||
|                 expressionEditor.destroy(); | ||||
|             }, | ||||
|             show: function() {} | ||||
|         } | ||||
|         RED.tray.show(trayOptions); | ||||
|     } | ||||
|  | ||||
|     function editMarkdown(options) { | ||||
|         var value = options.value; | ||||
|         var onComplete = options.complete; | ||||
|         var type = "_markdown" | ||||
|         editStack.push({type:type}); | ||||
|         RED.view.state(RED.state.EDITING); | ||||
|         var expressionEditor; | ||||
|  | ||||
|         var trayOptions = { | ||||
|             title: options.title || getEditStackTitle(), | ||||
|             width: "inherit", | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     id: "node-dialog-cancel", | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     id: "node-dialog-ok", | ||||
|                     text: RED._("common.label.done"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         onComplete(expressionEditor.getValue()); | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             resize: function(dimensions) { | ||||
|                 editTrayWidthCache[type] = dimensions.width; | ||||
|  | ||||
|                 var rows = $("#dialog-form>div:not(.node-text-editor-row)"); | ||||
|                 var editorRow = $("#dialog-form>div.node-text-editor-row"); | ||||
|                 var height = $("#dialog-form").height(); | ||||
|                 for (var i=0;i<rows.size();i++) { | ||||
|                     height -= $(rows[i]).outerHeight(true); | ||||
|                 } | ||||
|                 height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); | ||||
|                 $(".node-text-editor").css("height",height+"px"); | ||||
|                 expressionEditor.resize(); | ||||
|             }, | ||||
|             open: function(tray) { | ||||
|                 var trayBody = tray.find('.editor-tray-body'); | ||||
|                 var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor'); | ||||
|                 expressionEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-markdown', | ||||
|                     value: value, | ||||
|                     mode:"ace/mode/markdown" | ||||
|                 }); | ||||
|                 if (options.header) { | ||||
|                     options.header.appendTo(tray.find('#node-input-markdown-title')); | ||||
|                 } | ||||
|  | ||||
|                 dialogForm.i18n(); | ||||
|             }, | ||||
|             close: function() { | ||||
|                 editStack.pop(); | ||||
|                 expressionEditor.destroy(); | ||||
|             }, | ||||
|             show: function() {} | ||||
|         } | ||||
|         RED.tray.show(trayOptions); | ||||
|     } | ||||
|  | ||||
|     function stringToUTF8Array(str) { | ||||
|         var data = []; | ||||
|         var i=0, l = str.length; | ||||
|         for (i=0; i<l; i++) { | ||||
|             var char = str.charCodeAt(i); | ||||
|             if (char < 0x80) { | ||||
|                 data.push(char); | ||||
|             } else if (char < 0x800) { | ||||
|                 data.push(0xc0 | (char >> 6)); | ||||
|                 data.push(0x80 | (char & 0x3f)); | ||||
|             } else if (char < 0xd800 || char >= 0xe000) { | ||||
|                 data.push(0xe0 | (char >> 12)); | ||||
|                 data.push(0x80 | ((char>>6) & 0x3f)); | ||||
|                 data.push(0x80 | (char & 0x3f)); | ||||
|             } else { | ||||
|                 i++; | ||||
|                 char = 0x10000 + (((char & 0x3ff)<<10) | (str.charAt(i) & 0x3ff)); | ||||
|                 data.push(0xf0 | (char >>18)); | ||||
|                 data.push(0x80 | ((char>>12) & 0x3f)); | ||||
|                 data.push(0x80 | ((char>>6) & 0x3f)); | ||||
|                 data.push(0x80 | (char & 0x3f)); | ||||
|             } | ||||
|             RED.editor.types[type].show(options); | ||||
|         } else { | ||||
|             console.log("Unknown type editor:",type); | ||||
|         } | ||||
|         return data; | ||||
|     } | ||||
|  | ||||
|     function editBuffer(options) { | ||||
|         var value = options.value; | ||||
|         var onComplete = options.complete; | ||||
|         var type = "_buffer" | ||||
|         editStack.push({type:type}); | ||||
|         RED.view.state(RED.state.EDITING); | ||||
|         var bufferStringEditor = []; | ||||
|         var bufferBinValue; | ||||
|  | ||||
|         var panels; | ||||
|  | ||||
|         var trayOptions = { | ||||
|             title: getEditStackTitle(), | ||||
|             width: "inherit", | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     id: "node-dialog-cancel", | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     id: "node-dialog-ok", | ||||
|                     text: RED._("common.label.done"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         onComplete(JSON.stringify(bufferBinValue)); | ||||
|                         RED.tray.close(); | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             resize: function(dimensions) { | ||||
|                 if (dimensions) { | ||||
|                     editTrayWidthCache[type] = dimensions.width; | ||||
|                 } | ||||
|                 var height = $("#dialog-form").height(); | ||||
|                 if (panels) { | ||||
|                     panels.resize(height); | ||||
|                 } | ||||
|             }, | ||||
|             open: function(tray) { | ||||
|                 var trayBody = tray.find('.editor-tray-body'); | ||||
|                 var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor'); | ||||
|  | ||||
|                 bufferStringEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-buffer-str', | ||||
|                     value: "", | ||||
|                     mode:"ace/mode/text" | ||||
|                 }); | ||||
|                 bufferStringEditor.getSession().setValue(value||"",-1); | ||||
|  | ||||
|                 bufferBinEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-buffer-bin', | ||||
|                     value: "", | ||||
|                     mode:"ace/mode/text", | ||||
|                     readOnly: true | ||||
|                 }); | ||||
|  | ||||
|                 var changeTimer; | ||||
|                 var buildBuffer = function(data) { | ||||
|                     var valid = true; | ||||
|                     var isString = typeof data === 'string'; | ||||
|                     var binBuffer = []; | ||||
|                     if (isString) { | ||||
|                         bufferBinValue = stringToUTF8Array(data); | ||||
|                     } else { | ||||
|                         bufferBinValue = data; | ||||
|                     } | ||||
|                     var i=0,l=bufferBinValue.length; | ||||
|                     var c = 0; | ||||
|                     for(i=0;i<l;i++) { | ||||
|                         var d = parseInt(bufferBinValue[i]); | ||||
|                         if (!isString && (isNaN(d) || d < 0 || d > 255)) { | ||||
|                             valid = false; | ||||
|                             break; | ||||
|                         } | ||||
|                         if (i>0) { | ||||
|                             if (i%8 === 0) { | ||||
|                                 if (i%16 === 0) { | ||||
|                                     binBuffer.push("\n"); | ||||
|                                 } else { | ||||
|                                     binBuffer.push("  "); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 binBuffer.push(" "); | ||||
|                             } | ||||
|                         } | ||||
|                         binBuffer.push((d<16?"0":"")+d.toString(16).toUpperCase()); | ||||
|                     } | ||||
|                     if (valid) { | ||||
|                         $("#node-input-buffer-type-string").toggle(isString); | ||||
|                         $("#node-input-buffer-type-array").toggle(!isString); | ||||
|                         bufferBinEditor.setValue(binBuffer.join(""),1); | ||||
|                     } | ||||
|                     return valid; | ||||
|                 } | ||||
|                 var bufferStringUpdate = function() { | ||||
|                     var value = bufferStringEditor.getValue(); | ||||
|                     var isValidArray = false; | ||||
|                     if (/^[\s]*\[[\s\S]*\][\s]*$/.test(value)) { | ||||
|                         isValidArray = true; | ||||
|                         try { | ||||
|                             var data = JSON.parse(value); | ||||
|                             isValidArray = buildBuffer(data); | ||||
|                         } catch(err) { | ||||
|                             isValidArray = false; | ||||
|                         } | ||||
|                     } | ||||
|                     if (!isValidArray) { | ||||
|                         buildBuffer(value); | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|                 bufferStringEditor.getSession().on('change', function() { | ||||
|                     clearTimeout(changeTimer); | ||||
|                     changeTimer = setTimeout(bufferStringUpdate,200); | ||||
|                 }); | ||||
|  | ||||
|                 bufferStringUpdate(); | ||||
|  | ||||
|                 dialogForm.i18n(); | ||||
|  | ||||
|                 panels = RED.panels.create({ | ||||
|                     id:"node-input-buffer-panels", | ||||
|                     resize: function(p1Height,p2Height) { | ||||
|                         var p1 = $("#node-input-buffer-panel-str"); | ||||
|                         p1Height -= $(p1.children()[0]).outerHeight(true); | ||||
|                         var editorRow = $(p1.children()[1]); | ||||
|                         p1Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); | ||||
|                         $("#node-input-buffer-str").css("height",(p1Height-5)+"px"); | ||||
|                         bufferStringEditor.resize(); | ||||
|  | ||||
|                         var p2 = $("#node-input-buffer-panel-bin"); | ||||
|                         editorRow = $(p2.children()[0]); | ||||
|                         p2Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); | ||||
|                         $("#node-input-buffer-bin").css("height",(p2Height-5)+"px"); | ||||
|                         bufferBinEditor.resize(); | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 $(".node-input-buffer-type").click(function(e) { | ||||
|                     e.preventDefault(); | ||||
|                     RED.sidebar.info.set(RED._("bufferEditor.modeDesc")); | ||||
|                     RED.sidebar.info.show(); | ||||
|                 }) | ||||
|  | ||||
|  | ||||
|             }, | ||||
|             close: function() { | ||||
|                 editStack.pop(); | ||||
|                 bufferStringEditor.destroy(); | ||||
|                 bufferBinEditor.destroy(); | ||||
|             }, | ||||
|             show: function() {} | ||||
|         } | ||||
|         RED.tray.show(trayOptions); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
| @@ -2482,14 +1846,22 @@ RED.editor = (function() { | ||||
|                 $("#node-dialog-cancel").click(); | ||||
|                 $("#node-config-dialog-cancel").click(); | ||||
|             }); | ||||
|  | ||||
|             for (var type in RED.editor.types) { | ||||
|                 if (RED.editor.types.hasOwnProperty(type)) { | ||||
|                     RED.editor.types[type].init(); | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         types: {}, | ||||
|         edit: showEditDialog, | ||||
|         editConfig: showEditConfigNodeDialog, | ||||
|         editSubflow: showEditSubflowDialog, | ||||
|         editExpression: editExpression, | ||||
|         editJSON: editJSON, | ||||
|         editMarkdown: editMarkdown, | ||||
|         editBuffer: editBuffer, | ||||
|         editExpression: function(options) { showTypeEditor("_expression", options) }, | ||||
|         editJSON: function(options) { showTypeEditor("_json", options) }, | ||||
|         editMarkdown: function(options) { showTypeEditor("_markdown", options) }, | ||||
|         editBuffer: function(options) { showTypeEditor("_buffer", options) }, | ||||
|         buildEditForm: buildEditForm, | ||||
|         validateNode: validateNode, | ||||
|         updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo | ||||
|  | ||||
|   | ||||
							
								
								
									
										209
									
								
								editor/js/ui/editors/buffer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								editor/js/ui/editors/buffer.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| /** | ||||
|  * 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.editor.types._buffer = (function() { | ||||
|  | ||||
|  | ||||
|     var template = '<script type="text/x-red" data-template-name="_buffer"><div id="node-input-buffer-panels"><div id="node-input-buffer-panel-str" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><span class="node-input-buffer-type"><i class="fa fa-exclamation-circle"></i> <span id="node-input-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="node-input-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></span></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="node-input-buffer-str"></div></div></div><div id="node-input-buffer-panel-bin" class="red-ui-panel"><div class="form-row node-text-editor-row" style="margin-top: 10px"><div class="node-text-editor" id="node-input-buffer-bin"></div></div></div></div></script>'; | ||||
|  | ||||
|     function stringToUTF8Array(str) { | ||||
|         var data = []; | ||||
|         var i=0, l = str.length; | ||||
|         for (i=0; i<l; i++) { | ||||
|             var char = str.charCodeAt(i); | ||||
|             if (char < 0x80) { | ||||
|                 data.push(char); | ||||
|             } else if (char < 0x800) { | ||||
|                 data.push(0xc0 | (char >> 6)); | ||||
|                 data.push(0x80 | (char & 0x3f)); | ||||
|             } else if (char < 0xd800 || char >= 0xe000) { | ||||
|                 data.push(0xe0 | (char >> 12)); | ||||
|                 data.push(0x80 | ((char>>6) & 0x3f)); | ||||
|                 data.push(0x80 | (char & 0x3f)); | ||||
|             } else { | ||||
|                 i++; | ||||
|                 char = 0x10000 + (((char & 0x3ff)<<10) | (str.charAt(i) & 0x3ff)); | ||||
|                 data.push(0xf0 | (char >>18)); | ||||
|                 data.push(0x80 | ((char>>12) & 0x3f)); | ||||
|                 data.push(0x80 | ((char>>6) & 0x3f)); | ||||
|                 data.push(0x80 | (char & 0x3f)); | ||||
|             } | ||||
|         } | ||||
|         return data; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|             $(template).appendTo(document.body); | ||||
|         }, | ||||
|         show: function(options) { | ||||
|             var value = options.value; | ||||
|             var onComplete = options.complete; | ||||
|             var type = "_buffer" | ||||
|             RED.view.state(RED.state.EDITING); | ||||
|             var bufferStringEditor = []; | ||||
|             var bufferBinValue; | ||||
|  | ||||
|             var panels; | ||||
|  | ||||
|             var trayOptions = { | ||||
|                 title: options.title, | ||||
|                 width: "inherit", | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "node-dialog-cancel", | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-ok", | ||||
|                         text: RED._("common.label.done"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|                             onComplete(JSON.stringify(bufferBinValue)); | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 resize: function(dimensions) { | ||||
|                     var height = $("#dialog-form").height(); | ||||
|                     if (panels) { | ||||
|                         panels.resize(height); | ||||
|                     } | ||||
|                 }, | ||||
|                 open: function(tray) { | ||||
|                     var trayBody = tray.find('.editor-tray-body'); | ||||
|                     var dialogForm = RED.editor.buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor'); | ||||
|  | ||||
|                     bufferStringEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-buffer-str', | ||||
|                         value: "", | ||||
|                         mode:"ace/mode/text" | ||||
|                     }); | ||||
|                     bufferStringEditor.getSession().setValue(value||"",-1); | ||||
|  | ||||
|                     bufferBinEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-buffer-bin', | ||||
|                         value: "", | ||||
|                         mode:"ace/mode/text", | ||||
|                         readOnly: true | ||||
|                     }); | ||||
|  | ||||
|                     var changeTimer; | ||||
|                     var buildBuffer = function(data) { | ||||
|                         var valid = true; | ||||
|                         var isString = typeof data === 'string'; | ||||
|                         var binBuffer = []; | ||||
|                         if (isString) { | ||||
|                             bufferBinValue = stringToUTF8Array(data); | ||||
|                         } else { | ||||
|                             bufferBinValue = data; | ||||
|                         } | ||||
|                         var i=0,l=bufferBinValue.length; | ||||
|                         var c = 0; | ||||
|                         for(i=0;i<l;i++) { | ||||
|                             var d = parseInt(bufferBinValue[i]); | ||||
|                             if (!isString && (isNaN(d) || d < 0 || d > 255)) { | ||||
|                                 valid = false; | ||||
|                                 break; | ||||
|                             } | ||||
|                             if (i>0) { | ||||
|                                 if (i%8 === 0) { | ||||
|                                     if (i%16 === 0) { | ||||
|                                         binBuffer.push("\n"); | ||||
|                                     } else { | ||||
|                                         binBuffer.push("  "); | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     binBuffer.push(" "); | ||||
|                                 } | ||||
|                             } | ||||
|                             binBuffer.push((d<16?"0":"")+d.toString(16).toUpperCase()); | ||||
|                         } | ||||
|                         if (valid) { | ||||
|                             $("#node-input-buffer-type-string").toggle(isString); | ||||
|                             $("#node-input-buffer-type-array").toggle(!isString); | ||||
|                             bufferBinEditor.setValue(binBuffer.join(""),1); | ||||
|                         } | ||||
|                         return valid; | ||||
|                     } | ||||
|                     var bufferStringUpdate = function() { | ||||
|                         var value = bufferStringEditor.getValue(); | ||||
|                         var isValidArray = false; | ||||
|                         if (/^[\s]*\[[\s\S]*\][\s]*$/.test(value)) { | ||||
|                             isValidArray = true; | ||||
|                             try { | ||||
|                                 var data = JSON.parse(value); | ||||
|                                 isValidArray = buildBuffer(data); | ||||
|                             } catch(err) { | ||||
|                                 isValidArray = false; | ||||
|                             } | ||||
|                         } | ||||
|                         if (!isValidArray) { | ||||
|                             buildBuffer(value); | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|                     bufferStringEditor.getSession().on('change', function() { | ||||
|                         clearTimeout(changeTimer); | ||||
|                         changeTimer = setTimeout(bufferStringUpdate,200); | ||||
|                     }); | ||||
|  | ||||
|                     bufferStringUpdate(); | ||||
|  | ||||
|                     dialogForm.i18n(); | ||||
|  | ||||
|                     panels = RED.panels.create({ | ||||
|                         id:"node-input-buffer-panels", | ||||
|                         resize: function(p1Height,p2Height) { | ||||
|                             var p1 = $("#node-input-buffer-panel-str"); | ||||
|                             p1Height -= $(p1.children()[0]).outerHeight(true); | ||||
|                             var editorRow = $(p1.children()[1]); | ||||
|                             p1Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); | ||||
|                             $("#node-input-buffer-str").css("height",(p1Height-5)+"px"); | ||||
|                             bufferStringEditor.resize(); | ||||
|  | ||||
|                             var p2 = $("#node-input-buffer-panel-bin"); | ||||
|                             editorRow = $(p2.children()[0]); | ||||
|                             p2Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); | ||||
|                             $("#node-input-buffer-bin").css("height",(p2Height-5)+"px"); | ||||
|                             bufferBinEditor.resize(); | ||||
|                         } | ||||
|                     }); | ||||
|  | ||||
|                     $(".node-input-buffer-type").click(function(e) { | ||||
|                         e.preventDefault(); | ||||
|                         RED.sidebar.info.set(RED._("bufferEditor.modeDesc")); | ||||
|                         RED.sidebar.info.show(); | ||||
|                     }) | ||||
|  | ||||
|  | ||||
|                 }, | ||||
|                 close: function() { | ||||
|                     if (options.onclose) { | ||||
|                         options.onclose(); | ||||
|                     } | ||||
|                     bufferStringEditor.destroy(); | ||||
|                     bufferBinEditor.destroy(); | ||||
|                 }, | ||||
|                 show: function() {} | ||||
|             } | ||||
|             RED.tray.show(trayOptions); | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
							
								
								
									
										325
									
								
								editor/js/ui/editors/expression.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								editor/js/ui/editors/expression.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,325 @@ | ||||
| /** | ||||
|  * 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.editor.types._expression = (function() { | ||||
|  | ||||
|  | ||||
|     var template = '<script type="text/x-red" data-template-name="_expression"><div id="node-input-expression-panels"><div id="node-input-expression-panel-expr" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><span class="node-input-expression-legacy"><i class="fa fa-exclamation-circle"></i> <span data-i18n="expressionEditor.compatMode"></span></span><button id="node-input-expression-reformat" class="editor-button editor-button-small"><span data-i18n="expressionEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="node-input-expression"></div></div></div><div id="node-input-expression-panel-info" class="red-ui-panel"><div class="form-row"><ul id="node-input-expression-tabs"></ul><div id="node-input-expression-tab-help" class="node-input-expression-tab-content hide"><div><select id="node-input-expression-func"></select><button id="node-input-expression-func-insert" class="editor-button" data-i18n="expressionEditor.insert"></button></div><div id="node-input-expression-help"></div></div><div id="node-input-expression-tab-test" class="node-input-expression-tab-content hide"><div><span style="display: inline-block; width: calc(50% - 5px);"><span data-i18n="expressionEditor.data"></span><button style="float: right; margin-right: 5px;" id="node-input-example-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button></span><span style="display: inline-block; width: calc(50% - 5px);" data-i18n="expressionEditor.result"></span></div><div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-data"></div><div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-result"></div></div></div></div></div></script>'; | ||||
|     var expressionTestCache = {}; | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|             $(template).appendTo(document.body); | ||||
|         }, | ||||
|         show: function(options) { | ||||
|             var expressionTestCacheId = options.parent||"_"; | ||||
|             var value = options.value; | ||||
|             var onComplete = options.complete; | ||||
|             var type = "_expression" | ||||
|             RED.view.state(RED.state.EDITING); | ||||
|             var expressionEditor; | ||||
|             var testDataEditor; | ||||
|             var testResultEditor | ||||
|             var panels; | ||||
|  | ||||
|             var trayOptions = { | ||||
|                 title: options.title, | ||||
|                 width: "inherit", | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "node-dialog-cancel", | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-ok", | ||||
|                         text: RED._("common.label.done"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|                             $("#node-input-expression-help").html(""); | ||||
|                             onComplete(expressionEditor.getValue()); | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 resize: function(dimensions) { | ||||
|                     var height = $("#dialog-form").height(); | ||||
|                     if (panels) { | ||||
|                         panels.resize(height); | ||||
|                     } | ||||
|  | ||||
|                 }, | ||||
|                 open: function(tray) { | ||||
|                     var trayBody = tray.find('.editor-tray-body'); | ||||
|                     trayBody.addClass("node-input-expression-editor") | ||||
|                     var dialogForm = RED.editor.buildEditForm(tray.find('.editor-tray-body'),'dialog-form','_expression','editor'); | ||||
|                     var funcSelect = $("#node-input-expression-func"); | ||||
|                     Object.keys(jsonata.functions).forEach(function(f) { | ||||
|                         funcSelect.append($("<option></option>").val(f).text(f)); | ||||
|                     }) | ||||
|                     funcSelect.change(function(e) { | ||||
|                         var f = $(this).val(); | ||||
|                         var args = RED._('jsonata:'+f+".args",{defaultValue:''}); | ||||
|                         var title = "<h5>"+f+"("+args+")</h5>"; | ||||
|                         var body = marked(RED._('jsonata:'+f+'.desc',{defaultValue:''})); | ||||
|                         $("#node-input-expression-help").html(title+"<p>"+body+"</p>"); | ||||
|  | ||||
|                     }) | ||||
|                     expressionEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-expression', | ||||
|                         value: "", | ||||
|                         mode:"ace/mode/jsonata", | ||||
|                         options: { | ||||
|                             enableBasicAutocompletion:true, | ||||
|                             enableSnippets:true, | ||||
|                             enableLiveAutocompletion: true | ||||
|                         } | ||||
|                     }); | ||||
|                     var currentToken = null; | ||||
|                     var currentTokenPos = -1; | ||||
|                     var currentFunctionMarker = null; | ||||
|  | ||||
|                     expressionEditor.getSession().setValue(value||"",-1); | ||||
|                     expressionEditor.on("changeSelection", function() { | ||||
|                         var c = expressionEditor.getCursorPosition(); | ||||
|                         var token = expressionEditor.getSession().getTokenAt(c.row,c.column); | ||||
|                         if (token !== currentToken || (token && /paren/.test(token.type) && c.column !== currentTokenPos)) { | ||||
|                             currentToken = token; | ||||
|                             var r,p; | ||||
|                             var scopedFunction = null; | ||||
|                             if (token && token.type === 'keyword') { | ||||
|                                 r = c.row; | ||||
|                                 scopedFunction = token; | ||||
|                             } else { | ||||
|                                 var depth = 0; | ||||
|                                 var next = false; | ||||
|                                 if (token) { | ||||
|                                     if (token.type === 'paren.rparen') { | ||||
|                                         // If this is a block of parens ')))', set | ||||
|                                         // depth to offset against the cursor position | ||||
|                                         // within the block | ||||
|                                         currentTokenPos = c.column; | ||||
|                                         depth = c.column - (token.start + token.value.length); | ||||
|                                     } | ||||
|                                     r = c.row; | ||||
|                                     p = token.index; | ||||
|                                 } else { | ||||
|                                     r = c.row-1; | ||||
|                                     p = -1; | ||||
|                                 } | ||||
|                                 while ( scopedFunction === null && r > -1) { | ||||
|                                     var rowTokens = expressionEditor.getSession().getTokens(r); | ||||
|                                     if (p === -1) { | ||||
|                                         p = rowTokens.length-1; | ||||
|                                     } | ||||
|                                     while (p > -1) { | ||||
|                                         var type = rowTokens[p].type; | ||||
|                                         if (next) { | ||||
|                                             if (type === 'keyword') { | ||||
|                                                 scopedFunction = rowTokens[p]; | ||||
|                                                 // console.log("HIT",scopedFunction); | ||||
|                                                 break; | ||||
|                                             } | ||||
|                                             next = false; | ||||
|                                         } | ||||
|                                         if (type === 'paren.lparen') { | ||||
|                                             depth-=rowTokens[p].value.length; | ||||
|                                         } else if (type === 'paren.rparen') { | ||||
|                                             depth+=rowTokens[p].value.length; | ||||
|                                         } | ||||
|                                         if (depth < 0) { | ||||
|                                             next = true; | ||||
|                                             depth = 0; | ||||
|                                         } | ||||
|                                         // console.log(r,p,depth,next,rowTokens[p]); | ||||
|                                         p--; | ||||
|                                     } | ||||
|                                     if (!scopedFunction) { | ||||
|                                         r--; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             expressionEditor.session.removeMarker(currentFunctionMarker); | ||||
|                             if (scopedFunction) { | ||||
|                             //console.log(token,.map(function(t) { return t.type})); | ||||
|                                 funcSelect.val(scopedFunction.value).change(); | ||||
|                             } | ||||
|                         } | ||||
|                     }); | ||||
|  | ||||
|                     dialogForm.i18n(); | ||||
|                     $("#node-input-expression-func-insert").click(function(e) { | ||||
|                         e.preventDefault(); | ||||
|                         var pos = expressionEditor.getCursorPosition(); | ||||
|                         var f = funcSelect.val(); | ||||
|                         var snippet = jsonata.getFunctionSnippet(f); | ||||
|                         expressionEditor.insertSnippet(snippet); | ||||
|                         expressionEditor.focus(); | ||||
|                     }); | ||||
|                     $("#node-input-expression-reformat").click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         var v = expressionEditor.getValue()||""; | ||||
|                         try { | ||||
|                             v = jsonata.format(v); | ||||
|                         } catch(err) { | ||||
|                             // TODO: do an optimistic auto-format | ||||
|                         } | ||||
|                         expressionEditor.getSession().setValue(v||"",-1); | ||||
|                     }); | ||||
|  | ||||
|                     var tabs = RED.tabs.create({ | ||||
|                         element: $("#node-input-expression-tabs"), | ||||
|                         onchange:function(tab) { | ||||
|                             $(".node-input-expression-tab-content").hide(); | ||||
|                             tab.content.show(); | ||||
|                             trayOptions.resize(); | ||||
|                         } | ||||
|                     }) | ||||
|  | ||||
|                     tabs.addTab({ | ||||
|                         id: 'expression-help', | ||||
|                         label: RED._('expressionEditor.functionReference'), | ||||
|                         content: $("#node-input-expression-tab-help") | ||||
|                     }); | ||||
|                     tabs.addTab({ | ||||
|                         id: 'expression-tests', | ||||
|                         label: RED._('expressionEditor.test'), | ||||
|                         content: $("#node-input-expression-tab-test") | ||||
|                     }); | ||||
|                     testDataEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-expression-test-data', | ||||
|                         value: expressionTestCache[expressionTestCacheId] || '{\n    "payload": "hello world"\n}', | ||||
|                         mode:"ace/mode/json", | ||||
|                         lineNumbers: false | ||||
|                     }); | ||||
|                     var changeTimer; | ||||
|                     $(".node-input-expression-legacy").click(function(e) { | ||||
|                         e.preventDefault(); | ||||
|                         RED.sidebar.info.set(RED._("expressionEditor.compatModeDesc")); | ||||
|                         RED.sidebar.info.show(); | ||||
|                     }) | ||||
|                     var testExpression = function() { | ||||
|                         var value = testDataEditor.getValue(); | ||||
|                         var parsedData; | ||||
|                         var currentExpression = expressionEditor.getValue(); | ||||
|                         var expr; | ||||
|                         var usesContext = false; | ||||
|                         var legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(currentExpression); | ||||
|                         $(".node-input-expression-legacy").toggle(legacyMode); | ||||
|                         try { | ||||
|                             expr = jsonata(currentExpression); | ||||
|                             expr.assign('flowContext',function(val) { | ||||
|                                 usesContext = true; | ||||
|                                 return null; | ||||
|                             }); | ||||
|                             expr.assign('globalContext',function(val) { | ||||
|                                 usesContext = true; | ||||
|                                 return null; | ||||
|                             }); | ||||
|                         } catch(err) { | ||||
|                             testResultEditor.setValue(RED._("expressionEditor.errors.invalid-expr",{message:err.message}),-1); | ||||
|                             return; | ||||
|                         } | ||||
|                         try { | ||||
|                             parsedData = JSON.parse(value); | ||||
|                         } catch(err) { | ||||
|                             testResultEditor.setValue(RED._("expressionEditor.errors.invalid-msg",{message:err.toString()})) | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         try { | ||||
|                             var result = expr.evaluate(legacyMode?{msg:parsedData}:parsedData); | ||||
|                             if (usesContext) { | ||||
|                                 testResultEditor.setValue(RED._("expressionEditor.errors.context-unsupported"),-1); | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             var formattedResult; | ||||
|                             if (result !== undefined) { | ||||
|                                 formattedResult = JSON.stringify(result,null,4); | ||||
|                             } else { | ||||
|                                 formattedResult = RED._("expressionEditor.noMatch"); | ||||
|                             } | ||||
|                             testResultEditor.setValue(formattedResult,-1); | ||||
|                         } catch(err) { | ||||
|                             testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     testDataEditor.getSession().on('change', function() { | ||||
|                         clearTimeout(changeTimer); | ||||
|                         changeTimer = setTimeout(testExpression,200); | ||||
|                         expressionTestCache[expressionTestCacheId] = testDataEditor.getValue(); | ||||
|                     }); | ||||
|                     expressionEditor.getSession().on('change', function() { | ||||
|                         clearTimeout(changeTimer); | ||||
|                         changeTimer = setTimeout(testExpression,200); | ||||
|                     }); | ||||
|  | ||||
|                     testResultEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-expression-test-result', | ||||
|                         value: "", | ||||
|                         mode:"ace/mode/json", | ||||
|                         lineNumbers: false, | ||||
|                         readOnly: true | ||||
|                     }); | ||||
|                     panels = RED.panels.create({ | ||||
|                         id:"node-input-expression-panels", | ||||
|                         resize: function(p1Height,p2Height) { | ||||
|                             var p1 = $("#node-input-expression-panel-expr"); | ||||
|                             p1Height -= $(p1.children()[0]).outerHeight(true); | ||||
|                             var editorRow = $(p1.children()[1]); | ||||
|                             p1Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); | ||||
|                             $("#node-input-expression").css("height",(p1Height-5)+"px"); | ||||
|                             expressionEditor.resize(); | ||||
|  | ||||
|                             var p2 = $("#node-input-expression-panel-info > .form-row > div:first-child"); | ||||
|                             p2Height -= p2.outerHeight(true) + 20; | ||||
|                             $(".node-input-expression-tab-content").height(p2Height); | ||||
|                             $("#node-input-expression-test-data").css("height",(p2Height-5)+"px"); | ||||
|                             testDataEditor.resize(); | ||||
|                             $("#node-input-expression-test-result").css("height",(p2Height-5)+"px"); | ||||
|                             testResultEditor.resize(); | ||||
|                         } | ||||
|                     }); | ||||
|  | ||||
|                     $("#node-input-example-reformat").click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         var v = testDataEditor.getValue()||""; | ||||
|                         try { | ||||
|                             v = JSON.stringify(JSON.parse(v),null,4); | ||||
|                         } catch(err) { | ||||
|                             // TODO: do an optimistic auto-format | ||||
|                         } | ||||
|                         testDataEditor.getSession().setValue(v||"",-1); | ||||
|                     }); | ||||
|  | ||||
|                     testExpression(); | ||||
|                 }, | ||||
|                 close: function() { | ||||
|                     if (options.onclose) { | ||||
|                         options.onclose(); | ||||
|                     } | ||||
|                     expressionEditor.destroy(); | ||||
|                     testDataEditor.destroy(); | ||||
|                 }, | ||||
|                 show: function() {} | ||||
|             } | ||||
|             RED.tray.show(trayOptions); | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
							
								
								
									
										118
									
								
								editor/js/ui/editors/json.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								editor/js/ui/editors/json.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| /** | ||||
|  * 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.editor.types._json = (function() { | ||||
|  | ||||
|  | ||||
|     var template = '<script type="text/x-red" data-template-name="_json"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button id="node-input-json-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div></div></script>'; | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|             $(template).appendTo(document.body); | ||||
|         }, | ||||
|         show: function(options) { | ||||
|             var value = options.value; | ||||
|             var onComplete = options.complete; | ||||
|             var type = "_json" | ||||
|             RED.view.state(RED.state.EDITING); | ||||
|             var expressionEditor; | ||||
|             var changeTimer; | ||||
|  | ||||
|             var checkValid = function() { | ||||
|                 var v = expressionEditor.getValue(); | ||||
|                 try { | ||||
|                     JSON.parse(v); | ||||
|                     $("#node-dialog-ok").removeClass('disabled'); | ||||
|                     return true; | ||||
|                 } catch(err) { | ||||
|                     $("#node-dialog-ok").addClass('disabled'); | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|             var trayOptions = { | ||||
|                 title: options.title, | ||||
|                 width: "inherit", | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "node-dialog-cancel", | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-ok", | ||||
|                         text: RED._("common.label.done"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|                             if (options.requireValid && !checkValid()) { | ||||
|                                 return; | ||||
|                             } | ||||
|                             onComplete(expressionEditor.getValue()); | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 resize: function(dimensions) { | ||||
|                     var rows = $("#dialog-form>div:not(.node-text-editor-row)"); | ||||
|                     var editorRow = $("#dialog-form>div.node-text-editor-row"); | ||||
|                     var height = $("#dialog-form").height(); | ||||
|                     for (var i=0;i<rows.size();i++) { | ||||
|                         height -= $(rows[i]).outerHeight(true); | ||||
|                     } | ||||
|                     height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); | ||||
|                     $(".node-text-editor").css("height",height+"px"); | ||||
|                     expressionEditor.resize(); | ||||
|                 }, | ||||
|                 open: function(tray) { | ||||
|                     var trayBody = tray.find('.editor-tray-body'); | ||||
|                     var dialogForm = RED.editor.buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor'); | ||||
|                     expressionEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-json', | ||||
|                         value: "", | ||||
|                         mode:"ace/mode/json" | ||||
|                     }); | ||||
|                     expressionEditor.getSession().setValue(value||"",-1); | ||||
|                     if (options.requireValid) { | ||||
|                         expressionEditor.getSession().on('change', function() { | ||||
|                             clearTimeout(changeTimer); | ||||
|                             changeTimer = setTimeout(checkValid,200); | ||||
|                         }); | ||||
|                         checkValid(); | ||||
|                     } | ||||
|                     $("#node-input-json-reformat").click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         var v = expressionEditor.getValue()||""; | ||||
|                         try { | ||||
|                             v = JSON.stringify(JSON.parse(v),null,4); | ||||
|                         } catch(err) { | ||||
|                             // TODO: do an optimistic auto-format | ||||
|                         } | ||||
|                         expressionEditor.getSession().setValue(v||"",-1); | ||||
|                     }); | ||||
|                     dialogForm.i18n(); | ||||
|                 }, | ||||
|                 close: function() { | ||||
|                     expressionEditor.destroy(); | ||||
|                     if (options.onclose) { | ||||
|                         options.onclose(); | ||||
|                     } | ||||
|                 }, | ||||
|                 show: function() {} | ||||
|             } | ||||
|             RED.tray.show(trayOptions); | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
							
								
								
									
										90
									
								
								editor/js/ui/editors/markdown.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								editor/js/ui/editors/markdown.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.editor.types._markdown = (function() { | ||||
|  | ||||
|  | ||||
|     var template = '<script type="text/x-red" data-template-name="_markdown"><div class="form-row" id="node-input-markdown-title" style="margin-bottom: 3px; text-align: right;"></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-markdown"></div></div></script>'; | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|             $(template).appendTo(document.body); | ||||
|         }, | ||||
|         show: function(options) { | ||||
|             var value = options.value; | ||||
|             var onComplete = options.complete; | ||||
|             var type = "_markdown" | ||||
|             RED.view.state(RED.state.EDITING); | ||||
|             var expressionEditor; | ||||
|  | ||||
|             var trayOptions = { | ||||
|                 title: options.title, | ||||
|                 width: "inherit", | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "node-dialog-cancel", | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-ok", | ||||
|                         text: RED._("common.label.done"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|                             onComplete(expressionEditor.getValue()); | ||||
|                             RED.tray.close(); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 resize: function(dimensions) { | ||||
|                     var rows = $("#dialog-form>div:not(.node-text-editor-row)"); | ||||
|                     var editorRow = $("#dialog-form>div.node-text-editor-row"); | ||||
|                     var height = $("#dialog-form").height(); | ||||
|                     for (var i=0;i<rows.size();i++) { | ||||
|                         height -= $(rows[i]).outerHeight(true); | ||||
|                     } | ||||
|                     height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); | ||||
|                     $(".node-text-editor").css("height",height+"px"); | ||||
|                     expressionEditor.resize(); | ||||
|                 }, | ||||
|                 open: function(tray) { | ||||
|                     var trayBody = tray.find('.editor-tray-body'); | ||||
|                     var dialogForm = RED.editor.buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor'); | ||||
|                     expressionEditor = RED.editor.createEditor({ | ||||
|                         id: 'node-input-markdown', | ||||
|                         value: value, | ||||
|                         mode:"ace/mode/markdown" | ||||
|                     }); | ||||
|                     if (options.header) { | ||||
|                         options.header.appendTo(tray.find('#node-input-markdown-title')); | ||||
|                     } | ||||
|  | ||||
|                     dialogForm.i18n(); | ||||
|                 }, | ||||
|                 close: function() { | ||||
|                     expressionEditor.destroy(); | ||||
|                     if (options.onclose) { | ||||
|                         options.onclose(); | ||||
|                     } | ||||
|                 }, | ||||
|                 show: function() {} | ||||
|             } | ||||
|             RED.tray.show(trayOptions); | ||||
|  | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
| @@ -18,6 +18,12 @@ RED.library = (function() { | ||||
|     var exportToLibraryDialog; | ||||
|     var elementPrefix = "node-input-"; | ||||
|  | ||||
|  | ||||
|     var _librarySaveConfirm = '<div id="node-dialog-library-save-confirm" class="hide"><form class="form-horizontal"><div style="text-align: center; padding-top: 30px;" id="node-dialog-library-save-content"></div></form></div>'; | ||||
|     var _librarySave = '<div id="node-dialog-library-save" class="hide"><form class="form-horizontal"><div class="form-row"><label for="node-dialog-library-save-folder" data-i18n="[append]library.folder"><i class="fa fa-folder-open"></i> </label><input type="text" id="node-dialog-library-save-folder" data-i18n="[placeholder]library.folderPlaceholder"></div><div class="form-row"><label for="node-dialog-library-save-filename" data-i18n="[append]library.filename"><i class="fa fa-file"></i> </label><input type="text" id="node-dialog-library-save-filename" data-i18n="[placeholder]library.filenamePlaceholder"></div></form></div>'; | ||||
|     var _libraryLookup = '<div id="node-dialog-library-lookup" class="hide"><form class="form-horizontal"><div class="form-row"><ul id="node-dialog-library-breadcrumbs" class="breadcrumb"><li class="active"><a href="#" data-i18n="[append]library.breadcrumb"></a></li></ul></div><div class="form-row"><div style="vertical-align: top; display: inline-block; height: 100%; width: 30%; padding-right: 20px;"><div id="node-select-library" style="border: 1px solid #999; width: 100%; height: 100%; overflow:scroll;"><ul></ul></div></div><div style="vertical-align: top; display: inline-block;width: 65%; height: 100%;"><div style="height: 100%; width: 95%;" class="node-text-editor" id="node-select-library-text" ></div></div></div></form></div>'; | ||||
|  | ||||
|  | ||||
|     function loadFlowLibrary() { | ||||
|         $.getJSON("library/flows",function(data) { | ||||
|             //console.log(data); | ||||
| @@ -410,6 +416,11 @@ RED.library = (function() { | ||||
|     return { | ||||
|         init: function() { | ||||
|  | ||||
|  | ||||
|             $(_librarySave).appendTo(document.body); | ||||
|             $(_librarySaveConfirm).appendTo(document.body); | ||||
|             $(_libraryLookup).appendTo(document.body); | ||||
|  | ||||
|             RED.actions.add("core:library-export",exportFlow); | ||||
|  | ||||
|             RED.events.on("view:selection-changed",function(selection) { | ||||
|   | ||||
| @@ -17,6 +17,10 @@ | ||||
| RED.subflow = (function() { | ||||
|  | ||||
|  | ||||
|     var _subflowEditTemplate = '<script type="text/x-red" data-template-name="subflow"><div class="form-row"><label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label><input type="text" id="node-input-name"></div></script>'; | ||||
|     var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template"><div class="form-row"><i class="fa fa-tag"></i><label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name"></div><div class="form-row" style="margin-bottom: 0px;"><label for="subflow-input-info" data-i18n="editor:subflow.info"></label><a href="https://help.github.com/articles/markdown-basics/" style="font-size: 0.8em; float: right;" data-i18n="[html]subflow.format"></a></div><div class="form-row node-text-editor-row"><div style="height: 250px;" class="node-text-editor" id="subflow-input-info-editor"></div></div><div class="form-row form-tips" id="subflow-dialog-user-count"></div></script>'; | ||||
|  | ||||
|  | ||||
|     function getSubflow() { | ||||
|         return RED.nodes.subflow(RED.workspaces.active()); | ||||
|     } | ||||
| @@ -386,6 +390,10 @@ RED.subflow = (function() { | ||||
|  | ||||
|         RED.actions.add("core:create-subflow",createSubflow); | ||||
|         RED.actions.add("core:convert-to-subflow",convertToSubflow); | ||||
|  | ||||
|         $(_subflowEditTemplate).appendTo(document.body); | ||||
|         $(_subflowTemplateEditTemplate).appendTo(document.body); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function createSubflow() { | ||||
|   | ||||
| @@ -82,134 +82,6 @@ | ||||
| <div id="notifications"></div> | ||||
| <div id="dropTarget"><div data-i18n="[append]workspace.dropFlowHere"><br/><i class="fa fa-download"></i></div></div> | ||||
|  | ||||
| <div id="node-dialog-library-save-confirm" class="hide"> | ||||
|     <form class="form-horizontal"> | ||||
|         <div style="text-align: center; padding-top: 30px;" id="node-dialog-library-save-content"> | ||||
|         </div> | ||||
|     </form> | ||||
| </div> | ||||
|  | ||||
| <div id="node-dialog-library-save" class="hide"> | ||||
|     <form class="form-horizontal"> | ||||
|         <div class="form-row"> | ||||
|             <label for="node-dialog-library-save-folder" data-i18n="[append]library.folder"><i class="fa fa-folder-open"></i> </label> | ||||
|             <input type="text" id="node-dialog-library-save-folder" data-i18n="[placeholder]library.folderPlaceholder"> | ||||
|         </div> | ||||
|         <div class="form-row"> | ||||
|             <label for="node-dialog-library-save-filename" data-i18n="[append]library.filename"><i class="fa fa-file"></i> </label> | ||||
|             <input type="text" id="node-dialog-library-save-filename" data-i18n="[placeholder]library.filenamePlaceholder"> | ||||
|         </div> | ||||
|     </form> | ||||
| </div> | ||||
|  | ||||
| <div id="node-dialog-library-lookup" class="hide"> | ||||
|     <form class="form-horizontal"> | ||||
|         <div class="form-row"> | ||||
|             <ul id="node-dialog-library-breadcrumbs" class="breadcrumb"> | ||||
|                 <li class="active"><a href="#" data-i18n="[append]library.breadcrumb"></a></li> | ||||
|             </ul> | ||||
|         </div> | ||||
|         <div class="form-row"> | ||||
|             <div style="vertical-align: top; display: inline-block; height: 100%; width: 30%; padding-right: 20px;"> | ||||
|                 <div id="node-select-library" style="border: 1px solid #999; width: 100%; height: 100%; overflow:scroll;"><ul></ul></div> | ||||
|             </div> | ||||
|             <div style="vertical-align: top; display: inline-block;width: 65%; height: 100%;"> | ||||
|                 <div style="height: 100%; width: 95%;" class="node-text-editor" id="node-select-library-text" ></div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </form> | ||||
| </div> | ||||
| <script type="text/x-red" data-template-name="subflow"> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label> | ||||
|         <input type="text" id="node-input-name"> | ||||
|     </div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-template-name="subflow-template"> | ||||
|     <div class="form-row"> | ||||
|         <i class="fa fa-tag"></i> | ||||
|         <label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name"> | ||||
|     </div> | ||||
|     <div class="form-row" style="margin-bottom: 0px;"> | ||||
|         <label for="subflow-input-info" data-i18n="editor:subflow.info"></label> | ||||
|         <a href="https://help.github.com/articles/markdown-basics/" style="font-size: 0.8em; float: right;" data-i18n="[html]subflow.format"></a> | ||||
|     </div> | ||||
|     <div class="form-row node-text-editor-row"> | ||||
|         <div style="height: 250px;" class="node-text-editor" id="subflow-input-info-editor"></div> | ||||
|     </div> | ||||
|     <div class="form-row form-tips" id="subflow-dialog-user-count"></div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-template-name="_expression"> | ||||
|     <div id="node-input-expression-panels"> | ||||
|         <div id="node-input-expression-panel-expr" class="red-ui-panel"> | ||||
|             <div class="form-row" style="margin-bottom: 3px; text-align: right;"> | ||||
|                 <span class="node-input-expression-legacy"><i class="fa fa-exclamation-circle"></i> <span data-i18n="expressionEditor.compatMode"></span></span> | ||||
|                 <button id="node-input-expression-reformat" class="editor-button editor-button-small"><span data-i18n="expressionEditor.format"></span></button> | ||||
|             </div> | ||||
|             <div class="form-row node-text-editor-row"> | ||||
|                 <div class="node-text-editor" id="node-input-expression"></div> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div id="node-input-expression-panel-info" class="red-ui-panel"> | ||||
|             <div class="form-row"> | ||||
|                 <ul id="node-input-expression-tabs"></ul> | ||||
|                 <div id="node-input-expression-tab-help" class="node-input-expression-tab-content hide"> | ||||
|                     <div> | ||||
|                         <select id="node-input-expression-func"></select> | ||||
|                         <button id="node-input-expression-func-insert" class="editor-button" data-i18n="expressionEditor.insert"></button> | ||||
|                     </div> | ||||
|                     <div id="node-input-expression-help"></div> | ||||
|                 </div> | ||||
|                 <div id="node-input-expression-tab-test" class="node-input-expression-tab-content hide"> | ||||
|                     <div> | ||||
|                         <span style="display: inline-block; width: calc(50% - 5px);"> | ||||
|                             <span data-i18n="expressionEditor.data"></span> | ||||
|                             <button style="float: right; margin-right: 5px;" id="node-input-example-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button> | ||||
|                         </span> | ||||
|                         <span style="display: inline-block; width: calc(50% - 5px);" data-i18n="expressionEditor.result"></span> | ||||
|                     </div> | ||||
|                     <div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-data"></div> | ||||
|                     <div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-result"></div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </script> | ||||
| <script type="text/x-red" data-template-name="_json"> | ||||
|     <div class="form-row" style="margin-bottom: 3px; text-align: right;"> | ||||
|         <button id="node-input-json-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button> | ||||
|     </div> | ||||
|     <div class="form-row node-text-editor-row"> | ||||
|         <div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div> | ||||
|     </div> | ||||
| </script> | ||||
| <script type="text/x-red" data-template-name="_markdown"> | ||||
|     <div class="form-row" id="node-input-markdown-title" style="margin-bottom: 3px; text-align: right;"> | ||||
|  | ||||
|     </div> | ||||
|     <div class="form-row node-text-editor-row"> | ||||
|         <div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-markdown"></div> | ||||
|     </div> | ||||
| </script> | ||||
| <script type="text/x-red" data-template-name="_buffer"> | ||||
|     <div id="node-input-buffer-panels"> | ||||
|         <div id="node-input-buffer-panel-str" class="red-ui-panel"> | ||||
|             <div class="form-row" style="margin-bottom: 3px; text-align: right;"> | ||||
|                 <span class="node-input-buffer-type"><i class="fa fa-exclamation-circle"></i> <span id="node-input-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="node-input-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></span> | ||||
|             </div> | ||||
|             <div class="form-row node-text-editor-row"> | ||||
|                 <div class="node-text-editor" id="node-input-buffer-str"></div> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div id="node-input-buffer-panel-bin" class="red-ui-panel"> | ||||
|             <div class="form-row node-text-editor-row" style="margin-top: 10px"> | ||||
|                 <div class="node-text-editor" id="node-input-buffer-bin"></div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </script> | ||||
| <script src="vendor/vendor.js"></script> | ||||
| <script src="vendor/jsonata/jsonata.min.js"></script> | ||||
| <script src="vendor/ace/ace.js"></script> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user