From 2a16800305a075ff76ea3a6c9b9ce6d4c5fdcd48 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Wed, 12 Jul 2017 15:28:59 -0400 Subject: [PATCH 1/2] Iterate keys of object when used with `for...in` loop --- tags/for.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tags/for.js b/tags/for.js index de94a7207..a16350718 100644 --- a/tags/for.js +++ b/tags/for.js @@ -38,8 +38,10 @@ module.exports = function (liquid) { render: function (scope, hash) { var collection = Liquid.evalExp(this.collection, scope) - if (!Array.isArray(collection) || - (Array.isArray(collection) && collection.length === 0)) { + if (isObject(collection)) { + collection = Object.keys(collection) + } + if (isEmpty(collection)) { return liquid.renderer.renderTemplates(this.elseTemplates, scope) } @@ -90,3 +92,18 @@ module.exports = function (liquid) { } }) } + +function isObject(collection) { + if (collection) { + const ctr = collection.constructor + return ctr === Object || ctr == null + } + return false +} + +function isEmpty(collection) { + if (Array.isArray(collection)) { + return !collection.length + } + return true +} From fb52c864b1b87617e15aa6493f9d7a68771003d1 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Thu, 13 Jul 2017 10:27:22 -0400 Subject: [PATCH 2/2] Add `isPlainObject` to 'util/underscore.js' --- src/util/underscore.js | 10 ++++++++++ tags/for.js | 20 +++----------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/util/underscore.js b/src/util/underscore.js index 85f9b54fb..f3c9a442b 100644 --- a/src/util/underscore.js +++ b/src/util/underscore.js @@ -94,6 +94,15 @@ function isObject (value) { return value !== null && typeof value === 'object' } +/* + * Checks if value's prototype is Object or undefined. + * @param {any} value The value to check. + * @return {Boolean} Returns true if value is a plain object, else false. + */ +function isPlainObject(value) { + return value && !value.constructor || value.constructor === Object +} + /* * A function to create flexibly-numbered lists of integers, * handy for each and map loops. start, if omitted, defaults to 0; step defaults to 1. @@ -119,6 +128,7 @@ function range (start, stop, step) { exports.isString = isString exports.isArray = isArray exports.isObject = isObject +exports.isPlainObject = isPlainObject exports.isError = isError exports.range = range diff --git a/tags/for.js b/tags/for.js index a16350718..fcc8b11b3 100644 --- a/tags/for.js +++ b/tags/for.js @@ -1,6 +1,7 @@ const Liquid = require('..') const lexical = Liquid.lexical const mapSeries = require('../src/util/promise.js').mapSeries +const isPlainObject = require('../src/util/underscore.js').isPlainObject const RenderBreakError = Liquid.Types.RenderBreakError const assert = require('../src/util/assert.js') const re = new RegExp(`^(${lexical.identifier.source})\\s+in\\s+` + @@ -38,10 +39,10 @@ module.exports = function (liquid) { render: function (scope, hash) { var collection = Liquid.evalExp(this.collection, scope) - if (isObject(collection)) { + if (isPlainObject(collection)) { collection = Object.keys(collection) } - if (isEmpty(collection)) { + if (!Array.isArray(collection) || !collection.length) { return liquid.renderer.renderTemplates(this.elseTemplates, scope) } @@ -92,18 +93,3 @@ module.exports = function (liquid) { } }) } - -function isObject(collection) { - if (collection) { - const ctr = collection.constructor - return ctr === Object || ctr == null - } - return false -} - -function isEmpty(collection) { - if (Array.isArray(collection)) { - return !collection.length - } - return true -}