Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ coverage
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

move-into-view.js
move-into-view.min.js

# Dependency directories
node_modules
jspm_packages
Expand Down
1 change: 1 addition & 0 deletions dist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.MoveIntoView = require('./');
69 changes: 66 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,79 @@ function _parentsOf (target, isParent) {
}
}

/**
* Calculate wrapper's position based on an aspect ratio provided
*
* @name _position
* @function
* @access private
* @param {Number} aspectX aspect x (default 0.5)
* @param {Number} aspectY aspect y (default 0.5)
* @returns {Object} Coordinates
*/
function _position (aspectX, aspectY) {
aspectX = (typeof aspectX === 'undefined') ? 0.5 : aspectX;
aspectY = (typeof aspectY === 'undefined') ? 0.5 : aspectY;

var parent = this.parent.getBoundingClientRect();
var wrapper = this.wrapper.getBoundingClientRect();
var target = this.target.getBoundingClientRect();

var x = target.left + (target.width * aspectX) - (parent.width * aspectX);
var y = target.top + (target.height * aspectY) - parent.height * aspectY;

if (x < 0) x = 0;
if ((wrapper.width - x) < parent.width) x = wrapper.width - parent.width;

if (y < 0) y = 0;
if ((wrapper.height - y) < parent.height) y = wrapper.height - parent.height;

return {
x: x,
y: y
};
}

/**
* Applying elements position
*
* @name _move
* @function
* @access private
* @param {String} dir Direction
* @param {Number} aspectX
* @param {Number} aspectY
*/
function _move (dir, aspect) {
var position = this.position(aspect, aspect);

if (dir === 'x' || dir === 'both') {
this.wrapper.style.left = (position.x * -1) + 'px';
}

if (dir === 'y' || dir === 'both') {
this.wrapper.style.top = (position.y * -1) + 'px';
}

return this;
}

function MoveIntoView (target, options) {
target = target || this;
options = options || {};

var parents = _parentsOf(target, options.isParent);

var view = {
target: target,
wrapper: parents.wrapper,
parent: parents.parent
parent: parents.parent,
position: _position,
move: { }
};

view.move.x = _move.bind(view, 'x');
view.move.y = _move.bind(view, 'y');
view.move.both = _move.bind(view, 'both');

return view;
}

Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"test": "npm run lint && npm run karma && codecov",
"karma": "karma start karma.conf.js",
"lint": "eslint .",
"semantic-release": "semantic-release pre && npm publish && semantic-release post"
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"prepublish": "mkdir -p dist && browserify --ignore-missing dist.js > move-into-view.js && browserify --ignore-missing dist.js | uglifyjs -c > move-into-view.min.js"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -43,7 +44,8 @@
"karma-nyan-reporter": "^0.2.5",
"karma-phantomjs-launcher": "^1.0.2",
"mocha": "^3.2.0",
"watchify": "^3.8.0",
"semantic-release": "^6.3.2"
"semantic-release": "^6.3.2",
"uglify-js": "^2.8.16",
"watchify": "^3.8.0"
}
}
122 changes: 122 additions & 0 deletions tests/horizontal-positioning.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
var MoveIntoView = require('../');
var expect = require('chai').expect;
var resetCSS = require('./css/reset');

var CSSTate = require('csstate');
var cst = new CSSTate();

function vMock () {
var vParent = document.createElement('div');
vParent.classList.add('scrollable');
vParent.setAttribute('id', 'scrollable');
var vChild = document.createElement('div');
vChild.classList.add('wrapper');
vChild.setAttribute('id', 'wrapper');
vParent.appendChild(vChild);

for (var i = 0; i < 10; i++) {
var el = document.createElement('div');
el.classList.add('child');
vChild.appendChild(el);
}

return vParent;
}

var vMockCSS = {
'.scrollable': {
'position': 'relative',
'width': '90px',
'height': '120px',
'overflow': 'hidden'
},

'.wrapper': {
'position': 'absolute'
},

'.child': {
'display': 'block',
'width': '90px',
'height': '60px'
}
};

