Implement script tag (outputs JavaScript body as a string; slightly minified)
authorNick Downing <downing.nick@gmail.com>
Sun, 14 Oct 2018 12:29:30 +0000 (23:29 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 30 Oct 2018 07:54:35 +0000 (18:54 +1100)
page.jst
template.js

index 9623eb1..dae02d1 100644 (file)
--- a/page.jst
+++ b/page.jst
@@ -4,5 +4,9 @@ async _env => html.'cls-1'.cls-2#id-1(lang=_env.lang true=_env.val something-els
     `hello
 & goodbye
 `
+    script {
+      for (let i = 0; i < 100; ++i)
+        console.log(i)
+    }
   }
 }
index 8c459f5..2234499 100644 (file)
@@ -1,4 +1,5 @@
 let assert = require('assert')
+let astring = require('astring')
 let transform = require('./transform')
 let html_escape = require('html-escape')
 
@@ -139,41 +140,59 @@ let html_body = (context, st, c) => {
       prefix += '"'
     }
   }
+  prefix += '>'
 
-  let expr1 = {
-    type: 'Literal',
-    value: prefix + '>',
-  }
-  expr = expr === undefined ? expr1 : {
-    type: 'BinaryExpression',
-    left: expr,
-    operator: '+',
-    right: expr1,
-  }
-
-  let result = [
-    {
-      type: 'ExpressionStatement',
-      expression: {
-        type: 'CallExpression',
-        callee: {
-          type: 'MemberExpression',
-          object: {
-            type: 'Identifier',
-            name: '_out'
-          },
-          property: {
-            type: 'Identifier',
-            name: 'push'
+  let result = []
+  let body = c(context.body, st, 'Statement').body
+  if (tag === 'script')
+    prefix += astring.generate(
+      {
+        type: 'Program',
+        body: body,
+        sourceType: 'script'
+      },
+      {indent: ''}
+    )
+  else if (body.length !== 0) {
+    let expr1 = {
+      type: 'Literal',
+      value: prefix
+    }
+    expr = expr === undefined ? expr1 : {
+      type: 'BinaryExpression',
+      left: expr,
+      operator: '+',
+      right: expr1,
+    }
+    result.push(
+      {
+        type: 'ExpressionStatement',
+        expression: {
+          type: 'CallExpression',
+          callee: {
+            type: 'MemberExpression',
+            object: {
+              type: 'Identifier',
+              name: '_out'
+            },
+            property: {
+              type: 'Identifier',
+              name: 'push'
+            },
+            computed: false
           },
-          computed: false
-        },
-        arguments: [
-          expr
-        ]
+          arguments: [
+            expr
+          ]
+        }
       }
-    }
-  ].concat(c(context.body, st, 'Statement').body)
+    )
+    prefix = ''
+    expr = undefined
+
+    result = result.concat(body)
+  }
+
   if (
     tag !== 'br' &&
     tag !== 'img' &&
@@ -181,6 +200,18 @@ let html_body = (context, st, c) => {
     tag !== 'link' &&
     tag !== 'meta'
   )
+    prefix += '</' + tag + '>'
+  if (prefix.length !== 0) {
+    let expr1 = {
+      type: 'Literal',
+      value: prefix
+    }
+    expr = expr === undefined ? expr1 : {
+      type: 'BinaryExpression',
+      left: expr,
+      operator: '+',
+      right: expr1,
+    }
     result.push(
       {
         type: 'ExpressionStatement',
@@ -199,14 +230,12 @@ let html_body = (context, st, c) => {
             computed: false
           },
           arguments: [
-            {
-              type: 'Literal',
-              value: '</' + tag + '>'
-            }
+            expr
           ]
         }
       }
     )
+  }
   return result
 }
 
@@ -257,11 +286,13 @@ visitors.ExpressionStatement = (node, st, c) => {
     if (
       expr_to_tag(node.expression, context, true, false) &&
       context.body !== undefined
-    )
-      return {
+    ) {
+      let body = html_body(context, st, c)
+      return body.length === 1 ? body[0] : {
         type: 'BlockStatement',
-        body: html_body(context, st, c)
+        body: body
       }
+    }
   }
   return visitors_ExpressionStatement(node, st, c)
 }