Include jsonata from dependency on build and improve func highlight

This commit is contained in:
Nick O'Leary 2016-11-23 23:15:30 +00:00
parent eaa4b76ede
commit 534b07d120
6 changed files with 120 additions and 2824 deletions

View File

@ -154,7 +154,7 @@ module.exports = function(grunt) {
// bootstrap/FA/jquery
],
"public/vendor/jsonata/jsonata.js": [
"editor/vendor/jsonata/jsonata.js",
"node_modules/jsonata/jsonata.js",
"editor/vendor/jsonata/formatter.js"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 786 B

After

Width:  |  Height:  |  Size: 563 B

View File

@ -1415,7 +1415,7 @@ RED.editor = (function() {
var trayBody = tray.find('.editor-tray-body');
var dialogForm = buildEditForm(tray,'dialog-form','_expression','editor');
var funcSelect = $("#node-input-expression-func");
jsonata.functions.forEach(function(f) {
Object.keys(jsonata.functions).forEach(function(f) {
funcSelect.append($("<option></option>").val(f).text(f));
})
funcSelect.change(function(e) {
@ -1436,14 +1436,75 @@ RED.editor = (function() {
enableLiveAutocompletion: true
}
});
expressionEditor.getSession().setValue(value||"",-1);
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);
// console.log(token);
if (token && token.type === 'keyword') {
funcSelect.val(token.value).change();
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();
}
}
});
@ -1452,10 +1513,8 @@ RED.editor = (function() {
e.preventDefault();
var pos = expressionEditor.getCursorPosition();
var f = funcSelect.val();
var args = RED._('jsonata:'+f+".args",{defaultValue:''});
expressionEditor.insert(f+"("+args+")");
pos.column += f.length+1;
expressionEditor.moveCursorToPosition(pos);
var snippet = jsonata.getFunctionSnippet(f);
expressionEditor.insertSnippet(snippet);
expressionEditor.focus();
})
},
@ -1521,7 +1580,6 @@ RED.editor = (function() {
}
},100);
}
return editor;
}
}

View File

@ -105,5 +105,43 @@
}
jsonata.format = formatExpression;
jsonata.functions = ["$sum", "$count", "$max", "$min", "$average", "$string", "$substring", "$substringBefore", "$substringAfter", "$lowercase", "$uppercase", "$length", "$split", "$join", "$number", "$boolean", "$not", "$map", "$reduce", "$keys", "$lookup", "$append", "$exists", "$spread"]
jsonata.functions =
{
'$append':{ args:['array','array'] },
'$average':{ args:['value'] },
'$boolean':{ args:['value'] },
'$count':{ args:['array'] },
'$exists':{ args:['value'] },
'$join':{ args:['array','separator'] },
'$keys':{ args:['object'] },
'$length':{ args:['string'] },
'$lookup':{ args:['object','key'] },
'$lowercase':{ args:['string'] },
'$map':{ args:[] },
'$max':{ args:['array'] },
'$min':{ args:['array'] },
'$not':{ args:['value'] },
'$number':{ args:['value'] },
'$reduce':{ args:[] },
'$split':{ args:['string','separator','limit'] },
'$spread':{ args:['object'] },
'$string':{ args:['value'] },
'$substring':{ args:['string','start','length'] },
'$substringAfter':{ args:['string','chars'] },
'$substringBefore':{ args:['string','chars'] },
'$sum':{ args:['array'] },
'$uppercase':{ args:['string'] }
}
jsonata.getFunctionSnippet = function(fn) {
var snippetText = "";
if (jsonata.functions.hasOwnProperty(fn)) {
var def = jsonata.functions[fn];
snippetText = "\\"+fn+"(";
if (def.args) {
snippetText += def.args.map(function(a,i) { return "${"+(i+1)+":"+a+"}"}).join(", ");
}
snippetText += ")\n"
}
return snippetText;
}
})();

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,13 @@ define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/mode/
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var WorkerClient = require("../worker/worker_client").WorkerClient;
var jsonataFunctions = Object.keys(jsonata.functions);
// sort in length order (long->short) otherwise substringAfter gets matched
// as substring etc.
jsonataFunctions.sort(function(A,B) {
return B.length-A.length;
});
jsonataFunctions = jsonataFunctions.join("|").replace(/\$/g,"\\$");
var JSONataHighlightRules = function() {
@ -17,11 +24,7 @@ define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/mode/
"constant.language.boolean":
"true|false",
"storage.type":
"function",
"keyword":
"$sum|$count|$max|$min|$average|$string|$substring|$substringBefore|"+
"$substringAfter|$lowercase|$uppercase|$length|$split|$join|$number|"+
"$boolean|$not|$map|$reduce|$keys|$lookup|$append|$exists|$spread"
"function"
}, "identifier");
this.$rules = {
"start" : [
@ -46,6 +49,10 @@ define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/mode/
{ token: "keyword",
regex: /λ/
},
{
token: "keyword",
regex: jsonataFunctions
},
{
token : keywordMapper,
regex : "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"