describe('Test element setup', function () {
var vParent = null;

beforeEach(function () {
cst.rule(resetCSS);
cst.rule(vMockCSS);
});

afterEach(function () {
cst.exit();
});

before(function () {
vParent = vMock();
document.body.appendChild(vParent);
});

after(function () {
document.body.removeChild(vParent);
});

it('should setup mockup currectly', function () {
expect(MoveIntoView).to.be.exists;

var scrollable = document.getElementById('scrollable');

expect(scrollable.getBoundingClientRect().height).to.be.equal(120);
expect(scrollable.getBoundingClientRect().width).to.be.equal(90);

var wrapper = document.getElementById('wrapper');

expect(wrapper.getBoundingClientRect().width).to.be.equal(90);
expect(wrapper.childNodes[1].getBoundingClientRect().left).to.be.equal(0);
expect(wrapper.childNodes[1].getBoundingClientRect().top).to.be.equal(60);
expect(wrapper.childNodes[1].getBoundingClientRect().height).to.be.equal(60);
});

it('should find out parent node', function () {
var wrapper = document.getElementById('wrapper');
var firstChild = wrapper.childNodes[0];

expect(MoveIntoView(firstChild).wrapper).to.be.equal(wrapper);
expect(MoveIntoView(firstChild).parent).to.be.equal(vParent);
});

it('should handle negative y aspect ratios', function () {
var wrapper = document.getElementById('wrapper');
var view = MoveIntoView(wrapper.childNodes[0]);

expect(view.position(0, 0.5).y).to.be.equal(0);
expect(view.position(0, 0).y).to.be.equal(0);
expect(view.position(0, 1).y).to.be.equal(0);
});

it('should handle y aspect ratios', function () {
var wrapper = document.getElementById('wrapper');
var view = MoveIntoView(wrapper.childNodes[1]);

expect(view.position(0, 0).y).to.be.equal(60);
expect(view.position(0, 0.5).y).to.be.equal(30);
expect(view.position(0, 1).y).to.be.equal(0);
});

it('should handle over width x aspect ratios', function () {
var wrapper = document.getElementById('wrapper');
var view = MoveIntoView(wrapper.childNodes[8]);

expect(view.position(0, 0).y).to.be.equal(480);
expect(view.position(0, 0.5).y).to.be.equal(450);
expect(view.position(0, 1).y).to.be.equal(420);

view = MoveIntoView(wrapper.childNodes[9]);
expect(view.position(0, 0).y).to.be.equal(480);
expect(view.position(0, 0.5).y).to.be.equal(480);
expect(view.position(0, 1).y).to.be.equal(480);
});
});

77 changes: 77 additions & 0 deletions tests/moving-position.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
var MoveIntoView = require('../');
var expect = require('chai').expect;
var resetCSS = require('./css/reset');

var CSSTate = require('csstate');
var cst = new CSSTate();

function vMock () {
var vParent = document.createElement('div');
vParent.classList.add('scrollable');
vParent.setAttribute('id', 'scrollable');
var vChild = document.createElement('div');
vChild.classList.add('wrapper');
vChild.setAttribute('id', 'wrapper');
vParent.appendChild(vChild);

for (var i = 0; i < 10; i++) {
var el = document.createElement('div');
el.classList.add('child');
vChild.appendChild(el);
}

return vParent;
}

var vMockCSS = {
'.scrollable': {
'position': 'relative',
'width': '90px',
'height': '120px',
'overflow': 'hidden'
},

'.wrapper': {
'position': 'absolute'
},

'.child': {
'display': 'block',
'width': '90px',
'height': '60px'
}
};

describe('Test element setup', function () {
var vParent = null;

beforeEach(function () {
cst.rule(resetCSS);
cst.rule(vMockCSS);
});

afterEach(function () {
cst.exit();
});

before(function () {
vParent = vMock();
document.body.appendChild(vParent);
});

after(function () {
document.body.removeChild(vParent);
});

it('should move child', function () {
var wrapper = document.getElementById('wrapper');
var child = wrapper.childNodes[1];
MoveIntoView(child).move.y(0.5);
expect(wrapper.style.top).to.be.equal('-30px');
MoveIntoView(child).move.y(1);
expect(wrapper.style.top).to.be.equal('0px');
MoveIntoView(child).move.y(0);
expect(wrapper.style.top).to.be.equal('-60px');
});
});

41 changes: 36 additions & 5 deletions tests/element-setup.test.js → tests/vertical-positioning.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ var vMockCSS = {

'.child': {
'display': 'inline-block',
'width': '90px',
'height': '86px',
'margin': '0px 2px'
'width': '60px',
'height': '86px'
}
};

Expand Down Expand Up @@ -75,8 +74,8 @@ describe('Test element setup', function () {

var wrapper = document.getElementById('wrapper');

expect(wrapper.getBoundingClientRect().width).to.be.equal(940);
expect(wrapper.childNodes[1].getBoundingClientRect().left).to.be.equal(96);
expect(wrapper.getBoundingClientRect().width).to.be.equal(600);
expect(wrapper.childNodes[1].getBoundingClientRect().left).to.be.equal(60);
});

it('should find out parent node', function () {
Expand All @@ -86,5 +85,37 @@ describe('Test element setup', function () {
expect(MoveIntoView(firstChild).wrapper).to.be.equal(wrapper);
expect(MoveIntoView(firstChild).parent).to.be.equal(vParent);
});

it('should handle negative x aspect ratios', function () {
var wrapper = document.getElementById('wrapper');
var view = MoveIntoView(wrapper.childNodes[0]);

expect(view.position(0.5).x).to.be.equal(0);
expect(view.position(0).x).to.be.equal(0);
expect(view.position(1).x).to.be.equal(0);
});

it('should handle x aspect ratios', function () {
var wrapper = document.getElementById('wrapper');
var view = MoveIntoView(wrapper.childNodes[1]);

expect(view.position(0).x).to.be.equal(60);
expect(view.position(0.5).x).to.be.equal(30);
expect(view.position(1).x).to.be.equal(0);
});

it('should handle over width x aspect ratios', function () {
var wrapper = document.getElementById('wrapper');
var view = MoveIntoView(wrapper.childNodes[8]);

expect(view.position(0).x).to.be.equal(480);
expect(view.position(0.5).x).to.be.equal(450);
expect(view.position(1).x).to.be.equal(420);

view = MoveIntoView(wrapper.childNodes[9]);
expect(view.position(0).x).to.be.equal(480);
expect(view.position(0.5).x).to.be.equal(480);
expect(view.position(1).x).to.be.equal(480);
});
});