diff --git a/dist/angular-vs-repeat.js b/dist/angular-vs-repeat.js index 5ecc840..f952f35 100644 --- a/dist/angular-vs-repeat.js +++ b/dist/angular-vs-repeat.js @@ -153,12 +153,12 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i throw new Error('angular-vs-repeat: no ng-repeat directive on a child element'); } - function printDeprecationWarning(message) { - console.warn("vs-repeat deprecation: ".concat(message)); + function printDeprecationWarning($element, message) { + console.warn("vs-repeat deprecation: ".concat(message), $element[0]); } - function attrDeprecated(attrname) { - printDeprecationWarning("".concat(attrname, " attribute is deprecated. Pass the options object to vs-repeat attribute instead .")); + function attrDeprecated(attrname, $element) { + printDeprecationWarning($element, "".concat(attrname, " attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options")); } var defaultOptions = { @@ -191,7 +191,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i ['vsSize', 'vsScrollParent', 'vsSizeProperty', 'vsHorizontal', 'vsOffsetBefore', 'vsOffsetAfter', 'vsScrolledToEndOffset', 'vsScrolledToBeginningOffset', 'vsExcess', 'vsScrollMargin'].forEach(function (attrname) { if (attrname in compileAttrs) { - attrDeprecated(attrname); + attrDeprecated(attrname, compileElement); } }); @@ -381,7 +381,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i autosizingRequired = false; if ($scope.$root && !$scope.$root.$$phase) { - $scope.$apply(); + $scope.$digest(); } } } else { @@ -416,11 +416,6 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i function scrollHandler() { if (updateInnerCollection()) { $scope.$digest(); - var expectedSize = $scope.vsRepeat.sizesCumulative[originalLength]; - - if (expectedSize !== repeatContainer[0][scrollSize]) { - console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + repeatContainer[0][scrollSize] + 'px. Fix vsSize on element:', $element[0]); - } } } @@ -432,7 +427,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i getFromMeasured(); if ($scope.$root && !$scope.$root.$$phase) { - $scope.$apply(); + $scope.$digest(); } } @@ -455,24 +450,30 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i var _prevStartIndex, _prevEndIndex, _minStartIndex, _maxEndIndex; $scope.$on('vsRenderAll', function () { - //e , quantum) { - if (options.latch) { - setTimeout(function () { - // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength); - var __endIndex = originalLength; - _maxEndIndex = Math.max(__endIndex, _maxEndIndex); - $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; - $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); - _prevEndIndex = $scope.vsRepeat.endIndex; - $scope.$$postDigest(function () { - $beforeContent.css(getLayoutProp(), 0); - $afterContent.css(getLayoutProp(), 0); - }); - $scope.$apply(function () { - $scope.$emit('vsRenderAllDone'); - }); - }); + if (!options.latch) { + return; + } + + if ($scope.vsRepeat.endIndex === originalLength) { + $scope.$emit('vsRenderAllDone'); + return; } + + setTimeout(function () { + // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength); + var __endIndex = originalLength; + _maxEndIndex = Math.max(__endIndex, _maxEndIndex); + $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; + $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); + _prevEndIndex = $scope.vsRepeat.endIndex; + $beforeContent.css(getLayoutProp(), 0); + $afterContent.css(getLayoutProp(), 0); + $scope.$emit('vsRenderAllDone'); + + if ($scope.$root && !$scope.$root.$$phase) { + $scope.$digest(); + } + }); }); function reinitialize() { @@ -498,7 +499,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i reinitialize(); if ($scope.$root && !$scope.$root.$$phase) { - $scope.$apply(); + $scope.$digest(); } } @@ -555,6 +556,8 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i __startIndex = 0; __endIndex = 1; } else { + _warnMismatch(); + var relativeScroll = $scrollPosition - options.offsetBefore - scrollOffset; var _binaryFind = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll - options.scrollMargin); @@ -631,6 +634,23 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i return digestRequired; } + + function _warnMismatch() { + $scope.$$postDigest(function () { + window.requestAnimationFrame(function () { + var expectedSize = $scope.vsRepeat.sizesCumulative[originalLength]; + var compStyle = window.getComputedStyle(repeatContainer[0]); + var paddings = options.horizontal ? ['paddingLeft', 'paddingRight'] : ['paddingTop', 'paddingBottom']; + var containerSize = repeatContainer[0][scrollSize] - paddings.reduce(function (acc, prop) { + return acc + Number(compStyle[prop].slice(0, -2)); + }, 0); + + if (repeatContainer[0][scrollSize] && expectedSize !== containerSize) { + console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + containerSize + 'px. Fix vsSize on element:', $element[0]); + } + }); + }); + } } }; } diff --git a/dist/angular-vs-repeat.min.js b/dist/angular-vs-repeat.min.js index c7c6536..b003a97 100644 --- a/dist/angular-vs-repeat.min.js +++ b/dist/angular-vs-repeat.min.js @@ -1 +1 @@ -function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t."),console.warn("vs-repeat deprecation: ".concat(t))}var Q={latch:!1,container:null,scrollParent:null,size:null,offsetBefore:0,offsetAfter:0,scrolledToBeginning:U.noop,scrolledToEnd:U.noop,scrolledToBeginningOffset:0,scrolledToEndOffset:0,scrollMargin:0,horizontal:!1,autoresize:!1,hunked:!1,hunkSize:0},e=U.module("vs-repeat",[]).directive("vsRepeat",["$compile","$parse",function(F,J){return{restrict:"A",scope:!0,compile:function(e,t){var n="vsRepeatContainer"in t?U.element(e[0].querySelector(t.vsRepeatContainer)):e,r=n.children(),a=r.eq(0),H=a[0].outerHTML,L="$vs_collection";["vsSize","vsScrollParent","vsSizeProperty","vsHorizontal","vsOffsetBefore","vsOffsetAfter","vsScrolledToEndOffset","vsScrolledToBeginningOffset","vsExcess","vsScrollMargin"].forEach(function(e){e in t&&d(e)});var o=_slicedToArray(function(e){for(var t=["ng-repeat","data-ng-repeat","ng-repeat-start","data-ng-repeat-start"],n=0;n"),$=U.element("<"+o+' class="vs-repeat-after-content">"),b=null===g.size,I=g.scrollParent?"window"===g.scrollParent?U.element(Y):X.call(x,g.scrollParent):x,w=g.horizontal?"clientWidth":"clientHeight",s=g.horizontal?"offsetWidth":"offsetHeight",i=g.horizontal?"scrollWidth":"scrollHeight",S=g.horizontal?"scrollLeft":"scrollTop";if((m.vsRepeat.totalSize=0)===I.length)throw"Specified scroll parent selector did not match any element";if(m.vsRepeat.$scrollParent=I,m.vsRepeat.sizesCumulative=[],g.debug){var l="window"===g.scrollParent?U.element(document.body):I,c=U.element('
');c.css("position","window"===g.scrollParent?"fixed":"absolute"),l.append(c),m.$on("$destroy",function(){c.remove()})}var T,C,O,A,d,u=K(I[0],w)||50;function p(){!y||y.length<1?(m[L]=[],R=0,m.vsRepeat.sizesCumulative=[0]):(R=y.length,g.size?v():f()),E()}function v(){var n=0t?P(e,t,n,o,a+1):P(e,t,o,r,a+1)}return[t>e[r]?r:n,t=g.hunkSize||0===m.vsRepeat.startIndex&&0!==T?u=!0:(Math.abs(m.vsRepeat.endIndex-C)>=g.hunkSize||m.vsRepeat.endIndex===R&&C!==R)&&(u=!0):u=m.vsRepeat.startIndex!==T||m.vsRepeat.endIndex!==C),u){var p;m[L]=y.slice(m.vsRepeat.startIndex,m.vsRepeat.endIndex),m.$emit("vsRepeatInnerCollectionUpdated",m.vsRepeat.startIndex,m.vsRepeat.endIndex,T,C),g.scrolledToEnd&&(p=y.length-g.scrolledToEndOffset,(m.vsRepeat.endIndex>=p&&Cm.vsRepeat.startIndex&&m.$eval(g.scrolledToBeginning)),T=m.vsRepeat.startIndex,C=m.vsRepeat.endIndex;var v=m.vsRepeat.sizesCumulative[m.vsRepeat.startIndex]+g.offsetBefore,f=m.vsRepeat.sizesCumulative[m.vsRepeat.startIndex+m[L].length]+g.offsetBefore,h=m.vsRepeat.totalSize;z.css(M(),v+"px"),$.css(M(),h-f+"px")}return u}g.horizontal?(z.css("height","100%"),$.css("height","100%")):(z.css("width","100%"),$.css("width","100%")),e.vsRepeatOptions&&m.$watchCollection(e.vsRepeatOptions,function(e){var t=_extends({},g,e);JSON.stringify(t)!==JSON.stringify(g)&&(Object.assign(g,e),r(g),E())}),m.$watchCollection(N,function(){var e=0\n\t \t.vs-repeat-debug-element {\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n background: red;\n z-index: 99999999;\n box-shadow: 0 0 20px red;\n }\n\n .vs-repeat-debug-element + .vs-repeat-debug-element {\n display: none;\n }\n '),"undefined"!=typeof module&&module.exports&&(module.exports=e.name)}(window,window.angular); \ No newline at end of file +function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t"),b=U.element("<"+o+' class="vs-repeat-after-content">"),I=null===R.size,w=R.scrollParent?"window"===R.scrollParent?U.element(Y):X.call(z,R.scrollParent):z,S=R.horizontal?"clientWidth":"clientHeight",a=R.horizontal?"offsetWidth":"offsetHeight",T=R.horizontal?"scrollWidth":"scrollHeight",A=R.horizontal?"scrollLeft":"scrollTop";if((g.vsRepeat.totalSize=0)===w.length)throw"Specified scroll parent selector did not match any element";if(g.vsRepeat.$scrollParent=w,g.vsRepeat.sizesCumulative=[],R.debug){var s="window"===R.scrollParent?U.element(document.body):w,i=U.element('
');i.css("position","window"===R.scrollParent?"fixed":"absolute"),s.append(i),g.$on("$destroy",function(){i.remove()})}var C,O,M,_,l,d=K(w[0],S)||50;function c(){!$||$.length<1?(g[q]=[],x=0,g.vsRepeat.sizesCumulative=[0]):(x=$.length,R.size?u():p()),h()}function u(){var n=0t?P(e,t,n,a,o+1):P(e,t,a,r,o+1)}return[t>e[r]?r:n,t=R.hunkSize||0===g.vsRepeat.startIndex&&0!==C?u=!0:(Math.abs(g.vsRepeat.endIndex-O)>=R.hunkSize||g.vsRepeat.endIndex===x&&O!==x)&&(u=!0):u=g.vsRepeat.startIndex!==C||g.vsRepeat.endIndex!==O),u){var p;g[q]=$.slice(g.vsRepeat.startIndex,g.vsRepeat.endIndex),g.$emit("vsRepeatInnerCollectionUpdated",g.vsRepeat.startIndex,g.vsRepeat.endIndex,C,O),R.scrolledToEnd&&(p=$.length-R.scrolledToEndOffset,(g.vsRepeat.endIndex>=p&&Og.vsRepeat.startIndex&&g.$eval(R.scrolledToBeginning)),C=g.vsRepeat.startIndex,O=g.vsRepeat.endIndex;var v=g.vsRepeat.sizesCumulative[g.vsRepeat.startIndex]+R.offsetBefore,f=g.vsRepeat.sizesCumulative[g.vsRepeat.startIndex+g[q].length]+R.offsetBefore,h=g.vsRepeat.totalSize;y.css(B(),v+"px"),b.css(B(),h-f+"px")}return u}R.horizontal?(y.css("height","100%"),b.css("height","100%")):(y.css("width","100%"),b.css("width","100%")),e.vsRepeatOptions&&g.$watchCollection(e.vsRepeatOptions,function(e){var t=_extends({},R,e);JSON.stringify(t)!==JSON.stringify(R)&&(Object.assign(R,e),n(R),h())}),g.$watchCollection(N,function(){var e=0\n\t \t.vs-repeat-debug-element {\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n background: red;\n z-index: 99999999;\n box-shadow: 0 0 20px red;\n }\n\n .vs-repeat-debug-element + .vs-repeat-debug-element {\n display: none;\n }\n '),"undefined"!=typeof module&&module.exports&&(module.exports=e.name)}(window,window.angular); \ No newline at end of file diff --git a/gulpfile.babel.js b/gulpfile.babel.js index fd37070..a77a33d 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -5,12 +5,7 @@ import rename from 'gulp-rename'; import clean from 'gulp-clean'; import { Server } from 'karma'; -gulp.task('clean', () => - gulp.src('dist', { read: false }) - .pipe(clean()) -); - -gulp.task('babel', ['clean'], () => +gulp.task('babel', () => gulp.src('src/angular-vs-repeat.js') .pipe(babel()) .pipe(gulp.dest('dist')) @@ -40,6 +35,6 @@ gulp.task('karma-travis', ['build'], (done) => { }, done).start(); }); -gulp.task('build', ['clean', 'babel', 'min']); +gulp.task('build', ['babel', 'min']); gulp.task('test', ['build', 'karma']); gulp.task('travis', ['build', 'karma-travis']); diff --git a/src/angular-vs-repeat.js b/src/angular-vs-repeat.js index d8e0f0c..e4bfda1 100644 --- a/src/angular-vs-repeat.js +++ b/src/angular-vs-repeat.js @@ -377,7 +377,7 @@ reinitialize(); autosizingRequired = false; if ($scope.$root && !$scope.$root.$$phase) { - $scope.$apply(); + $scope.$digest(); } } } else { @@ -424,7 +424,7 @@ autosizingRequired = true; getFromMeasured(); if ($scope.$root && !$scope.$root.$$phase) { - $scope.$apply(); + $scope.$digest(); } } @@ -451,28 +451,34 @@ _minStartIndex, _maxEndIndex; - $scope.$on('vsRenderAll', function() {//e , quantum) { - if (options.latch) { - setTimeout(() => { - // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength); - const __endIndex = originalLength; - _maxEndIndex = Math.max(__endIndex, _maxEndIndex); + $scope.$on('vsRenderAll', function() { + if (!options.latch) { + return; + } - $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; - $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); + if ($scope.vsRepeat.endIndex === originalLength) { + $scope.$emit('vsRenderAllDone'); + return; + } - _prevEndIndex = $scope.vsRepeat.endIndex; + setTimeout(() => { + // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength); + const __endIndex = originalLength; + _maxEndIndex = Math.max(__endIndex, _maxEndIndex); - $scope.$$postDigest(() => { - $beforeContent.css(getLayoutProp(), 0); - $afterContent.css(getLayoutProp(), 0); - }); + $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; + $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); - $scope.$apply(() => { - $scope.$emit('vsRenderAllDone'); - }); - }); - } + _prevEndIndex = $scope.vsRepeat.endIndex; + + $beforeContent.css(getLayoutProp(), 0); + $afterContent.css(getLayoutProp(), 0); + + $scope.$emit('vsRenderAllDone'); + if ($scope.$root && !$scope.$root.$$phase) { + $scope.$digest(); + } + }); }); function reinitialize() { @@ -496,7 +502,7 @@ if (ch !== _prevClientSize) { reinitialize(); if ($scope.$root && !$scope.$root.$$phase) { - $scope.$apply(); + $scope.$digest(); } } _prevClientSize = ch; diff --git a/test/spec.js b/test/spec.js index 63b36bf..3a08bd7 100644 --- a/test/spec.js +++ b/test/spec.js @@ -185,7 +185,7 @@ it('should support manually provided unique element size', function(done){ $element = $compile([ '
', - '
', + '
', ' {{foo.value}}', '
', '
', @@ -196,8 +196,7 @@ setTimeout(() => { var elems = getElements($element); - expect(elems.length).to.be.greaterThan(1); - expect(elems.length).to.be.lessThan(5); + expect(elems.length).to.equal(2); done(); }); }); @@ -535,7 +534,7 @@ done(); }); - it.only('should properly calculate start and end index with element beyond', function (done) { + it('should properly calculate start and end index with element beyond', function (done) { $element = angular.element(`