Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

angular-in-viewport

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-in-viewport - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

examples/window-viewport.html

5

bower.json
{
"name": "angular-in-viewport",
"version": "1.0.1",
"version": "1.1.0",
"homepage": "https://github.com/showpad/angular-in-viewport",
"authors": [
"Klaas Cuvelier <cuvelierklaas@gmail.com>"
],
"description": "Directives to check if a DOM element is in a specified viewport",

@@ -9,0 +6,0 @@ "main": "dist/in-viewport.js",

3

CHANGELOG.md
# Changelog
## 1.1.0
* Allow to specify `window` as the viewport (thx @compwright)
## 1.0.1

@@ -4,0 +7,0 @@ * Fix package.json main file

@@ -11,2 +11,6 @@ (function (angular) {

angular
.module('in-viewport')
.directive('viewportEnter', viewportEnterDefinition);
/**

@@ -42,6 +46,2 @@ * Directive definition for viewport-enter

angular
.module('in-viewport')
.directive('viewportEnter', viewportEnterDefinition);
})(window.angular);

@@ -51,2 +51,6 @@ (function (angular) {

angular
.module('in-viewport')
.directive('viewportLeave', viewportLeaveDefinition);
/**

@@ -82,6 +86,2 @@ * Directive definition for viewport-enter

angular
.module('in-viewport')
.directive('viewportLeave', viewportLeaveDefinition);
})(window.angular);

@@ -91,2 +91,5 @@ (function (angular) {

angular
.module('in-viewport')
.directive('viewport', ViewportDefinition);

@@ -96,3 +99,3 @@ /**

*/
function ViewportDefinition()
function ViewportDefinition($window)
{

@@ -103,6 +106,8 @@ return {

controller: ViewportController,
link: ViewportLinking
link: viewportLinking($window)
};
}
ViewportDefinition.$inject = ['$window'];
/**

@@ -114,3 +119,3 @@ * Controller for viewport directive

{
var viewport = null,
var viewportFn = null,
isUpdating = false,

@@ -128,3 +133,3 @@ updateAgain = false,

if (!viewport) {
if (!viewportFn) {
return;

@@ -140,3 +145,3 @@ }

viewportRect = viewport.getBoundingClientRect();
viewportRect = viewportFn();

@@ -148,5 +153,5 @@ angular.forEach(items, function (item) {

pointIsInsideBounds(elementRect.left, elementRect.top, viewportRect) ||
pointIsInsideBounds(elementRect.left + elementRect.width, elementRect.top, viewportRect) ||
pointIsInsideBounds(elementRect.left, elementRect.top + elementRect.height, viewportRect) ||
pointIsInsideBounds(elementRect.left + elementRect.width, elementRect.top + elementRect.height, viewportRect);
pointIsInsideBounds(elementRect.right, elementRect.top, viewportRect) ||
pointIsInsideBounds(elementRect.left, elementRect.bottom, viewportRect) ||
pointIsInsideBounds(elementRect.right, elementRect.bottom, viewportRect);

@@ -182,18 +187,24 @@ // On first check and on change

{
return x >= bounds.left &&
y >= bounds.top &&
x <= bounds.left + bounds.width &&
y <= bounds.top + bounds.height;
return x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom;
}
/**
* Set the viewport element
* @param element
* Set the viewport box function
* @param function
*/
function setViewport (element)
function setViewportFn(fn)
{
viewport = element;
viewportFn = fn;
}
/**
* Return the current viewport box function
* @returns {*}
*/
function getViewportFn()
{
return viewportFn;
}
/**
* trigger an update

@@ -240,2 +251,11 @@ */

/**
* Get list of items
* @returns {Array}
*/
function getItems()
{
return items;
}
angular.element($window)

@@ -245,5 +265,7 @@ .on('resize', updateDelayed)

this.setViewport = setViewport;
this.add = add;
this.updateDelayed = updateDelayed;
this.setViewportFn = setViewportFn;
this.getViewportFn = getViewportFn;
this.add = add;
this.getItems = getItems;
this.updateDelayed = updateDelayed;
}

@@ -263,20 +285,35 @@

*/
function ViewportLinking($scope, iElement, iAttrs, viewport)
function viewportLinking($window)
{
viewport.setViewport(iElement[0]);
iElement.on('scroll', viewport.updateDelayed);
var linkFn = function($scope, iElement, iAttrs, $ctrl) {
if (iAttrs.viewport === 'window') {
$ctrl.setViewportFn(function() {
return {
top: 0,
left: 0,
bottom: window.innerHeight || document.documentElement.clientHeight,
right: window.innerWidth || document.documentElement.clientWidth
};
});
angular.element($window).on('scroll', $ctrl.updateDelayed);
} else {
$ctrl.setViewportFn(function() {
return iElement[0].getBoundingClientRect();
});
iElement.on('scroll', $ctrl.updateDelayed);
}
// Trick angular in calling this on digest
$scope.$watch(function () {
viewport.updateDelayed();
});
}
// Trick angular in calling this on digest
$scope.$watch(function () {
$ctrl.updateDelayed();
});
};
ViewportLinking.$inject = ['$scope', 'iElement', 'iAttrs', 'viewport'];
linkFn.$inject = ['$scope', 'iElement', 'iAttrs', 'viewport'];
angular
.module('in-viewport')
.directive('viewport', ViewportDefinition);
return linkFn;
}
viewportLinking.$inject = ['$window'];
})(window.angular);
!function(i){"use strict";i.module("in-viewport",[])}(window.angular);
!function(e){"use strict";function n(){return{require:"^viewport",restrict:"A",link:t}}function t(e,n,t,i){8!==n[0].nodeType&&t.viewportEnter&&i.add("enter",n[0],function(){e.$apply(function(){e.$eval(t.viewportEnter)})})}e.module("in-viewport").directive("viewportEnter",n)}(window.angular);
!function(e){"use strict";function i(){return{require:"^viewport",restrict:"A",link:n}}function n(e,i,n,t){8!==i[0].nodeType&&n.viewportLeave&&t.add("leave",i[0],function(){e.$apply(function(){e.$eval(n.viewportLeave)})})}e.module("in-viewport").directive("viewportLeave",i)}(window.angular);
!function(e){"use strict";function t(){return{restrict:"A",scope:!0,controller:n,link:i}}function n(t){function n(){var t,o,l;if(c){if(f)return void(a=!0);f=!0,t=c.getBoundingClientRect(),e.forEach(p,function(e){o=e.element.getBoundingClientRect(),l=i(o.left,o.top,t)||i(o.left+o.width,o.top,t)||i(o.left,o.top+o.height,t)||i(o.left+o.width,o.top+o.height,t),(null===e.state||e.state!==l)&&(l&&"function"==typeof e.enter?e.enter():l||"function"!=typeof e.leave||e.leave()),e.state=l}),f=!1,a&&(a=!1,n())}}function i(e,t,n){return e>=n.left&&t>=n.top&&e<=n.left+n.width&&t<=n.top+n.height}function o(e){c=e}function l(){window.clearTimeout(r),r=window.setTimeout(function(){n()},100)}function u(e,t,n){var i;if(-1===["leave","enter"].indexOf(e))throw"invalid event specified";i=d.indexOf(t),-1===i&&(d.push(t),p.push({element:t,state:null,leave:null,enter:null}),i=d.length-1),p[i][e]=n}var r,c=null,f=!1,a=!1,d=[],p=[];e.element(t).on("resize",l).on("orientationchange",l),this.setViewport=o,this.add=u,this.updateDelayed=l}function i(e,t,n,i){i.setViewport(t[0]),t.on("scroll",i.updateDelayed),e.$watch(function(){i.updateDelayed()})}n.$inject=["$window"],i.$inject=["$scope","iElement","iAttrs","viewport"],e.module("in-viewport").directive("viewport",t)}(window.angular);
!function(t){"use strict";function e(t){return{restrict:"A",scope:!0,controller:n,link:i(t)}}function n(e){function n(){var e,o,r;if(f){if(a)return void(w=!0);a=!0,e=f(),t.forEach(p,function(t){o=t.element.getBoundingClientRect(),r=i(o.left,o.top,e)||i(o.right,o.top,e)||i(o.left,o.bottom,e)||i(o.right,o.bottom,e),(null===t.state||t.state!==r)&&(r&&"function"==typeof t.enter?t.enter():r||"function"!=typeof t.leave||t.leave()),t.state=r}),a=!1,w&&(w=!1,n())}}function i(t,e,n){return t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}function o(t){f=t}function r(){return f}function u(){window.clearTimeout(d),d=window.setTimeout(function(){n()},100)}function l(t,e,n){var i;if(-1===["leave","enter"].indexOf(t))throw"invalid event specified";i=s.indexOf(e),-1===i&&(s.push(e),p.push({element:e,state:null,leave:null,enter:null}),i=s.length-1),p[i][t]=n}function c(){return p}var d,f=null,a=!1,w=!1,s=[],p=[];t.element(e).on("resize",u).on("orientationchange",u),this.setViewportFn=o,this.getViewportFn=r,this.add=l,this.getItems=c,this.updateDelayed=u}function i(e){var n=function(n,i,o,r){"window"===o.viewport?(r.setViewportFn(function(){return{top:0,left:0,bottom:window.innerHeight||document.documentElement.clientHeight,right:window.innerWidth||document.documentElement.clientWidth}}),t.element(e).on("scroll",r.updateDelayed)):(r.setViewportFn(function(){return i[0].getBoundingClientRect()}),i.on("scroll",r.updateDelayed)),n.$watch(function(){r.updateDelayed()})};return n.$inject=["$scope","iElement","iAttrs","viewport"],n}t.module("in-viewport").directive("viewport",e),e.$inject=["$window"],n.$inject=["$window"],i.$inject=["$window"]}(window.angular);
{
"name": "angular-in-viewport",
"version": "1.0.1",
"version": "1.1.0",
"description": "Directives to check if a DOM element is in a specified viewport",

@@ -5,0 +5,0 @@ "main": "dist/in-viewport.js",

@@ -13,4 +13,6 @@ [![GitHub version](https://badge.fury.io/gh/showpad%2Fangular-in-viewport.svg)](http://badge.fury.io/gh/showpad%2Fangular-in-viewport)

### viewport
Directive (attribute) specifying the DOM element which should be used as viewport
Directive (attribute) specifying the DOM element which should be used as viewport.
To use `window` as the viewport element, set `viewport="window"` on any parent element.
### viewport-enter

@@ -23,5 +25,8 @@ Directive (attribute) specifying a DOM element which should be watched. When the element enters the viewport the value of the attribute will be evaled.

#Compatibility
This plugin has been tested with Angular 1.2 and 1.3
This plugin works with Angular 1.x (v1.2 and higher)
#Example
Viewport container element:
```HTML

@@ -33,3 +38,11 @@ <ul style="width: 200px; height: 200px" viewport>

Window viewport:
```HTML
<ul style="width: 200px; height: 200px" viewport="window">
<li ng-repeat="item in items" style="width: 200px; height: 200px" viewport-leave="item.visible = false" viewport-enter="item.visible = true">
</ul>
```
# License
This Angular module has been published under the [MIT license](LICENSE)

@@ -11,3 +11,3 @@ (function (angular) {

*/
function ViewportDefinition()
function ViewportDefinition($window)
{

@@ -18,6 +18,8 @@ return {

controller: ViewportController,
link: ViewportLinking
link: viewportLinking($window)
};
}
ViewportDefinition.$inject = ['$window'];
/**

@@ -29,3 +31,3 @@ * Controller for viewport directive

{
var viewport = null,
var viewportFn = null,
isUpdating = false,

@@ -43,3 +45,3 @@ updateAgain = false,

if (!viewport) {
if (!viewportFn) {
return;

@@ -55,3 +57,3 @@ }

viewportRect = viewport.getBoundingClientRect();
viewportRect = viewportFn();

@@ -63,5 +65,5 @@ angular.forEach(items, function (item) {

pointIsInsideBounds(elementRect.left, elementRect.top, viewportRect) ||
pointIsInsideBounds(elementRect.left + elementRect.width, elementRect.top, viewportRect) ||
pointIsInsideBounds(elementRect.left, elementRect.top + elementRect.height, viewportRect) ||
pointIsInsideBounds(elementRect.left + elementRect.width, elementRect.top + elementRect.height, viewportRect);
pointIsInsideBounds(elementRect.right, elementRect.top, viewportRect) ||
pointIsInsideBounds(elementRect.left, elementRect.bottom, viewportRect) ||
pointIsInsideBounds(elementRect.right, elementRect.bottom, viewportRect);

@@ -97,24 +99,21 @@ // On first check and on change

{
return x >= bounds.left &&
y >= bounds.top &&
x <= bounds.left + bounds.width &&
y <= bounds.top + bounds.height;
return x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom;
}
/**
* Set the viewport element
* @param element
* Set the viewport box function
* @param function
*/
function setViewport(element)
function setViewportFn(fn)
{
viewport = element;
viewportFn = fn;
}
/**
* Return the current viewport
* Return the current viewport box function
* @returns {*}
*/
function getViewport()
function getViewportFn()
{
return viewport;
return viewportFn;
}

@@ -177,4 +176,4 @@

this.setViewport = setViewport;
this.getViewport = getViewport;
this.setViewportFn = setViewportFn;
this.getViewportFn = getViewportFn;
this.add = add;

@@ -197,15 +196,35 @@ this.getItems = getItems;

*/
function ViewportLinking($scope, iElement, iAttrs, viewport)
function viewportLinking($window)
{
viewport.setViewport(iElement[0]);
iElement.on('scroll', viewport.updateDelayed);
var linkFn = function($scope, iElement, iAttrs, $ctrl) {
if (iAttrs.viewport === 'window') {
$ctrl.setViewportFn(function() {
return {
top: 0,
left: 0,
bottom: window.innerHeight || document.documentElement.clientHeight,
right: window.innerWidth || document.documentElement.clientWidth
};
});
angular.element($window).on('scroll', $ctrl.updateDelayed);
} else {
$ctrl.setViewportFn(function() {
return iElement[0].getBoundingClientRect();
});
iElement.on('scroll', $ctrl.updateDelayed);
}
// Trick angular in calling this on digest
$scope.$watch(function () {
viewport.updateDelayed();
});
// Trick angular in calling this on digest
$scope.$watch(function () {
$ctrl.updateDelayed();
});
};
linkFn.$inject = ['$scope', 'iElement', 'iAttrs', 'viewport'];
return linkFn;
}
ViewportLinking.$inject = ['$scope', 'iElement', 'iAttrs', 'viewport'];
viewportLinking.$inject = ['$window'];
})(window.angular);

@@ -28,3 +28,3 @@ 'use strict';

this.updateDelayed = function () {};
this.setViewport = function () {};
this.setViewportFn = function () {};

@@ -31,0 +31,0 @@ viewportMockController = this;

@@ -28,3 +28,3 @@ 'use strict';

this.updateDelayed = function () {};
this.setViewport = function () {};
this.setViewportFn = function () {};

@@ -31,0 +31,0 @@ viewportMockController = this;

@@ -38,7 +38,7 @@ 'use strict';

describe('setViewport/getViewport', function () {
it('should set/get the current viewport element', function () {
describe('setViewportFn/getViewportFn', function () {
it('should set/get the current viewport box function', function () {
var viewport = {};
controller.setViewport(viewport);
expect(controller.getViewport()).toEqual(viewport);
controller.setViewportFn(viewport);
expect(controller.getViewportFn()).toEqual(viewport);
});

@@ -138,3 +138,3 @@ });

element[0].scrollTop = 550;
element[0].dispatchEvent(createEvent('scroll'));;
element[0].dispatchEvent(createEvent('scroll'));

@@ -141,0 +141,0 @@ element[0].scrollTop = 0;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc