@rhinostone/swig 2.5.0 → 2.5.2
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.
- package/HISTORY.md +24 -0
- package/README.md +12 -5
- package/ROADMAP.md +14 -2
- package/dist/swig.js +33 -4
- package/dist/swig.min.js +11 -2
- package/dist/swig.min.js.map +1 -1
- package/eslint.config.js +32 -0
- package/lib/parser.js +3 -0
- package/lib/swig.js +177 -1
- package/lib/tags/extends.js +25 -0
- package/lib/tags/set.js +5 -5
- package/package.json +8 -20
- package/.eslintrc.json +0 -24
package/HISTORY.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
[2.5.2](https://github.com/gina-io/swig/tree/v2.5.2) / 2026-06-02
|
|
2
|
+
-----------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
* **Fixed** Dynamic `{% extends %}` paths (e.g. `{% extends layout_var %}`) now resolve on the async-loader render path (`renderFile(path, locals, cb)` with `loader.async`) in `@rhinostone/swig-twig` and `@rhinostone/swig-jinja2`, matching native swig and real Twig/Jinja2. Static string-literal extends and the synchronous render path are unchanged.
|
|
5
|
+
|
|
6
|
+
* **Fixed** Dynamic `{% extends %}` paths (e.g. `{% extends layout_var %}`) now resolve on the async-loader render path (`renderFile(path, locals, cb)` with `loader.async`); previously a dynamic parent path produced a garbage template lookup. Static string-literal extends and the synchronous render path are unchanged.
|
|
7
|
+
|
|
8
|
+
[2.5.1](https://github.com/gina-io/swig/tree/v2.5.1) / 2026-05-28
|
|
9
|
+
-----------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
* **Fixed** Restored the JSDoc blocks on the top-level Swig public API methods (setFilter, setTag, setExtension, precompile, compile, compileFile, render, renderFile, run, invalidateCache) that were inadvertently stripped from lib/swig.js when the Swig constructor body was carved into @rhinostone/swig-core/lib/engine.js. The documentation comments now sit above the corresponding exports.* re-exports where make build-docs and IDE hover tooling read them. No runtime behavior change — the published lib/ code is byte-identical and only the JSDoc surface is updated.
|
|
12
|
+
|
|
13
|
+
* **Changed** Rephrased two stale internal-process tracker references in lib/tags/set.js source comments that survived the prior single-line audit sweep because the markers spanned a line wrap. The explanatory content is preserved verbatim; only the dead tracker tokens are dropped, per the in-repo no-internal-markers-in-shipping-source convention. No behavior change.
|
|
14
|
+
|
|
15
|
+
* **Changed** Migrated the test toolchain from mocha 1.12.0 to the Node.js built-in test runner (node:test) with built-in line coverage, removing the mocha, blanket, and travis-cov dev dependencies. This clears all 6 npm audit advisories (4 high, 2 critical) that were rooted in mocha's transitive dependency tree; the full suite passes unchanged and the 95% coverage gate over lib/ is preserved. The published package is unaffected — its only runtime dependency remains @rhinostone/swig-core.
|
|
16
|
+
|
|
17
|
+
* **Changed** Removed the unmaintained phantomjs and mocha-phantomjs browser-test toolchain, dropping the vulnerable form-data (CVE-2025-7783) and the rest of the legacy request dependency subtree from the dev dependency tree. Browser parity is verified through the production bundle build, pending a modern browser-test harness.
|
|
18
|
+
|
|
19
|
+
* **Changed** Upgraded the ESLint dev dependency from 8.57.1 to 9.x and migrated the lint configuration from the deprecated .eslintrc.json (eslintrc format) to the flat-config eslint.config.js, adding the globals dev dependency. The lenient rule set is preserved exactly (no indent enforcement, eqeqeq/no-eval/no-new-func off, semi always, max-len 600, plus an explicit linterOptions.reportUnusedDisableDirectives off to match the eslintrc default). ESLint 9 raises the lint toolchain Node floor to >=18.18, which affects development and CI only; the published package is unaffected and its only runtime dependency remains @rhinostone/swig-core.
|
|
20
|
+
|
|
21
|
+
* **Changed** Upgraded the example/development express dependency from the abandoned 3.x line to 4.x, dropping the vulnerable transitive morgan (CVE-2019-5413) and the legacy connect subtree from the dev dependency tree. The Express view-engine example runs unchanged. The published package is unaffected; its only runtime dependency remains @rhinostone/swig-core.
|
|
22
|
+
|
|
23
|
+
* **Changed** Upgraded the development lodash dependency from 1.3.x to 4.x, dropping the prototype-pollution and command-injection advisories (affecting lodash through 4.17.23) from the dev dependency tree. lodash is a test-only utility and the full suite passes unchanged on 4.x. The published package is unaffected; its only runtime dependency remains @rhinostone/swig-core.
|
|
24
|
+
|
|
1
25
|
[2.5.0](https://github.com/gina-io/swig/tree/v2.5.0) / 2026-05-27
|
|
2
26
|
-----------------------------------------------------------------
|
|
3
27
|
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ Swig
|
|
|
3
3
|
|
|
4
4
|
[](https://github.com/gina-io/swig/actions/workflows/ci.yml) [](https://www.npmjs.com/package/@rhinostone/swig) [](https://www.npmjs.com/package/@rhinostone/swig) [](https://socket.dev/npm/package/@rhinostone/swig)
|
|
5
5
|
|
|
6
|
-
> **Multi-flavor template engine** for Node.js and browsers — native Swig syntax (Jinja2/Django-inspired) and
|
|
6
|
+
> **Multi-flavor template engine** for Node.js and browsers — native Swig syntax (Jinja2/Django-inspired), Twig syntax, and Python Jinja2 syntax via dedicated frontends sharing one IR backend. [gina-io/swig](https://github.com/gina-io/swig) started as a maintained continuation of the abandoned [paularmstrong/swig](https://github.com/paularmstrong/swig) (last released 2014) and is now a standalone project. Security and bug fixes ship here.
|
|
7
7
|
|
|
8
8
|
> **Part of the [Gina](https://github.com/gina-io/gina) ecosystem.** This is the built-in template engine for [Gina](https://gina.io) ([npm](https://www.npmjs.com/package/gina)), a Node.js MVC framework with HTTP/2, multi-bundle architecture, and scope-based data isolation.
|
|
9
9
|
|
|
@@ -11,6 +11,8 @@ Swig is a **Jinja2/Django-inspired** template engine for node.js and browsers. T
|
|
|
11
11
|
|
|
12
12
|
> **Coming from Twig?** Install [@rhinostone/swig-twig](https://www.npmjs.com/package/@rhinostone/swig-twig) instead — a dedicated Twig-syntax frontend with closer parity than working around incompatibilities here.
|
|
13
13
|
|
|
14
|
+
> **Coming from Python Jinja2?** Install [@rhinostone/swig-jinja2](https://www.npmjs.com/package/@rhinostone/swig-jinja2) — a dedicated Jinja2-syntax frontend (near-subset) with closer parity than porting to native Swig syntax here.
|
|
15
|
+
|
|
14
16
|
Workspace packages
|
|
15
17
|
------------------
|
|
16
18
|
|
|
@@ -18,9 +20,10 @@ Workspace packages
|
|
|
18
20
|
| --- | --- | --- |
|
|
19
21
|
| [`@rhinostone/swig`](https://www.npmjs.com/package/@rhinostone/swig) | Native Swig syntax (Jinja2/Django-inspired). Drop-in for `@rhinostone/swig@1.x` consumers. | Upgrading from `@rhinostone/swig@1.x`, or starting fresh with Swig syntax. |
|
|
20
22
|
| [`@rhinostone/swig-twig`](https://www.npmjs.com/package/@rhinostone/swig-twig) | Twig-syntax frontend with closer Twig parity. | Migrating from PHP Twig, or writing new templates in Twig syntax. |
|
|
23
|
+
| [`@rhinostone/swig-jinja2`](https://www.npmjs.com/package/@rhinostone/swig-jinja2) | Python Jinja2-syntax frontend (near-subset). | Migrating from Python Jinja2, or writing new templates in Jinja2 syntax. |
|
|
21
24
|
| [`@rhinostone/swig-core`](https://www.npmjs.com/package/@rhinostone/swig-core) | Shared IR, backend, and runtime primitives. | Building a custom flavor frontend. Otherwise pulled in transitively. |
|
|
22
25
|
|
|
23
|
-
Each frontend pins the matching `@rhinostone/swig-core` version exactly
|
|
26
|
+
Each frontend pins the matching `@rhinostone/swig-core` version exactly (no caret, no tilde) — frontends and the core release in lockstep on every cut.
|
|
24
27
|
|
|
25
28
|
Features
|
|
26
29
|
--------
|
|
@@ -29,7 +32,7 @@ Features
|
|
|
29
32
|
* [Express](http://expressjs.com/) compatible.
|
|
30
33
|
* Object-Oriented template inheritance.
|
|
31
34
|
* Apply filters and transformations to output in your templates.
|
|
32
|
-
* **Hardened against prototype-pollution** — `__proto__` / `constructor` / `prototype` blocked at parser, tag-side, and IR-emission layers. CVE-2023-25345 fully patched.
|
|
35
|
+
* **Hardened against prototype-pollution** — `__proto__` / `constructor` / `prototype` blocked at parser, tag-side, and IR-emission layers. CVE-2023-25345 fully patched. 11 CVE regression cases under [`tests/regressions.test.js`](./tests/regressions.test.js).
|
|
33
36
|
* Automatically escapes all variable output (HTML by default; configurable per-call).
|
|
34
37
|
* Lots of iteration and conditionals supported.
|
|
35
38
|
* Robust without the bloat.
|
|
@@ -61,6 +64,10 @@ For Twig syntax:
|
|
|
61
64
|
|
|
62
65
|
npm install @rhinostone/swig-twig
|
|
63
66
|
|
|
67
|
+
For Python Jinja2 syntax:
|
|
68
|
+
|
|
69
|
+
npm install @rhinostone/swig-jinja2
|
|
70
|
+
|
|
64
71
|
Documentation
|
|
65
72
|
-------------
|
|
66
73
|
|
|
@@ -109,7 +116,7 @@ Migrating from `@rhinostone/swig@1.x`
|
|
|
109
116
|
|
|
110
117
|
`@rhinostone/swig@2.x` is **drop-in for `1.x` consumers** — `swig.compileFile`, `swig.renderFile`, `swig.setFilter`, `swig.setTag`, and the rest of the public API are unchanged. The internal carve into [@rhinostone/swig-core](https://www.npmjs.com/package/@rhinostone/swig-core) is transparent (test gate during the alpha cycle: byte-identical compiled output against the `1.x` test suite).
|
|
111
118
|
|
|
112
|
-
`2.0.0` also ships [@rhinostone/swig-twig](https://www.npmjs.com/package/@rhinostone/swig-twig), a sibling Twig-syntax frontend. Switching is opt-in — your existing `@rhinostone/swig` install keeps working.
|
|
119
|
+
`2.0.0` also ships [@rhinostone/swig-twig](https://www.npmjs.com/package/@rhinostone/swig-twig), a sibling Twig-syntax frontend, and `2.5.0` adds [@rhinostone/swig-jinja2](https://www.npmjs.com/package/@rhinostone/swig-jinja2) for Python Jinja2 syntax. Switching is opt-in — your existing `@rhinostone/swig` install keeps working.
|
|
113
120
|
|
|
114
121
|
Migrating from Jinja2 or Django
|
|
115
122
|
-------------------------------
|
|
@@ -132,7 +139,7 @@ How it works
|
|
|
132
139
|
|
|
133
140
|
Swig reads template files and translates them into cached JavaScript functions. The pipeline is: parse → emit IR → lower IR to JS source → `new Function(...)`. At render time, the compiled function runs against a context object to produce the output string.
|
|
134
141
|
|
|
135
|
-
In `2.x`, frontend parsers (native Swig syntax in [@rhinostone/swig](https://www.npmjs.com/package/@rhinostone/swig), Twig syntax in [@rhinostone/swig-twig](https://www.npmjs.com/package/@rhinostone/swig-twig)) emit a shared intermediate representation. The backend in [@rhinostone/swig-core](https://www.npmjs.com/package/@rhinostone/swig-core) lowers IR to JS. New flavors plug in at the frontend without touching the runtime.
|
|
142
|
+
In `2.x`, frontend parsers (native Swig syntax in [@rhinostone/swig](https://www.npmjs.com/package/@rhinostone/swig), Twig syntax in [@rhinostone/swig-twig](https://www.npmjs.com/package/@rhinostone/swig-twig), Python Jinja2 syntax in [@rhinostone/swig-jinja2](https://www.npmjs.com/package/@rhinostone/swig-jinja2)) emit a shared intermediate representation. The backend in [@rhinostone/swig-core](https://www.npmjs.com/package/@rhinostone/swig-core) lowers IR to JS. New flavors plug in at the frontend without touching the runtime.
|
|
136
143
|
|
|
137
144
|
License
|
|
138
145
|
-------
|
package/ROADMAP.md
CHANGED
|
@@ -14,14 +14,26 @@ _No near-term scheduled items. See [Future (post-2.0)](#future-post-20) for upco
|
|
|
14
14
|
|
|
15
15
|
| Status | Item |
|
|
16
16
|
| --- | --- |
|
|
17
|
-
| Planned | Async parse path for dynamic targets —
|
|
17
|
+
| Planned | Async parse path for the remaining dynamic targets — runtime-resolved `{% import %}` / `{% from %}` paths on the async-codegen branch. Static-target async dispatch shipped in 2.2.0; dynamic `{% extends %}` shipped in 2.5.2 (native + Twig + Jinja2) and dynamic `{% include %}` paths already resolve (the include path has always been an expression). Dynamic `import` / `from` are on hold pending consumer demand. |
|
|
18
18
|
| Planned | Ship a Django frontend as an additional `@rhinostone/swig-*` package. On demand — when there's concrete user demand. (The Jinja2 frontend shipped in `2.5.0`.) |
|
|
19
|
-
| Planned | Test framework migration. Replace mocha 1.x + expect.js with `node:test` + `node:assert/strict`,
|
|
19
|
+
| Planned | Test framework migration. Replace mocha 1.x + expect.js with `node:test` + `node:assert/strict`, add a modern browser-test harness (the legacy phantomjs runner has been removed), swap blanket for `c8`. (The Node engines bump is upstream-driven by gina and is being treated as done.) |
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
23
|
## Completed
|
|
24
24
|
|
|
25
|
+
### v2.5.2 (June 2026)
|
|
26
|
+
|
|
27
|
+
- Dynamic `{% extends %}` paths now resolve on the async render path (`renderFile(path, locals, cb)` against a loader with `loader.async === true`) across all three frontends — native `@rhinostone/swig`, `@rhinostone/swig-twig`, and `@rhinostone/swig-jinja2`. A dynamic parent (e.g. `{% extends layout_var %}`) is lowered to a deferred IR expression and resolved at render time, matching real Twig and Jinja2; previously a dynamic parent path was rejected at parse time (Twig / Jinja2) or produced a garbage template lookup (native). Static string-literal `{% extends %}` and the synchronous render path are unchanged — on the sync path a dynamic parent still requires a string literal (dispatch the chosen parent in the caller).
|
|
28
|
+
- All four packages (`@rhinostone/swig`, `@rhinostone/swig-core`, `@rhinostone/swig-twig`, `@rhinostone/swig-jinja2`) released in lockstep at `2.5.2`.
|
|
29
|
+
|
|
30
|
+
### v2.5.1 (May 2026)
|
|
31
|
+
|
|
32
|
+
- Restored JSDoc on the top-level `@rhinostone/swig` public API methods (`setFilter`, `setTag`, `setExtension`, `precompile`, `compile`, `compileFile`, `render`, `renderFile`, `run`, `invalidateCache`). The blocks were inadvertently stripped from `lib/swig.js` when the Swig constructor body was carved into `@rhinostone/swig-core` during the `2.0.0-alpha.1` cycle; `make build-docs` and IDE hover tooling read from `lib/swig.js`, so the documented surface for all ten methods had been missing since the carve. Doc-only restoration; `renderFile`'s block also documents the `v2.2.0` async-codegen dispatch (set `loader.async === true` on the loader to opt in).
|
|
33
|
+
- Cleaned two stale internal-process tracker references from `lib/tags/set.js` source comments; the explanatory content is preserved and only the dead reference tokens were dropped.
|
|
34
|
+
- Dev-tooling modernization riding the same release: retired the unmaintained `phantomjs` browser-test toolchain (also dropped the vulnerable `form-data` from the dev tree); bumped the example/development `express` dependency from `~3` to `^4` (also dropped the vulnerable `morgan` and `minimist` from the dev tree); bumped the test-utility `lodash` dependency from `~1.3.1` to `^4` (cleared five `lodash` advisories from the dev tree); migrated the test toolchain from `mocha` 1.12.0 to the Node built-in `node:test` runner with built-in line coverage (cleared the six remaining dev-tree audit findings, taking `npm audit` to zero); migrated the ESLint dev dependency from 8.x to 9.x with the new flat-config (`.eslintrc.json` → `eslint.config.js`), clearing the six "deprecated by maintainer" Socket Low alerts on the repo scan. None of this affects the published runtime — only the dev/CI toolchain.
|
|
35
|
+
- All four packages (`@rhinostone/swig`, `@rhinostone/swig-core`, `@rhinostone/swig-twig`, `@rhinostone/swig-jinja2`) released in lockstep at `2.5.1`. The runtime in `@rhinostone/swig-core` / `@rhinostone/swig-twig` / `@rhinostone/swig-jinja2` is functionally identical to `2.5.0`; only `@rhinostone/swig`'s `lib/swig.js` and `lib/tags/set.js` carry source-comment changes.
|
|
36
|
+
|
|
25
37
|
### v2.5.0 (May 2026)
|
|
26
38
|
|
|
27
39
|
- Added `@rhinostone/swig-jinja2`, a Python Jinja2-syntax frontend on the shared `@rhinostone/swig-core` engine — the third dialect in the multi-flavor family alongside native swig and `@rhinostone/swig-twig`. Ships 13 tags (`set`, `if` / `elif` / `else`, `for` with `else`, `block`, `extends`, `include`, `macro`, `import`, `from`, `raw`, `filter`, `with`, `autoescape`), 39 filters, and 16 `is` tests, plus the `**` / `//` / `~` operators, inline-if, Python slicing, and `{{- … -}}` whitespace control. Async loader support via `renderFileAsync` / `compileFileAsync`. Autoescape and the CVE-2023-25345 guards are inherited from `@rhinostone/swig-core`. Every filter and is-test was cross-checked against Python Jinja2 3.x; the behavioural differences (where the JavaScript runtime diverges from CPython) and the explicit non-goals (no sandboxed rendering, `{% call %}` / `{% do %}` / `{% trans %}`, the `map` / `select` filter family, macro kwargs) are documented in the Jinja2 templating guide.
|
package/dist/swig.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Swig v2.5.
|
|
1
|
+
/*! Swig v2.5.2 | https://github.com/gina-io/swig | @license https://github.com/gina-io/swig/blob/master/LICENSE */
|
|
2
2
|
/*! DateZ (c) 2011 Tomo Universalis | @license https://github.com/ocrybit/DateZ/blob/master/LISENCE */
|
|
3
3
|
(() => {
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -664,11 +664,29 @@
|
|
|
664
664
|
// lib/tags/extends.js
|
|
665
665
|
var require_extends = __commonJS({
|
|
666
666
|
"lib/tags/extends.js"(exports) {
|
|
667
|
+
var _t = require_tokentypes();
|
|
667
668
|
exports.compile = function() {
|
|
668
669
|
};
|
|
669
670
|
exports.parse = function() {
|
|
670
671
|
return true;
|
|
671
672
|
};
|
|
673
|
+
exports.lowerExpr = function(parser, tokens) {
|
|
674
|
+
var i, tk, pathTokens = [];
|
|
675
|
+
for (i = 0; i < tokens.length; i += 1) {
|
|
676
|
+
tk = tokens[i];
|
|
677
|
+
if (tk.type === _t.WHITESPACE) {
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
pathTokens.push(tk);
|
|
681
|
+
}
|
|
682
|
+
if (!pathTokens.length) {
|
|
683
|
+
return void 0;
|
|
684
|
+
}
|
|
685
|
+
if (pathTokens.length === 1 && pathTokens[0].type === _t.STRING) {
|
|
686
|
+
return void 0;
|
|
687
|
+
}
|
|
688
|
+
return { file: parser.parseExpr(tokens) };
|
|
689
|
+
};
|
|
672
690
|
exports.ends = false;
|
|
673
691
|
}
|
|
674
692
|
});
|
|
@@ -2990,7 +3008,7 @@
|
|
|
2990
3008
|
source = source.replace(/\r\n/g, "\n");
|
|
2991
3009
|
var escape = opts.autoescape, tagOpen = opts.tagControls[0], tagClose = opts.tagControls[1], varOpen = opts.varControls[0], varClose = opts.varControls[1], escapedTagOpen = escapeRegExp(tagOpen), escapedTagClose = escapeRegExp(tagClose), escapedVarOpen = escapeRegExp(varOpen), escapedVarClose = escapeRegExp(varClose), tagStrip = new RegExp("^" + escapedTagOpen + "-?\\s*|\\s*-?" + escapedTagClose + "$", "g"), tagStripBefore = new RegExp("^" + escapedTagOpen + "-"), tagStripAfter = new RegExp("-" + escapedTagClose + "$"), varStrip = new RegExp("^" + escapedVarOpen + "-?\\s*|\\s*-?" + escapedVarClose + "$", "g"), varStripBefore = new RegExp("^" + escapedVarOpen + "-"), varStripAfter = new RegExp("-" + escapedVarClose + "$"), cmtOpen = opts.cmtControls[0], cmtClose = opts.cmtControls[1], anyChar = "[\\s\\S]*?", splitter = new RegExp(
|
|
2992
3010
|
"(" + escapedTagOpen + anyChar + escapedTagClose + "|" + escapedVarOpen + anyChar + escapedVarClose + "|" + escapeRegExp(cmtOpen) + anyChar + escapeRegExp(cmtClose) + ")"
|
|
2993
|
-
), line = 1, stack = [], parent = null, tokens = [], blocks = {}, inRaw = false, stripNext;
|
|
3011
|
+
), line = 1, stack = [], parent = null, parentExpr = null, tokens = [], blocks = {}, inRaw = false, stripNext;
|
|
2994
3012
|
function parseVariable(str, line2) {
|
|
2995
3013
|
var tokens2 = lexer.read(utils.strip(str)), parser, node;
|
|
2996
3014
|
parser = new TokenParser(tokens2, filters, escape, line2, opts.filename);
|
|
@@ -3081,6 +3099,7 @@
|
|
|
3081
3099
|
if (token) {
|
|
3082
3100
|
if (token.name === "extends") {
|
|
3083
3101
|
parent = token.args.join("").replace(/^\'|\'$/g, "").replace(/^\"|\"$/g, "");
|
|
3102
|
+
parentExpr = token.irExpr && token.irExpr.file;
|
|
3084
3103
|
} else if (token.block && !stack.length) {
|
|
3085
3104
|
blocks[token.args.join("")] = token;
|
|
3086
3105
|
}
|
|
@@ -3121,6 +3140,7 @@
|
|
|
3121
3140
|
return {
|
|
3122
3141
|
name: opts.filename,
|
|
3123
3142
|
parent,
|
|
3143
|
+
parentExpr,
|
|
3124
3144
|
tokens,
|
|
3125
3145
|
blocks
|
|
3126
3146
|
};
|
|
@@ -4388,7 +4408,7 @@
|
|
|
4388
4408
|
}
|
|
4389
4409
|
});
|
|
4390
4410
|
return ir.extendsDeferred(
|
|
4391
|
-
ir.literal("string", tokens.parent),
|
|
4411
|
+
tokens.parentExpr || ir.literal("string", tokens.parent),
|
|
4392
4412
|
childBlocks,
|
|
4393
4413
|
childIRs,
|
|
4394
4414
|
options.filename || ""
|
|
@@ -4682,7 +4702,7 @@
|
|
|
4682
4702
|
var loaders = require_loaders2();
|
|
4683
4703
|
var preWalker = require_pre_walker();
|
|
4684
4704
|
var engine = require_engine();
|
|
4685
|
-
exports.version = "2.5.
|
|
4705
|
+
exports.version = "2.5.2";
|
|
4686
4706
|
var defaultOptions = {
|
|
4687
4707
|
autoescape: true,
|
|
4688
4708
|
varControls: ["{{", "}}"],
|
|
@@ -4917,6 +4937,15 @@
|
|
|
4917
4937
|
* a tight IR keeps the shape honest for future flavor backends.
|
|
4918
4938
|
* @private
|
|
4919
4939
|
*/
|
|
4940
|
+
/*!
|
|
4941
|
+
* Lower a dynamic parent-path to IR so `{% extends layout_var %}`
|
|
4942
|
+
* resolves at render time on the async codegen path. A lone
|
|
4943
|
+
* string-literal path (`{% extends "x.html" %}`) returns undefined, so
|
|
4944
|
+
* the engine keeps its existing tokens.parent string + ir.literal path
|
|
4945
|
+
* unchanged; only a dynamic path is lowered. Mirrors include.js. The
|
|
4946
|
+
* resulting IRExpr is read back as token.irExpr.file by the parser
|
|
4947
|
+
* splitter and stashed on the sibling tokens.parentExpr slot.
|
|
4948
|
+
*/
|
|
4920
4949
|
/*!
|
|
4921
4950
|
* JSON-escape a literal text chunk for embedding inside a JS
|
|
4922
4951
|
* double-quoted string literal in the compiled template body.
|