From af0a86e50be45d0862e7851c598afc61376a3b81 Mon Sep 17 00:00:00 2001 From: Kabir Shah Date: Mon, 10 Jun 2019 12:14:30 -0700 Subject: [PATCH] allow nested text expressions --- packages/moon/dist/moon.js | 16 +++++++++++++--- packages/moon/dist/moon.min.js | 2 +- packages/moon/src/compiler/lexer/lexer.js | 15 +++++++++++++-- packages/moon/test/compiler/lexer.test.js | 2 +- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/moon/dist/moon.js b/packages/moon/dist/moon.js index dee3a842..bfaefb7a 100644 --- a/packages/moon/dist/moon.js +++ b/packages/moon/dist/moon.js @@ -366,13 +366,23 @@ } else if (_char === "{") { // If a sequence of characters begins with "{", process it as an // expression token. - var expression = ""; // Consume the input until the end of the expression. + var expression = ""; // Keep a stack of opened objects. + + var opened = 0; // Consume the input until the end of the expression. for (i += 1; i < input.length; i++) { var _char2 = input[i]; - if (_char2 === "}") { - break; + if (_char2 === "{") { + opened += 1; + expression += _char2; + } else if (_char2 === "}") { + if (opened === 0) { + break; + } else { + opened -= 1; + expression += _char2; + } } else { expression += _char2; } diff --git a/packages/moon/dist/moon.min.js b/packages/moon/dist/moon.min.js index 55e3a117..d58c5f17 100644 --- a/packages/moon/dist/moon.min.js +++ b/packages/moon/dist/moon.min.js @@ -4,4 +4,4 @@ * Released under the MIT License * https://kbrsh.github.io/moon */ -!function(e,t){"undefined"==typeof module?e.Moon=t():module.exports=t()}(this,function(){"use strict";var b={element:0,text:1,component:2};var y,O=/^\s+$/,S=/<([\w\d-_]+)([^>]*?)(\/?)>/g,C=/([\w\d-_:@]*)(?:=(?:("[^"]*"|'[^']*')|{([^=]*)}))?/g,t=/"[^"]*"|'[^']*'|\d+[a-zA-Z$_]\w*|\.[a-zA-Z$_]\w*|[a-zA-Z$_]\w*:|([a-zA-Z$_]\w*)/g,k=/&|>|<| |"|\\|"|\n|\r/g,r=["NaN","false","in","null","this","true","typeof","undefined","window"],q={"&":"&",">":">","<":"<"," ":" ",""":'\\"',"\\":"\\\\",'"':'\\"',"\n":"\\n","\r":"\\r"};function P(e){switch(e){case"class":return"className";case"for":return"htmlFor";default:return e}}function E(e){var n=!0;return{value:e.replace(t,function(e,t){return void 0===t||-1!==r.indexOf(t)?e:(n=!1,"$"===t[0]?t:"data."+t)}),isStatic:n}}function n(e){e=e.trim();for(var t,n=[],r=0;r",r+2),l=e.slice(r+2,o);0,n.push({type:"tagClose",value:l}),r=o+1;continue}if("!"===i&&"-"===e[r+2]&&"-"===e[r+3]){var u=e.indexOf("--\x3e",r+4);0,r=u+3;continue}S.lastIndex=r;var d=S.exec(e);0;for(var s=d[0],f=d[1],v=d[2],c=d[3],p={},h=void 0;null!==(h=C.exec(v));){var m=h[0],g=P(h[1]),w=h[2],b=h[3];0===m.length?C.lastIndex+=1:64===g.charCodeAt(0)?p[g]={value:"["+E(b).value+",data]",isStatic:!1}:p[g]=void 0===b?{value:void 0===w?"true":w,isStatic:!0}:E(b)}n.push({type:"tagOpen",value:f,attributes:p,closed:"/"===c}),r+=s.length}else if("{"===a){var y="";for(r+=1;r]*?)(\/?)>/g,k=/([\w\d-_:@]*)(?:=(?:("[^"]*"|'[^']*')|{([^=]*)}))?/g,t=/"[^"]*"|'[^']*'|\d+[a-zA-Z$_]\w*|\.[a-zA-Z$_]\w*|[a-zA-Z$_]\w*:|([a-zA-Z$_]\w*)/g,q=/&|>|<| |"|\\|"|\n|\r/g,r=["NaN","false","in","null","this","true","typeof","undefined","window"],P={"&":"&",">":">","<":"<"," ":" ",""":'\\"',"\\":"\\\\",'"':'\\"',"\n":"\\n","\r":"\\r"};function E(e){switch(e){case"class":return"className";case"for":return"htmlFor";default:return e}}function F(e){var n=!0;return{value:e.replace(t,function(e,t){return void 0===t||-1!==r.indexOf(t)?e:(n=!1,"$"===t[0]?t:"data."+t)}),isStatic:n}}function n(e){e=e.trim();for(var t,n=[],r=0;r",r+2),l=e.slice(r+2,o);0,n.push({type:"tagClose",value:l}),r=o+1;continue}if("!"===i&&"-"===e[r+2]&&"-"===e[r+3]){var u=e.indexOf("--\x3e",r+4);0,r=u+3;continue}C.lastIndex=r;var d=C.exec(e);0;for(var s=d[0],f=d[1],v=d[2],c=d[3],p={},h=void 0;null!==(h=k.exec(v));){var m=h[0],g=E(h[1]),w=h[2],b=h[3];0===m.length?k.lastIndex+=1:64===g.charCodeAt(0)?p[g]={value:"["+F(b).value+",data]",isStatic:!1}:p[g]=void 0===b?{value:void 0===w?"true":w,isStatic:!0}:F(b)}n.push({type:"tagOpen",value:f,attributes:p,closed:"/"===c}),r+=s.length}else if("{"===a){var y="",x=0;for(r+=1;r { }) test("lex expression", () => { - expect(lex(`{data + 1}`)).toEqual([{"attributes": {"": {"value": "data.data + 1", isStatic: false}}, "closed": true, "type": "tagOpen", "value": "text"}]); + expect(lex(`{data + 1 + {foo: true, bar: false}}`)).toEqual([{"attributes": {"": {"value": "data.data + 1 + {foo: true, bar: false}", isStatic: false}}, "closed": true, "type": "tagOpen", "value": "text"}]); }); test("lex attributes", () => {