diff --git a/docs/helpers/for-of.md b/docs/helpers/for-of.md
index 34e2e353..1597b91a 100644
--- a/docs/helpers/for-of.md
+++ b/docs/helpers/for-of.md
@@ -65,6 +65,32 @@
```
@codepen
+ If a positive integer value is passed, it will loop that number of times.
+ You can access the current index with `scope.index`:
+
+ ```js
+ import {stache} from "can";
+
+ var view = stache(`
+
+ {{# for(this.integerValue) }}
+ - {{scope.index}}
+ {{/ for }}
+
+ `);
+
+ var data = {
+ integerValue: 3
+ };
+
+ var frag = view(data);
+ console.log(frag.firstElementChild.innerHTML)
+ //-> 012
+
+ document.body.appendChild(frag);
+ ```
+ @codepen
+
If the `EXPRESSION` is falsy or an empty object or list, the `INVERSE` section will be rendered:
```js
@@ -102,12 +128,15 @@
{{/ for }}
```
- @param {can-stache/expressions/key-lookup|can-stache/expressions/call} EXPRESSION An
- expression that typically returns a [can-reflect.isListLike list like] data structure.
- If the value of the `EXPRESSION` is an observable list (for example: [can-define/list/list]), the resulting HTML is updated when the list changes. When a change in the list happens, only the minimum amount of DOM
- element changes occur. The list itself can also change, and a [can-diff/list/list difference]
- will be performed, which also will perform a minimal set of updates.
+ @param {can-stache/expressions/key-lookup|can-stache/expressions/call} EXPRESSION An expression that returns
+
+
+ - A [can-reflect.isListLike list like] data structure.
+ - An object-like (key-value) data structure.
+ - A positive integer Number
+
+ If the value of the `EXPRESSION` is an observable list ([can-define/list/list]) or map ([can-define/map/map]) and an item within it changes, only the minimum amount of DOM elements in the resulting HTML will change. If the list/map/or number value itself changes, a [can-diff/list/list difference] will be performed, resulting again in a minimal set of updates.
@param {can-stache.sectionRenderer} FN A subsection that is
diff --git a/helpers/-for-of-test.js b/helpers/-for-of-test.js
index b92c2632..8ce18b81 100644
--- a/helpers/-for-of-test.js
+++ b/helpers/-for-of-test.js
@@ -185,3 +185,31 @@ QUnit.test("for(value of object) works if value is keyed with a dot (issue#698)"
assert.equal( frag.firstChild.className, "[first-FIRST][second.key.has.dot-SECOND]");
});
+
+QUnit.test("for(integerValue) works", function (assert) {
+ var template = stache("{{#for(integerValue)}}[{{scope.index}}]{{/for}}
");
+ var frag = template({
+ integerValue: 3
+ });
+ assert.equal( frag.firstChild.innerHTML, "[0][1][2]" );
+});
+
+QUnit.test("for(ittr of intVal) works", function (assert) {
+ var template = stache("");
+ var object = {
+ intVal: 6
+ };
+ var frag = template({
+ object: object
+ });
+
+ assert.equal( frag.firstChild.className, "[0-0][1-1][2-2][3-3][4-4][5-5]" );
+});
+
+QUnit.test("for(integerValue) uses else block for negatives", function (assert) {
+ var template = stache("{{#for(integerValue)}}[{{scope.index}}]{{else}}val is negative{{/for}}
");
+ var frag = template({
+ integerValue: -3
+ });
+ assert.equal( frag.firstChild.innerHTML, "val is negative" );
+});
diff --git a/helpers/-for-of.js b/helpers/-for-of.js
index 01c5efd6..4afdd7e2 100644
--- a/helpers/-for-of.js
+++ b/helpers/-for-of.js
@@ -14,6 +14,23 @@ var bindAndRead = function (value) {
}
};
+function forOfInteger(integer, variableName, options) {
+ var result = [];
+ for (var i = 0; i < integer; i++) {
+ var variableScope = {};
+ if(variableName !== undefined){
+ variableScope[variableName] = i;
+ }
+ result.push(
+ options.fn( options.scope
+ .add({ index: i }, { special: true })
+ .addLetContext(variableScope) )
+ );
+ }
+
+ return options.stringOnly ? result.join('') : result;
+}
+
function forOfObject(object, variableName, options){
var result = [];
canReflect.each(object, function(val, key){
@@ -68,6 +85,9 @@ var forHelper = function(helperOptions) {
options = args.pop(),
resolved = bindAndRead(items);
+ if(resolved && resolved === Math.floor(resolved)) {
+ return forOfInteger(resolved, variableName, helperOptions);
+ }
if(resolved && !canReflect.isListLike(resolved)) {
return forOfObject(resolved,variableName, helperOptions);
}