From 50d17a8e9cf68bcf8b5e72eb25ee17e375b11856 Mon Sep 17 00:00:00 2001 From: Jelle De Loecker Date: Tue, 13 Feb 2024 11:36:24 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20block=20variables=20not=20?= =?UTF-8?q?being=20prepared=20properly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/blocks.js | 21 ++++++++ lib/core/renderer.js | 6 ++- lib/core/variables.js | 9 +++- test/30-renderer.js | 122 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 140 insertions(+), 18 deletions(-) diff --git a/lib/core/blocks.js b/lib/core/blocks.js index bbcc8efa..273db7be 100644 --- a/lib/core/blocks.js +++ b/lib/core/blocks.js @@ -127,6 +127,27 @@ Blocks.setMethod(function toDry() { return result; }); +/** + * Prepare this for cloning + * + * @author Jelle De Loecker + * @since 2.3.16 + * @version 2.3.16 + * + * @param {Renderer} renderer + */ +Blocks.setMethod(function _prepareClone(renderer, wm, custom_method) { + + let blocks = new Blocks(); + + for (let [key, entry] of this.values) { + entry = Bound.JSON.clone(entry, custom_method || 'toHawkejs', null, wm); + blocks.values.set(key, entry); + } + + return blocks; +}); + /** * Copy over blocks if this isntance doesn't have them * diff --git a/lib/core/renderer.js b/lib/core/renderer.js index 30f18205..26edcd96 100644 --- a/lib/core/renderer.js +++ b/lib/core/renderer.js @@ -821,7 +821,7 @@ Renderer.setMethod(function toJSON() { * * @author Jelle De Loecker * @since 2.2.11 - * @version 2.2.20 + * @version 2.3.16 */ Renderer.setMethod(function _prepareClone(wm, custom_method) { @@ -829,11 +829,13 @@ Renderer.setMethod(function _prepareClone(wm, custom_method) { wm = new WeakMap(); } + let blocks = this.blocks._prepareClone(this, wm, custom_method); + const result = { variables : this._prepareVariables(this.variables, wm, custom_method), expose_to_scene : this._prepareVariables(this.expose_to_scene, wm, custom_method), request : this.request, - blocks : this.blocks, + blocks : blocks, page_title : this.page_title, last_template : this.last_template, focus_block : this.focus_block, diff --git a/lib/core/variables.js b/lib/core/variables.js index f4d40acb..2bce5d92 100644 --- a/lib/core/variables.js +++ b/lib/core/variables.js @@ -49,7 +49,8 @@ Variables.setStatic(function cast(value, renderer) { }); /** - * Get the amount of variables + * Get the amount of variables in this instance. + * This ignores the parent's variables. * * @author Jelle De Loecker * @since 2.2.13 @@ -77,12 +78,16 @@ Variables.setMethod(function getOwnDict() { * * @author Jelle De Loecker * @since 2.2.13 - * @version 2.2.13 + * @version 2.3.16 * * @param {symbol} clone_name */ Variables.setMethod(function getExistingCloneIfValid(clone_name) { + if (!Object.hasOwn(this, clone_name)) { + return; + } + let result = this[clone_name]; if (!result) { diff --git a/test/30-renderer.js b/test/30-renderer.js index 33f65b87..fa0cae23 100644 --- a/test/30-renderer.js +++ b/test/30-renderer.js @@ -3,6 +3,7 @@ var assert = require('assert'), hawkejs; const Blast = __Protoblast; +let CloneTestClass; const RENDER = (done, ...render_args) => { let callback = render_args.pop(); @@ -21,6 +22,14 @@ describe('Renderer', function() { hawkejs = createHawkejsInstance(); hawkejs.parallel_task_limit = 1; hawkejs.addViewDirectory(__dirname + '/templates'); + + CloneTestClass = Blast.Collection.Function.inherits(null, function CloneTestClass(value) { + this.value = value; + }); + + CloneTestClass.setMethod(function toHawkejs() { + return new CloneTestClass('!!!' + this.value + '!!!'); + }); }); describe('#async(fnc)', function() { @@ -48,6 +57,62 @@ describe('Renderer', function() { done(); }); }); + + it('should correctly serialize variables', function(done) { + + let value = new CloneTestClass('value_to_clone'); + + let source = `<% this.doAsyncTest() %>`; + let compiled = hawkejs.compile(source); + + let renderer = RENDER(done, compiled, {bla: value}, function finished(err, html) { + + if (err) { + throw err; + } + + assert.strictEqual(html, 'The value is: "!!!value_to_clone!!!"'); + + let dried = Blast.Bound.JSON.dry(renderer); + + let has_cloned_value = dried.indexOf('"!!!value_to_clone!!!"') > -1; + let has_uncloned_value = dried.indexOf('"value_to_clone"') > -1; + + assert.strictEqual(has_uncloned_value, false, 'The uncloned value was found in the serialized Renderer'); + assert.strictEqual(has_cloned_value, true, 'The cloned value was not found in the serialized Renderer'); + + done(); + }); + + renderer.set('unused', value); + + renderer.doAsyncTest = function doAsyncTest() { + + return this.async((next) => { + let source = `The value is: "<%= test_instance.value %>"`; + let compiled = hawkejs.compile(source); + + let other_renderer = renderer.createSubRenderer(); + other_renderer.set('test_instance', value); + other_renderer.set('test_instance_2', value); + + let placeholder = other_renderer.addSubtemplate(compiled, {print: false}); + + placeholder.getContent((err, block) => { + + if (err) { + return next(err); + } + + try { + next(null, Blast.Bound.JSON.clone(block, 'toHawkejs')); + } catch (err) { + next(err); + } + }); + }); + }; + }); }); describe('#assign(name)', function() { @@ -144,23 +209,19 @@ This is the main content describe('#addSubTemplate(template, options)', () => { it('should correctly convert the variables', (done) => { - let CloneTestClass = Blast.Collection.Function.inherits(null, function CloneTestClass(value) { - this.value = value; - }); - - CloneTestClass.setMethod(function toHawkejs() { - return new CloneTestClass('!!!' + this.value + '!!!'); - }); - let value = new CloneTestClass('value_to_clone'); let renderer = hawkejs.createRenderer(); renderer.set('test_instance', value); + renderer.set('test_instance_2', value); + + let sub_renderer = renderer.createSubRenderer(); + sub_renderer.set('test_instance', value); let source = `The value is: "<%= test_instance.value %>"`; let compiled = hawkejs.compile(source); - let placeholder = renderer.addSubtemplate(compiled, {print: false}); + let placeholder = sub_renderer.addSubtemplate(compiled, {print: false}); //let cloned = Blast.Bound.JSON.clone(value, 'toHawkejs') @@ -171,7 +232,17 @@ This is the main content } try { + + let dried = Blast.Bound.JSON.dry(block_buffer); + + let has_cloned_value = dried.indexOf('"!!!value_to_clone!!!"') > -1; + let has_uncloned_value = dried.indexOf('"value_to_clone"') > -1; + + assert.strictEqual(has_uncloned_value, false, 'The uncloned value was found in the serialized BlockBuffer'); + assert.strictEqual(has_cloned_value, true, 'The cloned value was not found in the serialized BlockBuffer'); + assert.strictEqual(block_buffer.toHTML(), 'The value is: "!!!value_to_clone!!!"'); + } catch (err) { return done(err); } @@ -181,24 +252,47 @@ This is the main content async function testFoundation() { + let dried = Blast.Bound.JSON.dry(renderer); + + let has_cloned_value = dried.indexOf('"!!!value_to_clone!!!"') > -1; + let has_uncloned_value = dried.indexOf('"value_to_clone"') > -1; + + try { + assert.strictEqual(has_uncloned_value, false, 'The uncloned value was found in the serialized Renderer'); + assert.strictEqual(has_cloned_value, true, 'The cloned value was not found in the serialized Renderer'); + } catch (err) { + return done(err); + } + + dried = Blast.Bound.JSON.dry(sub_renderer); + + has_cloned_value = dried.indexOf('"!!!value_to_clone!!!"') > -1; + has_uncloned_value = dried.indexOf('"value_to_clone"') > -1; + + try { + assert.strictEqual(has_uncloned_value, false, 'The uncloned value was found in the serialized sub-Renderer'); + assert.strictEqual(has_cloned_value, true, 'The cloned value was not found in the serialized sub-Renderer'); + } catch (err) { + return done(err); + } + let foundation = renderer.foundation(); let content = await foundation.getContent(); //console.log('Content:', content) - let has_cloned_value = content.indexOf('"!!!value_to_clone!!!"') > -1; - let has_uncloned_value = content.indexOf('"value_to_clone"') > -1; + has_cloned_value = content.indexOf('"!!!value_to_clone!!!"') > -1; + has_uncloned_value = content.indexOf('"value_to_clone"') > -1; try { - assert.strictEqual(has_cloned_value, true, 'The cloned value was not found in the content'); - assert.strictEqual(has_uncloned_value, false, 'The uncloned value was found in the content'); + assert.strictEqual(has_uncloned_value, false, 'The uncloned value was found in the foundation content'); + assert.strictEqual(has_cloned_value, true, 'The cloned value was not found in the foundation content'); } catch (err) { return done(err); } done(); } - }); });