diff --git a/src/Engines/JavaScript.js b/src/Engines/JavaScript.js index 82abcf35e..3dac80265 100644 --- a/src/Engines/JavaScript.js +++ b/src/Engines/JavaScript.js @@ -8,6 +8,10 @@ const EventBusUtil = require("../Util/EventBusUtil"); class JavaScriptTemplateNotDefined extends EleventyBaseError {} class JavaScript extends TemplateEngine { + // which data keys to bind to `this` in JavaScript template functions + // static DATA_KEYS_TO_BIND = ["page", "eleventy"]; + static DATA_KEYS_TO_BIND = ["page", "eleventy"]; + constructor(name, dirs, config) { super(name, dirs, config); this.instances = {}; @@ -50,7 +54,9 @@ class JavaScript extends TemplateEngine { } return new mod(); } else { - return { render: mod }; + return { + render: mod, + }; } } else if ("data" in mod || "render" in mod) { if (!("render" in mod)) { @@ -67,7 +73,6 @@ class JavaScript extends TemplateEngine { const mod = require(TemplatePath.absolutePath(inputPath)); let inst = this._getInstance(mod); - if (inst) { this.instances[inputPath] = inst; } else { @@ -110,11 +115,10 @@ class JavaScript extends TemplateEngine { static wrapJavaScriptFunction(inst, fn) { return function (...args) { - if (inst && inst.page) { - this.page = inst.page; - } - if (inst && inst.eleventy) { - this.eleventy = inst.eleventy; + for (let key of JavaScript.DATA_KEYS_TO_BIND) { + if (inst && inst[key]) { + this[key] = inst[key]; + } } return fn.call(this, ...args); @@ -136,9 +140,13 @@ class JavaScript extends TemplateEngine { // TODO does this do anything meaningful for non-classes? // `inst` should have a normalized `render` function from _getInstance - // only blow away existing inst.page if it has a page.url - if (!inst.page || inst.page.url) { - inst.page = data.page; + for (let key of JavaScript.DATA_KEYS_TO_BIND) { + if (!inst[key] && data[key]) { + // only blow away existing inst.page if it has a page.url + if (key !== "page" || !inst.page || inst.page.url) { + inst[key] = data[key]; + } + } } Object.assign(inst, this.getJavaScriptFunctions(inst)); diff --git a/test/EleventyTest.js b/test/EleventyTest.js index 3611633b1..fd049cc75 100644 --- a/test/EleventyTest.js +++ b/test/EleventyTest.js @@ -693,3 +693,19 @@ test("Eleventy tag collection with spaces in the tag name, issue #2851", async ( t.deepEqual(result.length, result[0].data.collections.all.length); t.deepEqual(result[0].data.collections["tag with spaces"].length, 1); }); + +test("this.eleventy on JavaScript template functions, issue #2790", async (t) => { + t.plan(3); + + let elev = new Eleventy("./test/stubs-2790", "./test/stubs-2790/_site", { + config: function (eleventyConfig) { + eleventyConfig.addJavaScriptFunction("jsfunction", function () { + t.truthy(this.eleventy); + return this.eleventy.generator.split(" ")[0]; + }); + }, + }); + let result = await elev.toJSON(); + t.deepEqual(result.length, 1); + t.deepEqual(result[0].content, `

Eleventy

`); +}); diff --git a/test/stubs-2790/page.11ty.js b/test/stubs-2790/page.11ty.js new file mode 100644 index 000000000..026d69069 --- /dev/null +++ b/test/stubs-2790/page.11ty.js @@ -0,0 +1,3 @@ +module.exports = function ({ name }) { + return `

${this.jsfunction(name)}

`; +};