@cilix/lightjs 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/core.js +116 -38
  2. package/index.js +1 -1
  3. package/package.json +1 -1
package/core.js CHANGED
@@ -19,11 +19,9 @@
19
19
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  */
21
21
 
22
- const fs = require('fs');
23
- const path = require("path");
24
-
25
- module.exports = (config) => {
22
+ module.exports = (config, fs, path) => {
26
23
  const _files = {};
24
+ let includeRuntime = false;
27
25
 
28
26
  function throw_error (err) {
29
27
  err.origin = 'light';
@@ -351,7 +349,9 @@ module.exports = (config) => {
351
349
  "let",
352
350
  "nosync",
353
351
  "as",
354
- "global"
352
+ "global",
353
+ "when",
354
+ "catch"
355
355
  ];
356
356
 
357
357
  let symbols = [
@@ -661,10 +661,15 @@ module.exports = (config) => {
661
661
  const parse = (tokens) => {
662
662
  let tok = tokens[0];
663
663
  let cursor = 0;
664
- let in_tag = false;
665
664
  let ast = { type: 'file', data: { file: tok.file }, children: [] };
666
665
  let parent = ast;
667
666
 
667
+ const parse_state = {
668
+ in_tag: false,
669
+ if_depth: 0,
670
+ each_depth: 0
671
+ };
672
+
668
673
  function ast_node(type, data) {
669
674
  let node = { type, data, children: [] };
670
675
  parent.children.push(node);
@@ -1014,6 +1019,7 @@ module.exports = (config) => {
1014
1019
  attr[key] = { type: "bool", data: true };
1015
1020
  }
1016
1021
  } else if (accept("on")) {
1022
+ includeRuntime = true;
1017
1023
  expect(":");
1018
1024
  let handler;
1019
1025
  let evt = tok.data;
@@ -1030,9 +1036,9 @@ module.exports = (config) => {
1030
1036
  }
1031
1037
 
1032
1038
  function parse_custom_tag_body () {
1033
- in_tag = true;
1039
+ parse_state.in_tag = true;
1034
1040
  parse_tag_list();
1035
- in_tag = false;
1041
+ parse_state.in_tag = false;
1036
1042
  }
1037
1043
 
1038
1044
  function parse_tag() {
@@ -1084,6 +1090,7 @@ module.exports = (config) => {
1084
1090
  }
1085
1091
 
1086
1092
  function parse_if_statement() {
1093
+ parse_state.if_depth++;
1087
1094
  expect("(");
1088
1095
  let condition = parse_expr();
1089
1096
  expect(")");
@@ -1112,13 +1119,68 @@ module.exports = (config) => {
1112
1119
  }
1113
1120
  }
1114
1121
  parent = current;
1122
+ parse_state.if_depth--;
1115
1123
  }
1116
1124
 
1117
- const parse_tag_list = () => {
1125
+ function parse_when_statement() {
1126
+ if (parse_state.each_depth > 0) {
1127
+ throw_error({
1128
+ msg: 'when cannot be nested in each',
1129
+ pos: tok.pos,
1130
+ file: tok.file
1131
+ });
1132
+ }
1133
+ if (parse_state.if_depth > 0) {
1134
+ throw_error({
1135
+ msg: 'when cannot be nested in if',
1136
+ pos: tok.pos,
1137
+ file: tok.file
1138
+ });
1139
+ }
1140
+ expect("(");
1141
+ let condition = parse_expr();
1142
+ expect(")");
1143
+ let current = parent;
1144
+ let node = ast_node('when', condition);
1145
+ parent = node;
1146
+ let pass = ast_node('block');
1147
+ parent = pass;
1148
+ if (accept("[")) {
1149
+ parse_tag_list();
1150
+ expect("]");
1151
+ } else {
1152
+ parse_tag();
1153
+ }
1154
+ expect("else");
1155
+ parent = node;
1156
+ let fail = ast_node('block');
1157
+ parent = fail;
1158
+ if (accept("[")) {
1159
+ parse_tag_list();
1160
+ expect("]");
1161
+ } else {
1162
+ parse_tag();
1163
+ }
1164
+ parent = current;
1165
+ expect("catch");
1166
+ parent = node;
1167
+ let catchBlock = ast_node('block');
1168
+ parent = catchBlock;
1169
+ if (accept("[")) {
1170
+ parse_tag_list();
1171
+ expect("]");
1172
+ } else {
1173
+ parse_tag();
1174
+ }
1175
+ parent = current;
1176
+ }
1177
+
1178
+ function parse_tag_list() {
1118
1179
  if (accept("if")) {
1119
1180
  parse_if_statement();
1120
1181
  parse_tag_list();
1121
1182
  } else if (accept("each")) {
1183
+ parse_state.each_depth++;
1122
1184
  expect("(");
1123
1185
  let it1, it0 = tok.data;
1124
1186
  expect("ident");
@@ -1142,6 +1204,10 @@ module.exports = (config) => {
1142
1204
  parse_tag();
1143
1205
  }
1144
1206
  parent = current;
1207
+ parse_state.each_depth--;
1208
+ parse_tag_list();
1209
+ } else if (accept("when")) {
1210
+ parse_when_statement();
1145
1211
  parse_tag_list();
1146
1212
  } else if (peek("ident")) {
1147
1213
  parse_tag();
@@ -1154,10 +1220,11 @@ module.exports = (config) => {
1154
1220
  ast_node('yield', { pos: tok.pos, file: tok.file });
1155
1221
  next();
1156
1222
  parse_tag_list();
1157
- } else if (in_tag && (peek('global') || peek('const') || peek('let'))) {
1223
+ } else if (parse_state.in_tag && (peek('global') || peek('const') || peek('let'))) {
1158
1224
  parse_assignment();
1159
1225
  parse_tag_list();
1160
- } else if (in_tag && peek('js_context')) {
1226
+ } else if (parse_state.in_tag && peek('js_context')) {
1227
+ includeRuntime = true;
1161
1228
  parent.js = tok.data;
1162
1229
  ast_node('js', { js: tok.data, pos: tok.pos, file: tok.file });
1163
1230
  next();
@@ -1296,6 +1363,7 @@ module.exports = (config) => {
1296
1363
  } else if (peek('const') || peek('let') || peek('global')) {
1297
1364
  parse_assignment();
1298
1365
  } else if (peek('js_context')) {
1366
+ includeRuntime = true;
1299
1367
  ast_node('js', { js: tok.data, pos: tok.pos, file: tok.file });
1300
1368
  js_found = true;
1301
1369
  next();
@@ -1320,7 +1388,7 @@ module.exports = (config) => {
1320
1388
  let inScript = false;
1321
1389
  let inStyle = false;
1322
1390
 
1323
- const found = { head: false, head: false, body: false };
1391
+ const found = { head: false, html: false, body: false };
1324
1392
 
1325
1393
  const emit = flush ? (txt) => {
1326
1394
  if (html.length > 100) {
@@ -1432,7 +1500,6 @@ module.exports = (config) => {
1432
1500
  ctx.pop();
1433
1501
  break;
1434
1502
  }
1435
- // todo: html -> head, body enforcement
1436
1503
  if (valid_tags.indexOf(node.data.name) === -1) {
1437
1504
  err(`Invalid tag: ${node.data.name}`, node.data);
1438
1505
  }
@@ -1497,11 +1564,13 @@ module.exports = (config) => {
1497
1564
  } else {
1498
1565
  node.children.forEach(walk);
1499
1566
  if (node.data.name === 'head') {
1500
- emit('<script>');
1501
- emit(`document.addEventListener('DOMContentLoaded', function () {\n`);
1502
- emit(`(function (data){${js}})(${JSON.stringify(initial_state)})`);
1503
- emit('});');
1504
- emit('<' + '/script>');
1567
+ if (includeRuntime) {
1568
+ emit('<script>');
1569
+ emit(`document.addEventListener('DOMContentLoaded', function () {\n`);
1570
+ emit(`(function (data){${js}})(${JSON.stringify(initial_state)})`);
1571
+ emit('});');
1572
+ emit('<' + '/script>');
1573
+ }
1505
1574
  }
1506
1575
  emit('</');
1507
1576
  emit(node.data.name);
@@ -2189,7 +2258,7 @@ module.exports = (config) => {
2189
2258
  out[out.length - 1].code += txt;
2190
2259
  if (fileIdx > -1) {
2191
2260
  const n = fileList[fileIdx].name;
2192
- out[out.length - 1].parent_dir = getPathInfo(n).parent;
2261
+ out[out.length - 1].parent_dir = path ? getPathInfo(n).parent : '/';
2193
2262
  }
2194
2263
  };
2195
2264
 
@@ -2688,28 +2757,29 @@ module.exports = (config) => {
2688
2757
  return out;
2689
2758
  };
2690
2759
 
2691
- const renderToAst = async (file, actions) => {
2692
- const fileText = openFile(file);
2760
+ const renderToAst = async (file, actions, _fileText) => {
2761
+ const fileText = file === 'default' ? _fileText : openFile(file);
2693
2762
  const tokens = tokenize(fileText, file);
2694
2763
  const ast = parse(tokens);
2695
- const runtime = generateRuntime(ast, actions);
2696
- let js;
2697
-
2698
- if (config.jsTransform) {
2699
- js = (await Promise.all(runtime.map(async (chunk) => {
2700
- if (chunk.transform) {
2701
- return await config.jsTransform(chunk);
2702
- }
2703
- return chunk.code;
2704
- }))).join('\n');
2705
- } else {
2706
- js = runtime.map((chunk) => chunk.code).join('\n');
2707
- }
2764
+ let js = '';
2765
+ if (includeRuntime) {
2766
+ const runtime = generateRuntime(ast, actions);
2767
+
2768
+ if (config.jsTransform) {
2769
+ js = (await Promise.all(runtime.map(async (chunk) => {
2770
+ if (chunk.transform) {
2771
+ return await config.jsTransform(chunk);
2772
+ }
2773
+ return chunk.code;
2774
+ }))).join('\n');
2775
+ } else {
2776
+ js = runtime.map((chunk) => chunk.code).join('\n');
2777
+ }
2708
2778
 
2709
- if (config.jsPostProcess) {
2710
- js = await config.jsPostProcess(js);
2779
+ if (config.jsPostProcess) {
2780
+ js = await config.jsPostProcess(js);
2781
+ }
2711
2782
  }
2712
-
2713
2783
  return { ast, js };
2714
2784
  };
2715
2785
 
@@ -2728,11 +2798,19 @@ module.exports = (config) => {
2728
2798
  return html;
2729
2799
  };
2730
2800
 
2801
+ const renderString = async (fileText, data) => {
2802
+ _files.default = fileText;
2803
+ const result = await renderToAst('default', [], fileText);
2804
+ const html = renderToHTML(result, data);
2805
+
2806
+ return html;
2807
+ };
2808
+
2731
2809
  const renderToCache = async (file, actions) => {
2732
2810
  const result = await renderToAst(file, actions);
2733
2811
  return JSON.stringify(result);
2734
2812
  };
2735
2813
 
2736
- return { render, renderToCache, renderToHTML, printError };
2814
+ return { render, renderString, renderToCache, renderToHTML, printError };
2737
2815
  };
2738
2816
 
package/index.js CHANGED
@@ -108,7 +108,7 @@ Light.compile = async (name, opts) => {
108
108
  });
109
109
  return result.outputFiles[0].text;
110
110
  }
111
- });
111
+ }, fs, path);
112
112
  try {
113
113
  let html;
114
114
  if (opts.cache) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cilix/lightjs",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "A new kind of JavaScript framework",
5
5
  "main": "index.js",
6
6
  "scripts": {