Comparing version 0.0.50 to 0.0.51
@@ -607,3 +607,3 @@ 'use strict'; | ||
var lastCh = ''; | ||
let stop = false, inComments = false; | ||
let stop = false, inComments = false, inJs = false; | ||
@@ -659,3 +659,3 @@ for (var ch = this.pickChar(); !stop && ch; ch = ch && this.pickChar()) { | ||
} | ||
else if (textQuotes.indexOf(ch) !== -1) { // Open Quotes.. | ||
else if ((tag || inJs) && textQuotes.indexOf(ch) !== -1) { // Open Quotes.. | ||
if (tag) tag += ch; | ||
@@ -665,8 +665,13 @@ quotes.push(ch); | ||
else if (ch === '-') { | ||
if (tag && tag === '<!-') { | ||
tag = ''; | ||
inComments = true; | ||
if (tag.length > 1) { // at least '<!' | ||
if (lastCh === '!') { | ||
tag += ch; | ||
} | ||
else if (tag.startsWith("!-", 1)) { | ||
tag = ''; | ||
inComments = true; | ||
} | ||
} | ||
else { | ||
tag += ch; | ||
tag = ''; | ||
} | ||
@@ -716,2 +721,5 @@ } | ||
openTag = openTagName = ''; // open-tag is closed | ||
if ("script".equal(tagName, true)) | ||
inJs = false; | ||
} | ||
@@ -729,2 +737,3 @@ } | ||
inJs = "script".equal(tagName, true); | ||
openTag = tag; | ||
@@ -731,0 +740,0 @@ openTagName = tagName; |
@@ -15,2 +15,6 @@ # The overview of Razor-Express View Template Engine | ||
- [Code blocks](#code-blocks) | ||
- [Rendering HTML within JavaScript code blocks](#rendering-html-within-javascript-code-blocks) | ||
- [Control structures](#control-structures) | ||
- [Conditionals @if, else if, else, and @switch](#conditionals-if-else-if-else-and-switch) | ||
- [Looping @for, @while, and @do while](#looping-for-while-and-do-while) | ||
@@ -241,3 +245,3 @@ ## What is View Template? | ||
`@for` | ||
##### `@for` | ||
```HTML+Razor | ||
@@ -259,3 +263,3 @@ <table> | ||
`@Array.prototype.forEach` | ||
##### `@while` | ||
```HTML+Razor | ||
@@ -267,21 +271,2 @@ <table> | ||
</tr> | ||
@{ | ||
countries.forEach((c)=>{ | ||
<tr> | ||
<td>@c.name</td> | ||
<td>@c.area</td> | ||
</tr> | ||
}); | ||
} | ||
</table> | ||
``` | ||
**Note** that in this example we have enclosed the construction in `@{...}`, otherwise the parser will consider this statement an expression. The expression is calculated and rendered in HTML as a single value and it cannot render any HTML within itself. When it's wrapped in a code block explicitly, as in this example, it is parsed as part of the code block and therefore can render HTML. | ||
`@while` | ||
```HTML+Razor | ||
<table> | ||
<tr> | ||
<th>Country</th> | ||
<th>Area sq.km</th> | ||
</tr> | ||
@{ var i = 0; } | ||
@@ -298,3 +283,15 @@ @while(i < countries.length){ | ||
`@do while` | ||
##### `@do while` | ||
```HTML+Razor | ||
@do{ | ||
var country = countries[i++]; | ||
<tr> | ||
<td>@country.name</td> | ||
<td>@country.area</td> | ||
</tr> | ||
}while(i < countries.length) | ||
``` | ||
<sup>[^ try these code examples](https://runkit.com/develax/razor-looping-structures)</sup> | ||
##### `@Array.prototype.forEach` | ||
Using `forEach` structure for looping an array is not recommended. An example of using `forEach` with explanations is given in the ["Expressions & code blocks confusion"](https://github.com/DevelAx/RazorExpress/blob/master/README.md#expressions--code-blocks-confusion) section. |
{ | ||
"name": "raz", | ||
"description": "Razor-like syntax for templating views in NodeJS Express framework by mixing HTML with JavaScript.", | ||
"version": "0.0.50", | ||
"version": "0.0.51", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Sergey", |
@@ -19,2 +19,3 @@ # RAZ: Razor-Express View Template Engine | ||
- [Missing semicolon](#missing-semicolon) | ||
- [Expressions & code blocks confusion](#expressions--code-blocks-confusion) | ||
- [**Debugging & Errors handling in Razor-Express**](https://github.com/DevelAx/RazorExpress/blob/master/docs/Debugging.md) | ||
@@ -32,3 +33,3 @@ - Debugging view templates | ||
The closest to *Razor* currently supported library for *NodeJs & Express* I could find was [Vash](https://www.npmjs.com/package/vash). But in some points, it was quite different from *ASP.NET MVC Razor* syntax which I was used to and it just looked much less concise and convenient to me (the concepts of layouts and partial blocks, for example). In short, it did not suit me completely and what's more important I couldn't see its current development. | ||
The closest to *Razor* currently supported library for *NodeJs & Express* I could find was [Vash](https://www.npmjs.com/package/vash). But in some points, it was quite different from *ASP.NET MVC Razor* syntax which I was used to and it just looked much less concise and convenient to me (the syntax for rendering layouts and partial blocks, for example). In short, it did not suit me completely and what's more important I couldn't see its current development. | ||
@@ -364,1 +365,38 @@ A brief comparison of syntax of Node.JS layout engines | ||
<sup>* [Run this code with RunKit.](https://runkit.com/develax/razor-pitfalls-semicolon)</sup> | ||
Expressions & code blocks confusion | ||
--- | ||
Try to stick to simple classical language constructs to avoid ambiguous parser or runtime errors. Although almost all JavaScript syntax is correctly parsed by the engine, some language constructs may not work as you expect. For example, you might try to write a loop as follows: | ||
```HTML+Razor | ||
<table> | ||
<tr> | ||
<th>Country</th> | ||
<th>Area sq.km</th> | ||
</tr> | ||
@countries.forEach((c)=>{ | ||
<tr> | ||
<td>@c.name</td> | ||
<td>@c.area</td> | ||
</tr> | ||
}); | ||
</table> | ||
``` | ||
There are no syntax errors in this example and the code intuitively looks quite decent. The parser also won't find any problems. However, a runtime error will occur during execution. The actual problem is that the parser considers this statement an expression. When an expression is detected it is evaluated and the return value of it is rendered in HTML. But the parser does look for HTML within expressions. Therefore the HTML tags you put in the expression will cause the runtime error because the whole expression with these tags (as part of JavaScript code) will be tried to be executed. | ||
To make this code work you need to *wrap it explicitly in a code block* then it will be parsed as part of the code block and HTML within it will be rendered correctly. That is, you need to bring it to the following form: | ||
```HTML+Razor | ||
... | ||
@{ | ||
countries.forEach((c)=>{ | ||
<tr> | ||
<td>@c.name</td> | ||
<td>@c.area</td> | ||
</tr> | ||
}); | ||
} | ||
... | ||
``` | ||
<sup>^ [run this example](https://runkit.com/develax/razor-array-foreach)</sup> | ||
However, the best way to avoid such ambiguities is to stick to a plain JavaScript syntax style while writing your view templates. See ["Looping @for, @while, and @do while"](https://github.com/DevelAx/RazorExpress/blob/master/docs/overview.md#looping-for-while-and-do-while) section for examples of loop structures. |
@@ -279,2 +279,17 @@ (function () { | ||
{ | ||
name: "HTML 31.1", | ||
template: `@{<span>1'2</span>}`, | ||
expected: `<span>1'2</span>` | ||
}, | ||
{ | ||
name: "HTML 31.2", | ||
template: `<span>--1'2--</span>`, | ||
expected: `<span>--1'2--</span>` | ||
}, | ||
{ | ||
name: "HTML 31.3", | ||
template: `@{<span>--1'2--</span>}`, | ||
expected: `<span>--1'2--</span>` | ||
}, | ||
{ | ||
name: "HTML 32", | ||
@@ -281,0 +296,0 @@ template: ` |
199871
4118
400