Skip to content

Commit

Permalink
add test + merge review
Browse files Browse the repository at this point in the history
  • Loading branch information
pieter-v committed May 16, 2017
1 parent 5ad3a91 commit ec84708
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 33 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,14 @@ export default Ember.Controller.extend({

The `fixed-grid-layout` will arrange the items in a grid to to fill the content area. The arguments for the layout are:

| Argument | Description |
| ------------ | --------------------------- |
| `itemWidth` | The width of each item |
| `itemHeight` | The height of each item |
| Argument | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| `itemWidth` | The width of each item |
| `itemHeight` | The height of each item |
| `itemCount` | The number of items passed to the collection. This is usually the number of items in the model (`model.length`). |

```hbs
{{#ember-collection items=model cell-layout=(fixed-grid-layout itemWidth itemHeight)
{{#ember-collection items=model cell-layout=(fixed-grid-layout itemWidth itemHeight itemCount)
scroll-left=scrollLeft scroll-top=scrollTop scroll-change=(action "scrollChange")
as |item index| }}
<div class="list-item">{{item.name}}</div>
Expand Down Expand Up @@ -195,7 +196,7 @@ export default Ember.Helper.helper(function(params, hash) {
* Returns the position of the item
*/
positionAt(itemIndex, clientWidth, clientHeight) {
return { x, y};
return {x, y};
}

/**
Expand Down
12 changes: 11 additions & 1 deletion addon/components/ember-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,23 @@ export default Ember.Component.extend({
}
},

useScrollIndex(scrollIndexAttr){
if (scrollIndexAttr === undefined) {
return false;
}
if (this._scrollIndex === scrollIndexAttr) {
return false;
}
return this._clientWidth || this._clientHeight;
},

updateScrollPosition(){
if (!this._scrollChange) { return; } // don't process bound scroll coords unless our action is being handled
let scrollIndexAttr = this.getAttr('scroll-index');
if (scrollIndexAttr !== undefined) {
scrollIndexAttr = parseInt(scrollIndexAttr, 10);
}
if (this._scrollIndex !== scrollIndexAttr && (this._clientWidth || this._clientHeight)) {
if (this.useScrollIndex(scrollIndexAttr)) {
let cellLayout = this._cellLayout;
let position = cellLayout.positionAt(scrollIndexAttr, this._clientWidth, this._clientHeight);
let width = cellLayout.widthAt(scrollIndexAttr, this._clientWidth, this._clientHeight);
Expand Down
4 changes: 2 additions & 2 deletions addon/layouts/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {formatPixelStyle} from '../utils/style-generators';

export default class Grid
{
constructor(cellWidth, cellHeight) {
this.length = 0;
constructor(cellWidth, cellHeight, length) {
this.length = length || 0;
this.bin = new FixedGrid(this, cellWidth, cellHeight);
}

Expand Down
2 changes: 1 addition & 1 deletion app/helpers/fixed-grid-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import Ember from 'ember';
import Grid from 'ember-collection/layouts/grid';

export default Ember.Helper.helper(function (params, hash) {
return new Grid(params[0], params[1]);
return new Grid(params[0], params[1], params[2]);
});
25 changes: 24 additions & 1 deletion tests/helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,28 @@ function checkContent(view, assert, expectedFirstItem, expectedCount) {
}
}

var size;
// lifted from antiscroll MIT license
function scrollbarSize() {
if (size === undefined) {
var div = $(
'<div class="antiscroll-inner" style="width:50px;height:50px;overflow-y:scroll;' +
'position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%"/>' +
'</div>'
);

$('body').append(div);
var w1 = $(div)[0].offsetWidth;
var w2 = $('div', div)[0].offsetWidth;
$(div).remove();

size = w1 - w2;
}

return size;
}


export {
itemPositions,
generateContent,
Expand All @@ -111,4 +133,5 @@ export {
findItems,
findVisibleItems,
checkContent,
sortItemsByPosition };
sortItemsByPosition,
scrollbarSize };
93 changes: 93 additions & 0 deletions tests/unit/scroll-index-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Ember from "ember";
import {moduleForComponent, test} from "ember-qunit";
import {checkContent, findScrollable, generateContent, scrollbarSize, sortItemsByPosition} from "../helpers/helpers";
import hbs from "htmlbars-inline-precompile";

let template = hbs`<div style={{size-to-style width height}}>{{#ember-collection
items=content
cell-layout=(fixed-grid-layout itemWidth itemHeight content.length)
estimated-width=width
estimated-height=height
scroll-index=scrollIndex
scroll-left=offsetX
scroll-top=offsetY
scroll-change=(action scrollChangeAction)
buffer=buffer
class="ember-collection"
as |item| ~}}
<div class="list-item">{{item.name}}</div>
{{~/ember-collection~}}</div>`;

function scrollChangeAction(scrollLeft, scrollTop) {
this.setProperties({
scrollLeft: scrollLeft,
scrollTop: scrollTop
});
}

let raf = window.requestAnimationFrame;
if (raf === undefined) {
raf = function (callback) {
setTimeout(callback, 16);
};
}

const RSVP = Ember.RSVP;

const content = generateContent(12);

moduleForComponent('ember-collection', 'scrollIndex', {
integration: true
});

test("base case", function (assert) {
let width = 100, height = 500, itemWidth = 50, itemHeight = 50;
let scrollIndex = 0;

Ember.run(() => {
this.setProperties({width, height, itemWidth, itemHeight, content, scrollIndex, scrollChangeAction});
this.render(template);
});

assert.equal(findScrollable(this).prop('scrollTop'), 0);

let positionSorted = sortItemsByPosition(this);

assert.equal(Ember.$(positionSorted[0]).text().trim(), "Item 1", "The first item has not been hidden");

Ember.run(() => {
this.set('width', 150);
});

assert.equal(findScrollable(this).prop('scrollTop'), 0);
checkContent(this, assert, 0, 5);
});

test("scroll but within content length", function (assert) {
let width = 100 + scrollbarSize(), height = 100 + scrollbarSize(), itemWidth = 50, itemHeight = 50;
let scrollIndex = 8;

Ember.run(() => {
this.setProperties({width, height, itemWidth, itemHeight, content, scrollIndex, scrollChangeAction});
this.render(template);
});

assert.equal(findScrollable(this).prop('scrollTop'), 135, 'Scrolled one row.');

Ember.run(() => {
this.set('width', 300 + scrollbarSize());
});

return new RSVP.Promise(function (resolve) {
raf(() => {
Ember.run(resolve);
});
}).then(() => {
assert.equal(findScrollable(this).prop('scrollTop'), 0, 'No scroll with wider list.');

let positionSorted = sortItemsByPosition(this);

assert.equal(Ember.$(positionSorted[0]).text().trim(), "Item 1", "The first item is not visible but in buffer.");
checkContent(this, assert, 0, 5);
});
});
23 changes: 1 addition & 22 deletions tests/unit/scroll-top-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Ember from 'ember';
import { test, moduleForComponent } from 'ember-qunit';
import { findScrollable, generateContent, sortItemsByPosition, checkContent } from '../helpers/helpers';
import { findScrollable, generateContent, sortItemsByPosition, checkContent, scrollbarSize } from '../helpers/helpers';
import template from '../templates/fixed-grid';

var raf = window.requestAnimationFrame;
Expand All @@ -12,27 +12,6 @@ if (raf === undefined) {

var RSVP = Ember.RSVP;

var size;
// lifted from antiscroll MIT license
function scrollbarSize() {
if (size === undefined) {
var div = $(
'<div class="antiscroll-inner" style="width:50px;height:50px;overflow-y:scroll;' +
'position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%"/>' +
'</div>'
);

$('body').append(div);
var w1 = $(div).innerWidth();
var w2 = $('div', div).innerWidth();
$(div).remove();

size = w1 - w2;
}

return size;
}

var content = generateContent(5);

moduleForComponent('ember-collection', 'scrollTop', {
Expand Down

0 comments on commit ec84708

Please sign in to comment.