diff --git a/app/assets/javascripts/discourse/controllers/topic_controller.js b/app/assets/javascripts/discourse/controllers/topic_controller.js index b31636df6d6..e77a672d606 100644 --- a/app/assets/javascripts/discourse/controllers/topic_controller.js +++ b/app/assets/javascripts/discourse/controllers/topic_controller.js @@ -275,10 +275,6 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected return post.get('post_number') === 1 && post.get('topic.expandable_first_post'); }.property(), - slackRatio: function() { - return Discourse.Capabilities.currentProp('slackRatio'); - }.property(), - jumpTopDisabled: function() { return (this.get('progressPosition') < 2); }.property('progressPosition'), diff --git a/app/assets/javascripts/discourse/lib/capabilities.js b/app/assets/javascripts/discourse/lib/capabilities.js index d94b3da4d05..a93604f7178 100644 --- a/app/assets/javascripts/discourse/lib/capabilities.js +++ b/app/assets/javascripts/discourse/lib/capabilities.js @@ -5,29 +5,6 @@ @namespace Discourse @module Discourse **/ -Discourse.Capabilities = Ember.Object.extend({ - - /** - How much slack we should allow with infinite scrolling. - - @property slackRatio - **/ - slackRatio: function() { - // Android is slow, so we use a really small slack - if (this.get('android')) { return 0.5; } - - // Touch devices get more slack due to inertia - if (this.get('touch')) { return 1.5; } - - var desktopSlack = parseFloat(Discourse.SiteSettings.desktop_post_slack_ratio,10); - desktopSlack = Math.max(desktopSlack,1); - - // Higher resolution devices (likely laptops/desktops) should get more slack because they - // can handle the perf. - return this.get('highRes') ? desktopSlack : 0.75; - - }.property('android', 'touch', 'highRes') - -}); +Discourse.Capabilities = Ember.Object.extend({}); Discourse.Capabilities.reopenClass(Discourse.Singleton); diff --git a/app/assets/javascripts/discourse/templates/topic.js.handlebars b/app/assets/javascripts/discourse/templates/topic.js.handlebars index 63ec92a0b2f..eb3a4f044de 100644 --- a/app/assets/javascripts/discourse/templates/topic.js.handlebars +++ b/app/assets/javascripts/discourse/templates/topic.js.handlebars @@ -82,7 +82,7 @@ idProperty="post_number" defaultHeight="200" content=postStream.posts - slackRatio=slackRatio + slackRatio="15" loadingHTML=controller.loadingHTML preservesContext="true" uncloakDefault="true" diff --git a/vendor/assets/javascripts/ember-cloaking.js b/vendor/assets/javascripts/ember-cloaking.js index 07f349c4688..984c93f8b69 100644 --- a/vendor/assets/javascripts/ember-cloaking.js +++ b/vendor/assets/javascripts/ember-cloaking.js @@ -83,19 +83,25 @@ findTopView: function(childViews, viewportTop, min, max) { if (max < min) { return min; } - var mid = Math.floor((min + max) / 2), - // in case of not full-window scrolling - scrollOffset = this.get('wrapperTop') >> 0, - $view = childViews[mid].$(), - viewBottom = $view.position().top + scrollOffset + $view.height(); + var wrapperTop = this.get('wrapperTop')>>0; - if (viewBottom > viewportTop) { - return this.findTopView(childViews, viewportTop, min, mid-1); - } else { - return this.findTopView(childViews, viewportTop, mid+1, max); + while(max>min){ + var mid = Math.floor((min + max) / 2), + // in case of not full-window scrolling + $view = childViews[mid].$(), + viewBottom = $view.position().top + wrapperTop + $view.height(); + + if (viewBottom > viewportTop) { + max = mid-1; + } else { + min = mid+1; + } } + + return min; }, + /** Determine what views are onscreen and cloak/uncloak them as necessary. @@ -107,8 +113,10 @@ var childViews = this.get('childViews'); if ((!childViews) || (childViews.length === 0)) { return; } - var toUncloak = [], + var self = this, + toUncloak = [], onscreen = [], + onscreenCloaks = [], // calculating viewport edges $w = $(window), windowHeight = this.get('wrapperHeight') || ( window.innerHeight ? window.innerHeight : $w.height() ), @@ -148,6 +156,7 @@ if (viewBottom > windowTop && viewTop <= windowBottom) { onscreen.push(view.get('content')); + onscreenCloaks.push(view); } bottomView++; @@ -168,9 +177,22 @@ } var toCloak = childViews.slice(0, topView).concat(childViews.slice(bottomView+1)); - Em.run.schedule('afterRender', function() { - toUncloak.forEach(function (v) { v.uncloak(); }); + + this._uncloak = toUncloak; + if(this._nextUncloak){ + Em.run.cancel(this._nextUncloak); + this._nextUncloak = null; + } + + Em.run.schedule('afterRender', this, function() { + onscreenCloaks.forEach(function (v) { + if(v && v.uncloak) { + v.uncloak(); + } + }); toCloak.forEach(function (v) { v.cloak(); }); + if(self._nextUncloak){Em.run.cancel(self._nextUncloak)} + self._nextUncloak = Em.run.later(self, self.uncloakQueue,50); }); for (var j=bottomView; j0){ + var view = this._uncloak.shift(); + if(view && view.uncloak && !view._containedView){ + Em.run.schedule('afterRender', view, view.uncloak); + processed++; + } + } + if(this._uncloak.length === 0){ + this._uncloak = null; + } else { + Em.run.schedule('afterRender', self, function(){ + if(self._nextUncloak){ + Em.run.cancel(self._nextUncloak); + } + self._nextUncloak = Em.run.next(self, function(){ + if(self._nextUncloak){ + Em.run.cancel(self._nextUncloak); + } + self._nextUncloak = Em.run.later(self,self.uncloakQueue,delay); + }); + }); + } + } + }, + scrollTriggered: function() { Em.run.scheduleOnce('afterRender', this, 'scrolled'); },