diff --git a/.gitignore b/.gitignore index f3215ee..24aac9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules -test/draft.js \ No newline at end of file +test/draft.js +/.idea/ diff --git a/dist/angular-vs-repeat.js b/dist/angular-vs-repeat.js index 3d9efb8..1d129dd 100644 --- a/dist/angular-vs-repeat.js +++ b/dist/angular-vs-repeat.js @@ -21,10 +21,10 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i * into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of * pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc. * The directive renders only so many elements that can fit into current container's clientHeight/clientWidth. - * LIMITATIONS: + * LIMITATIONS: * - current version only supports an Array as a right-hand-side object for ngRepeat * - all rendered elements must have the same height/width or the sizes of the elements must be known up front - * USAGE: + * USAGE: * In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat * example: *
@@ -32,7 +32,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i * *
* - * or: + * or: *
*
* @@ -44,7 +44,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i * *
*
- * You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value + * You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value * of the option's `size` property. This can be used if one wants to override the automatically computed element size. * example: *
@@ -52,13 +52,13 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i * *
* - * IMPORTANT! - * - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat + * IMPORTANT! + * - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat * - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive * will compute it automatically - * OPTIONAL PARAMETERS (attributes): + * OPTIONAL PARAMETERS (attributes): * vs-repeat-container="selector" - selector for element containing ng-repeat. (defaults to the current element) - * OPTIONS: + * OPTIONS: * Options shall be passed as an object to the `vs-repeat` attribute e.g.: `
` * * Available options: @@ -67,14 +67,14 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i * `offset-after` - bottom/right offset in pixels (defaults to 0) * `scroll-margin` - how many pixels ahead should elements be rendered while scrolling * `latch` - if true, elements will be rendered gradually but won't be removed when scrolled away (defaults to false) - * `size` - a property name of the items in collection that is a number denoting the element size (in pixels) + * `size` - a property name of the items in collection that is a number denoting the element size (in pixels) * `autoresize` - use this attribute without vs-size and without specifying element's size. The automatically computed element style will * readjust upon window resize if the size is dependable on the viewport size * `scrolled-to-end` - callback will be called when the last item of the list is rendered * `scrolled-to-end-offset` - set this number to trigger the scrolledToEnd callback n items before the last gets rendered * `scrolled-to-beginning` - callback will be called when the first item of the list is rendered * `scrolled-to-beginning-offset` - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered - * EVENTS: + * EVENTS: * - `vsRepeatTrigger` - an event the directive listens for to manually trigger reinitialization * - `vsRepeatReinitialized` - an event the directive emits upon reinitialization done */ @@ -161,6 +161,14 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i printDeprecationWarning($element, "".concat(attrname, " attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options")); } + function safeDigest(scope) { + var phase = scope.$root.$$phase; + + if (phase !== "$apply" && phase !== "$digest") { + scope.$digest(); + } + } + var defaultOptions = { latch: false, preserveLatchOnRefresh: false, @@ -381,8 +389,8 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i reinitialize(); autosizingRequired = false; - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } } } else { @@ -419,7 +427,7 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i var pos = $scrollParent[0][scrollPos]; if (updateInnerCollection()) { - $scope.$digest(); + safeDigest($scope); if (options._ensureScrollIntegrity) { $scrollParent[0][scrollPos] = pos; @@ -434,13 +442,13 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i autosizingRequired = true; getFromMeasured(); - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } } if (updateInnerCollection()) { - $scope.$digest(); + safeDigest($scope); } } @@ -478,8 +486,8 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i $afterContent.css(getLayoutProps(0)); $scope.$emit('vsRenderAllDone'); - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } }); }); @@ -510,8 +518,8 @@ function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else i if (ch !== _prevClientSize) { reinitialize(); - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } } diff --git a/dist/angular-vs-repeat.min.js b/dist/angular-vs-repeat.min.js index 0554921..ef59b78 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"),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",O=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 A,C,M,_,l,d=K(w[0],S)||50;function c(){!y||y.length<1?(g[q]=[],x=0,g.vsRepeat.sizesCumulative=[0]):(x=y.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!==A?u=!0:(Math.abs(g.vsRepeat.endIndex-C)>=R.hunkSize||g.vsRepeat.endIndex===x&&C!==x)&&(u=!0):u=g.vsRepeat.startIndex!==A||g.vsRepeat.endIndex!==C),u){var p;g[q]=y.slice(g.vsRepeat.startIndex,g.vsRepeat.endIndex),g.$emit("vsRepeatInnerCollectionUpdated",g.vsRepeat.startIndex,g.vsRepeat.endIndex,A,C),R.scrolledToEnd&&(p=y.length-R.scrolledToEndOffset,(g.vsRepeat.endIndex>=p&&Cg.vsRepeat.startIndex&&g.$eval(R.scrolledToBeginning)),A=g.vsRepeat.startIndex,C=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;$.css(B(v+"px")),b.css(B(h-f+"px"))}return u}R.horizontal?($.css("height","100%"),b.css("height","100%")):($.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\n .vs-repeat-before-content,\n .vs-repeat-after-content {\n border: none !important;\n padding: 0 !important;\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"),I=U.element("<"+o+' class="vs-repeat-after-content">"),$=null===R.size,w=R.scrollParent?"window"===R.scrollParent?U.element(Y):X.call(y,R.scrollParent):y,S=R.horizontal?"clientWidth":"clientHeight",a=R.horizontal?"offsetWidth":"offsetHeight",T=R.horizontal?"scrollWidth":"scrollHeight",O=R.horizontal?"scrollLeft":"scrollTop";if((m.vsRepeat.totalSize=0)===w.length)throw"Specified scroll parent selector did not match any element";if(m.vsRepeat.$scrollParent=w,m.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),m.$on("$destroy",function(){i.remove()})}var A,C,M,_,l,c=K(w[0],S)||50;function d(){!z||z.length<1?(m[q]=[],x=0,m.vsRepeat.sizesCumulative=[0]):(x=z.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===m.vsRepeat.startIndex&&0!==A?u=!0:(Math.abs(m.vsRepeat.endIndex-C)>=R.hunkSize||m.vsRepeat.endIndex===x&&C!==x)&&(u=!0):u=m.vsRepeat.startIndex!==A||m.vsRepeat.endIndex!==C),u){var p;m[q]=z.slice(m.vsRepeat.startIndex,m.vsRepeat.endIndex),m.$emit("vsRepeatInnerCollectionUpdated",m.vsRepeat.startIndex,m.vsRepeat.endIndex,A,C),R.scrolledToEnd&&(p=z.length-R.scrolledToEndOffset,(m.vsRepeat.endIndex>=p&&Cm.vsRepeat.startIndex&&m.$eval(R.scrolledToBeginning)),A=m.vsRepeat.startIndex,C=m.vsRepeat.endIndex;var v=m.vsRepeat.sizesCumulative[m.vsRepeat.startIndex]+R.offsetBefore,f=m.vsRepeat.sizesCumulative[m.vsRepeat.startIndex+m[q].length]+R.offsetBefore,h=m.vsRepeat.totalSize;b.css(B(v+"px")),I.css(B(h-f+"px"))}return u}R.horizontal?(b.css("height","100%"),I.css("height","100%")):(b.css("width","100%"),I.css("width","100%")),e.vsRepeatOptions&&m.$watchCollection(e.vsRepeatOptions,function(e){var t=_extends({},R,e);JSON.stringify(t)!==JSON.stringify(R)&&(Object.assign(R,e),n(R),h())}),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\n .vs-repeat-before-content,\n .vs-repeat-after-content {\n border: none !important;\n padding: 0 !important;\n }\n '),"undefined"!=typeof module&&module.exports&&(module.exports=e.name)}(window,window.angular); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 57e4ebb..a8ed288 100644 --- a/package-lock.json +++ b/package-lock.json @@ -909,6 +909,16 @@ } } }, + "JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -1625,9 +1635,9 @@ "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", "dev": true, "requires": { + "JSONStream": "1.3.2", "combine-source-map": "0.8.0", "defined": "1.0.0", - "JSONStream": "1.3.2", "safe-buffer": "5.1.1", "through2": "2.0.3", "umd": "3.0.2" @@ -1662,6 +1672,7 @@ "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", "dev": true, "requires": { + "JSONStream": "1.3.2", "assert": "1.4.1", "browser-pack": "6.0.4", "browser-resolve": "1.11.2", @@ -1683,7 +1694,6 @@ "https-browserify": "1.0.0", "inherits": "2.0.3", "insert-module-globals": "7.0.2", - "JSONStream": "1.3.2", "labeled-stream-splicer": "2.0.0", "module-deps": "4.1.1", "os-browserify": "0.3.0", @@ -4762,14 +4772,6 @@ } } }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, "string-width": { "version": "1.0.2", "bundled": true, @@ -4780,6 +4782,14 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "stringstream": { "version": "0.0.5", "bundled": true, @@ -5970,10 +5980,10 @@ "integrity": "sha512-p3s7g96Nm62MbHRuj9ZXab0DuJNWD7qcmdUXCOQ/ZZn42DtDXfsLill7bq19lDCx3K3StypqUnuE3H2VmIJFUw==", "dev": true, "requires": { + "JSONStream": "1.3.2", "combine-source-map": "0.7.2", "concat-stream": "1.5.2", "is-buffer": "1.1.6", - "JSONStream": "1.3.2", "lexical-scope": "1.2.0", "process": "0.11.10", "through2": "2.0.3", @@ -6468,16 +6478,6 @@ "dev": true, "optional": true }, - "JSONStream": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", - "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", - "dev": true, - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" - } - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -7408,6 +7408,7 @@ "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", "dev": true, "requires": { + "JSONStream": "1.3.2", "browser-resolve": "1.11.2", "cached-path-relative": "1.0.1", "concat-stream": "1.5.2", @@ -7415,7 +7416,6 @@ "detective": "4.7.1", "duplexer2": "0.1.4", "inherits": "2.0.3", - "JSONStream": "1.3.2", "parents": "1.0.1", "readable-stream": "2.3.5", "resolve": "1.5.0", @@ -9803,12 +9803,6 @@ } } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -9836,6 +9830,12 @@ } } }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", diff --git a/src/angular-vs-repeat.js b/src/angular-vs-repeat.js index dc0fa9c..de59412 100644 --- a/src/angular-vs-repeat.js +++ b/src/angular-vs-repeat.js @@ -166,6 +166,13 @@ printDeprecationWarning($element, `${attrname} attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options`); } + function safeDigest(scope) { + const phase = scope.$root.$$phase; + if (phase !== "$apply" && phase !== "$digest") { + scope.$digest(); + } + } + const defaultOptions = { latch: false, preserveLatchOnRefresh: false, @@ -377,8 +384,8 @@ _mapSize(measuredSize); reinitialize(); autosizingRequired = false; - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } } } else { @@ -416,7 +423,7 @@ function scrollHandler() { const pos = $scrollParent[0][scrollPos]; if (updateInnerCollection()) { - $scope.$digest(); + safeDigest($scope); if (options._ensureScrollIntegrity) { $scrollParent[0][scrollPos] = pos; @@ -430,13 +437,13 @@ if (options.autoresize) { autosizingRequired = true; getFromMeasured(); - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } } if (updateInnerCollection()) { - $scope.$digest(); + safeDigest($scope); } } @@ -482,8 +489,8 @@ $afterContent.css(getLayoutProps(0)); $scope.$emit('vsRenderAllDone'); - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } }); }); @@ -512,8 +519,8 @@ const ch = getClientSize($scrollParent[0], clientSize); if (ch !== _prevClientSize) { reinitialize(); - if ($scope.$root && !$scope.$root.$$phase) { - $scope.$digest(); + if ($scope.$root) { + safeDigest($scope); } } _prevClientSize = ch;