You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2014/01/23 18:36:30 UTC
[02/10] git commit: [#4257] Refactors, added doc comments,
fixed duplicate paging controls
[#4257] Refactors, added doc comments, fixed duplicate paging controls
Signed-off-by: Cory Johns <cj...@slashdotmedia.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f1f4ff49
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f1f4ff49
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f1f4ff49
Branch: refs/heads/cj/4395
Commit: f1f4ff499c4abd3f6137fc6ac24cca71334f0b86
Parents: df82f28
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sat Jan 18 16:15:43 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:03 2014 +0000
----------------------------------------------------------------------
.../forgeactivity/nf/activity/css/activity.css | 7 +-
.../forgeactivity/nf/activity/js/activity.js | 150 +++++++++++--------
.../forgeactivity/templates/index.html | 1 -
3 files changed, 96 insertions(+), 62 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1f4ff49/ForgeActivity/forgeactivity/nf/activity/css/activity.css
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/css/activity.css b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
index 66395ff..f3a5324 100644
--- a/ForgeActivity/forgeactivity/nf/activity/css/activity.css
+++ b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
@@ -49,10 +49,13 @@
.activity .page_list {
margin-top: 5px;
}
-.activity .show-more {
+.activity .no-more.newer {
+ display: none;
+}
+.activity .show-more, .activity .no-more {
display: block;
text-align: center;
}
-.activity .show-more.older {
+.activity .show-more.older, .activity .no-more.older {
margin-top: 10px;
}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1f4ff49/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index e8c0346..a1313c6 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -17,8 +17,8 @@
under the License.
*/
-ActivityBrowseOptions = {
- maintainScrollState: true,
+ASOptions = {
+ maintainScrollHistory: true,
usePjax: true,
useHash: true,
forceAdvancedScroll: false,
@@ -27,18 +27,20 @@ ActivityBrowseOptions = {
}
$(function() {
- var hasAPI = window.history && window.history.pushState && window.history.replaceState;
- var iOS4 = navigator.userAgent.match(/iP(od|one|ad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork/);
- if (!hasAPI || iOS4) {
- ActivityBrowseOptions.usePjax = false;
- }
- if (!ActivityBrowseOptions.usePjax) {
- if (!ActivityBrowseOptions.useHash) {
- ActivityBrowseOptions.maintainScrollState = false;
+ function detectFeatures() {
+ var hasAPI = window.history && window.history.pushState && window.history.replaceState;
+ var iOS4 = navigator.userAgent.match(/iP(od|one|ad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork/);
+ if (!hasAPI || iOS4) {
+ ASOptions.usePjax = false;
}
- if (!ActivityBrowseOptions.forceAdvancedScroll) {
- ActivityBrowseOptions.useShowMore = false;
- ActivityBrowseOptions.useInfiniteScroll = false;
+ if (!ASOptions.usePjax) {
+ if (!ASOptions.useHash) {
+ ASOptions.maintainScrollHistory = false;
+ }
+ if (!ASOptions.forceAdvancedScroll) {
+ ASOptions.useShowMore = false;
+ ASOptions.useInfiniteScroll = false;
+ }
}
}
@@ -46,12 +48,20 @@ $(function() {
var oldScrollTop = null;
var oldTop = null;
function saveScrollPosition() {
+ // Save the relative position of the first visible element of
+ // interest for later restore to keep the important visible content
+ // at the same viewport position before / after DOM changes.
+ // TODO: This could be made more generic by making the "interesting
+ // elements" selector configurable.
var $firstVisible = $('.timeline li:in-viewport:first');
firstVisibleId = $firstVisible.attr('id');
oldScrollTop = $(window).scrollTop();
oldTop = $firstVisible.offset().top;
}
+
function restoreScrollPosition() {
+ // Restore the relative position of "interesting" content previously
+ // saved by saveScrollPosition.
var $window = $(window);
var $firstVisible = $('#'+firstVisibleId);
if (!$firstVisible.length) {
@@ -66,7 +76,10 @@ $(function() {
$(window).trigger('scroll');
}
- function maintainScrollState_pjax() {
+ function maintainScrollHistory_pjax() {
+ // Use the HTML5 history API to record page and scroll position.
+ // TODO: Page changes should pushState while just scroll changes
+ // should replaceState.
var $firstVisibleActivity = $('.timeline li:in-viewport:first');
var page = $firstVisibleActivity.data('page');
var limit = $('.timeline').data('limit');
@@ -76,7 +89,11 @@ $(function() {
}
}
- function maintainScrollState_hash() {
+ function maintainScrollHistory_hash() {
+ // Use the location.hash to record the scroll position.
+ // TODO/FIXME: This doesn't record the page for forceAdvancedPaging, and since
+ // the hash history is additive (confirm?), it can require clicking Back
+ // through all of your scrolling.
var $firstVisibleActivity = $('.timeline li:in-viewport:first');
saveScrollPosition();
window.location.hash = $firstVisibleActivity.attr('id'); // causes jump...
@@ -86,48 +103,63 @@ $(function() {
var delayed = null;
function scrollHandler(event) {
clearTimeout(delayed);
- delayed = setTimeout(ActivityBrowseOptions.usePjax
- ? maintainScrollState_pjax
- : maintainScrollState_hash, 100);
- }
-
- function maintainScrollState() {
- if (!ActivityBrowseOptions.maintainScrollState) {
+ var method = ASOptions.usePjax
+ ? maintainScrollHistory_pjax
+ : maintainScrollHistory_hash;
+ var delay = ASOptions.usePjax
+ ? 100 // scrolls replace history and don't affect scrolling, so more is ok
+ : 750; // scrolls add history and affect scrolling, so make sure they're done
+ delayed = setTimeout(method, delay);
+ }
+
+ function enableScrollHistory() {
+ // Attempt to record the scroll position in the browser history
+ // using either the HTML5 history API (aka PJAX) or via the location
+ // hash. Otherwise, when the user clicks a link and then comes back,
+ // they will lose their scroll position and, in the case of advanced
+ // paging, which page they were on. See: http://xkcd.com/1309/
+ if (!ASOptions.maintainScrollHistory) {
return;
}
$(window).scroll(scrollHandler);
}
function pageOut(newer) {
+ // Remove a single page of either newer or older content.
var $timeline = $('.timeline li');
- var limit = $('.timeline').data('limit') || 100;
+ var limit = $('.timeline').data('limit');
var range = newer ? [0, limit] : [-limit, undefined];
$timeline.slice(range[0], range[1]).remove();
- if (!newer && $('.show-more.older').hasClass('no-more')) {
- $('.no-more').removeClass('no-more');
- updateShowMore();
- }
+ $('.no-more.'+(newer ? 'newer' : 'older')).remove();
}
- window.pageOut = pageOut;
function pageIn(newer, url) {
+ // Load a single page of either newer or older content from the URL.
+ // If the added page causes too many to be on screen, calls pageOut
+ // to keep memory usage in check. Also uses save/restoreScrollPosition
+ // to try to keep the same content in view at the same place.
$.get(url, function(html) {
+ var $html = $(html);
+ var $timeline = $('.timeline');
+ var limit = $('.timeline').data('limit');
saveScrollPosition();
- if (newer) {
- $('.timeline').prepend(html);
- } else {
- if (html.match(/^\s*$/)) {
- $('.show-more.older').addClass('no-more');
- } else {
- $('.timeline').append(html);
- }
+ if ($html.length < limit) {
+ var method = newer ? 'before' : 'after';
+ var cls = newer ? 'newer' : 'older';
+ $timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
}
+ var method = newer ? 'prepend' : 'append';
+ $timeline[method]($html);
var firstPage = $('.timeline li:first').data('page');
var lastPage = $('.timeline li:last').data('page');
if (lastPage - firstPage >= 3) {
pageOut(!newer);
}
- if (ActivityBrowseOptions.useShowMore) {
+ if (ASOptions.useShowMore) {
+ // this has to be here instead of showMoreLink handler to
+ // ensure that scroll changes between added / removed content
+ // and Show More links combine properly and don't cause a jump
+ // due to hitting the edge of the page
updateShowMore();
}
restoreScrollPosition();
@@ -136,56 +168,56 @@ $(function() {
});
}
- function makeShowMoreHandler(newer) {
- // has to be factory to prevent closure memory leak
- // see: https://www.meteor.com/blog/2013/08/13/an-interesting-kind-of-javascript-memory-leak
- return function(event) {
- event.preventDefault();
- pageIn(newer, this.href);
- };
- }
-
function makeShowMoreLink(newer, targetPage, limit) {
- var $link = $('<a class="show-more">Show more</a>');
+ var $link = $('<a class="show-more">Show More</a>');
$link.addClass(newer ? 'newer' : 'older');
$link.attr('href', 'pjax?page='+targetPage+'&limit='+limit);
- $link.click(makeShowMoreHandler(newer)); // has to be factory to prevent closure memory leak
+ $link.click(function(event) {
+ event.preventDefault();
+ pageIn(newer, this.href);
+ });
return $link;
}
function updateShowMore() {
+ // Update the state of the Show More links when using "Show More"-style
+ // advanced paging.
var $timeline = $('.timeline');
if (!$timeline.length) {
return;
}
- var noMoreActivities = $('.show-more.older').hasClass('no-more');
- $('.page_list, .show-more').remove();
var limit = $('.timeline').data('limit');
var firstPage = $('.timeline li:first').data('page');
var lastPage = $('.timeline li:last').data('page');
- if (firstPage > 0) {
+ var noMoreNewer = firstPage == 0 || $('.no-more.newer').length;
+ var noMoreOlder = $('.no-more.older').length;
+ $('.show-more').remove(); // TODO: could update HREFs instead of always re-creating links
+ if (!noMoreNewer) {
$timeline.before(makeShowMoreLink(true, firstPage-1, limit));
}
- if (noMoreActivities) {
- $timeline.after('<div class="show-more older no-more">No more activities</div>');
- } else {
+ if (!noMoreOlder) {
$timeline.after(makeShowMoreLink(false, lastPage+1, limit));
}
}
- window.updateShowMore = updateShowMore;
+
+ function enableShowMore() {
+ $('.page_list').remove();
+ updateShowMore();
+ }
function enableInfiniteScroll() {
}
function enableAdvancedPaging() {
- if (ActivityBrowseOptions.useInfiniteScroll) {
+ if (ASOptions.useInfiniteScroll) {
enableInfiniteScroll();
- } else if (ActivityBrowseOptions.useShowMore) {
- updateShowMore();
+ } else if (ASOptions.useShowMore) {
+ enableShowMore();
}
}
- maintainScrollState(); // http://xkcd.com/1309/
+ detectFeatures();
+ enableScrollHistory();
enableAdvancedPaging();
});
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1f4ff49/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 4b8c162..5b222f7 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -47,7 +47,6 @@
{% else %}
<ul class="timeline" data-limit="{{limit}}">
{% include 'forgeactivity:templates/timeline.html' %}
- {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
</ul>
{{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
{% endif %}