@rhinostone/swig 2.4.2 → 2.5.0

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.
@@ -28,7 +28,7 @@ var _dangerousProps = require('@rhinostone/swig-core/lib/security').dangerousPro
28
28
  * @param {literal} varname Local-accessible object name to assign the macros to.
29
29
  */
30
30
  exports.compile = function (compiler, args, content, parents, options) {
31
- // Phase 2 (#T22): async-codegen branch. Parse stashed `[{path}, alias]`
31
+ // Async-codegen branch. Parse stashed `[{path}, alias]`
32
32
  // (no macro pre-render in async mode); emit IRImportDeferred so the
33
33
  // backend's `_swig.getTemplate` + `.exports` bind happens at runtime.
34
34
  if (options && options.codegenMode === 'async') {
@@ -62,21 +62,44 @@ exports.compile = function (compiler, args, content, parents, options) {
62
62
  };
63
63
  });
64
64
 
65
- // Emit the imported file's own (nested) imports first, un-namespaced, so the
66
- // macros defined below can reference them by their original alias at call
67
- // time. Without this, file-level imports are invisible inside macro bodies
68
- // and such calls silently render empty.
65
+ // Re-home every name a nested import binds under THIS import's alias, so the
66
+ // imported file's own imports stay local to it and never leak bare into the
67
+ // parent _ctx: `_ctx.<boundName>` -> `_ctx.<ctx>.<boundName>`. Before this,
68
+ // the nested setup was emitted bare, which clobbered a same-named parent var,
69
+ // corrupted macros that read live _ctx after a later {% set %}, and cascaded
70
+ // transitively-imported aliases into the parent. Mirrors the swig-twig fix in
71
+ // packages/swig-twig/lib/tags/import.js; compounds across import depth with
72
+ // no special-casing.
73
+ var innerReplacements = [];
69
74
  utils.each(nestedImports, function (arg) {
70
- out += arg.compiled;
75
+ utils.each(arg.boundNames, function (nm) {
76
+ innerReplacements.push({
77
+ ex: new RegExp('_ctx\\.' + nm + '(\\W)', 'g'),
78
+ re: '_ctx.' + ctx + '.' + nm + '$1'
79
+ });
80
+ });
81
+ });
82
+
83
+ // Emit the imported file's own (nested) imports first, re-homed under the
84
+ // alias, so the macros defined below resolve them at call time.
85
+ utils.each(nestedImports, function (arg) {
86
+ var c = arg.compiled;
87
+ utils.each(innerReplacements, function (re) {
88
+ c = c.replace(re.ex, re.re);
89
+ });
90
+ out += c;
71
91
  });
72
92
 
73
- // Replace all occurrences of all macros in this file with
74
- // proper namespaced definitions and calls
93
+ // Replace all occurrences of all macros in this file with proper namespaced
94
+ // definitions and calls, then re-home any nested-import references too.
75
95
  utils.each(macros, function (arg) {
76
96
  var c = arg.compiled;
77
97
  utils.each(replacements, function (re) {
78
98
  c = c.replace(re.ex, re.re);
79
99
  });
100
+ utils.each(innerReplacements, function (re) {
101
+ c = c.replace(re.ex, re.re);
102
+ });
80
103
  out += c;
81
104
  });
82
105
 
@@ -119,7 +142,11 @@ exports.parse = function (str, line, parser, types, stack, opts, swig) {
119
142
  if (token.name === 'import') {
120
143
  self.out.push({
121
144
  compiled: token.compile(compiler, token.args.slice(), token.content, [], compileOpts) + '\n',
122
- isImport: true
145
+ isImport: true,
146
+ // The nested import binds one namespace alias (the tail of its
147
+ // parsed args). compile() re-homes it under THIS import's alias so
148
+ // it never leaks bare into the parent _ctx.
149
+ boundNames: [token.args[token.args.length - 1]]
123
150
  });
124
151
  return;
125
152
  }
@@ -127,11 +154,11 @@ exports.parse = function (str, line, parser, types, stack, opts, swig) {
127
154
  return;
128
155
  }
129
156
  macroName = token.args[0];
130
- // Phase 2 (#T15): macro.compile now returns an IRMacro node
131
- // rather than a JS source string. Render it through the shared
132
- // backend so import.js still gets the JS source it performs
133
- // regex-surgery on for namespace-prefixing. The +'\n' trailing
134
- // newline matches the pre-Phase-2 compile output exactly.
157
+ // macro.compile returns an IRMacro node rather than a JS source
158
+ // string. Render it through the shared backend so import.js still
159
+ // gets the JS source it performs regex-surgery on for
160
+ // namespace-prefixing. The +'\n' trailing newline matches the
161
+ // legacy compile output exactly.
135
162
  out += backend.compile([token.compile(compiler, token.args, token.content, [], compileOpts)], [], compileOpts) + '\n';
136
163
  self.out.push({compiled: out, name: macroName});
137
164
  });
@@ -35,10 +35,10 @@ exports.compile = function (compiler, args, content, parents, options, blockName
35
35
  // Silly JSLint "Strange Loop" requires return to be in a conditional
36
36
  if (breaker && parentFile !== parent.name) {
37
37
  block = parent.blocks[blockName];
38
- // Phase 2: the block tag now returns `IRBlock { body: [...] }`.
39
- // Splice the matched parent block's body into an IRParent node;
40
- // the backend emits body verbatim plus a trailing newline for
41
- // byte-identity with the pre-Phase-2 JS-string emission shape.
38
+ // The block tag returns `IRBlock { body: [...] }`. Splice the
39
+ // matched parent block's body into an IRParent node; the backend
40
+ // emits body verbatim plus a trailing newline for byte-identity
41
+ // with the legacy JS-string emission shape.
42
42
  var blockNode = block.compile(compiler, [blockName], block.content, parents.slice(i + 1), options);
43
43
  return ir.parent((blockNode && blockNode.body) ? blockNode.body.concat([ir.legacyJS('\n')]) : [ir.legacyJS('\n')]);
44
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinostone/swig",
3
- "version": "2.4.2",
3
+ "version": "2.5.0",
4
4
  "description": "A simple, powerful, and extendable templating engine for node.js and browsers, similar to Django, Jinja2, and Twig.",
5
5
  "keywords": [
6
6
  "template",
@@ -21,7 +21,7 @@
21
21
  "Rhinostone <contact@gina.io>"
22
22
  ],
23
23
  "dependencies": {
24
- "@rhinostone/swig-core": "2.4.2"
24
+ "@rhinostone/swig-core": "2.5.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "blanket": "~1.1",