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:30:43 UTC
[1/9] git commit: [#4257] Added basic paging to Activity page
Updated Branches:
refs/heads/master 88b250031 -> e276acfa3
[#4257] Added basic paging to Activity page
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/28f74b11
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/28f74b11
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/28f74b11
Branch: refs/heads/master
Commit: 28f74b117b018468a80558824601a085afd2cb90
Parents: 88b2500
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sat Jan 18 00:46:57 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:26:26 2014 +0000
----------------------------------------------------------------------
Allura/allura/lib/widgets/form_fields.py | 14 +++++++++++++-
Allura/allura/templates/widgets/page_list.html | 6 ++++--
ForgeActivity/forgeactivity/main.py | 13 +++++++++++--
ForgeActivity/forgeactivity/templates/index.html | 1 +
4 files changed, 29 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 2249372..e3060dc 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -285,7 +285,9 @@ class PageList(ew_core.Widget):
limit=None,
count=0,
page=0,
- show_label=False)
+ show_label=True,
+ show_if_single_page=False,
+ force_next=False)
def paginator(self, count, page, limit, zero_based_pages=True):
page_offset = 1 if zero_based_pages else 0
@@ -298,6 +300,16 @@ class PageList(ew_core.Widget):
return paginate.Page(range(count), page + page_offset, int(limit),
url=page_url)
+ def prepare_context(self, context):
+ context = super(PageList, self).prepare_context(context)
+ count = context['count']
+ page = context['page']
+ limit = context['limit']
+ context['paginator'] = self.paginator(count, page, limit)
+ if context['force_next']:
+ context['paginator'].next_page = context['paginator'].page + 1
+ return context
+
def resources(self):
yield ew.CSSLink('css/page_list.css')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/Allura/allura/templates/widgets/page_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/page_list.html b/Allura/allura/templates/widgets/page_list.html
index a5f39b2..64ff18f 100644
--- a/Allura/allura/templates/widgets/page_list.html
+++ b/Allura/allura/templates/widgets/page_list.html
@@ -18,8 +18,10 @@
-#}
<div>
<div class="page_list">
- {% set paginator = widget.paginator(count, page, limit) %}
- {{paginator.pager('$link_first $link_previous ~2~ $link_next $link_last (Page $page of $page_count)')}}
+ {{paginator.pager(
+ format='$link_first $link_previous ~2~ $link_next $link_last' + (show_label and ' (Page $page of $page_count)' or ''),
+ show_if_single_page=show_if_single_page
+ )}}
</div>
<div class="clear"></div>
</div>
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index da81307..991bb61 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -22,7 +22,7 @@ from pylons import tmpl_context as c, app_globals as g
from pylons import request, response
from tg import expose, validate, config
from tg.decorators import with_trailing_slash, without_trailing_slash
-from paste.deploy.converters import asbool
+from paste.deploy.converters import asbool, asint
from webob import exc
from webhelpers import feedgenerator as FG
@@ -33,6 +33,7 @@ from allura.lib.security import require_authenticated
from allura.model.timeline import perm_check
from allura.lib import helpers as h
from allura.lib.decorators import require_post
+from allura.lib.widgets.form_fields import PageList
from allura.ext.user_profile import ProfileSectionBase
from .widgets.follow import FollowToggle
@@ -65,6 +66,7 @@ class ForgeActivityApp(Application):
class W:
follow_toggle = FollowToggle()
+ page_list = PageList()
class ForgeActivityController(BaseController):
@@ -91,6 +93,7 @@ class ForgeActivityController(BaseController):
raise exc.HTTPNotFound()
c.follow_toggle = W.follow_toggle
+ c.page_list = W.page_list
if c.project.is_user_project:
followee = c.project.user_project_of
actor_only = followee != c.user
@@ -103,7 +106,13 @@ class ForgeActivityController(BaseController):
limit=kw.get('limit', 100),
actor_only=actor_only,
filter_func=perm_check(c.user))
- return dict(followee=followee, following=following, timeline=timeline)
+ return dict(
+ followee=followee,
+ following=following,
+ timeline=timeline,
+ page=asint(kw.get('page', 0)),
+ limit=asint(kw.get('limit', 100)),
+ )
@expose('jinja:forgeactivity:templates/index.html')
@with_trailing_slash
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 435fc82..e63c904 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -57,6 +57,7 @@
{% endif %}
</li>
{% endfor %}
+ {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
</ul>
{% endif %}
</div>
[7/9] git commit: [#4257] Disable hash-based scroll management as
it's not worth it
Posted by jo...@apache.org.
[#4257] Disable hash-based scroll management as it's not worth it
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/de4f5b71
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/de4f5b71
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/de4f5b71
Branch: refs/heads/master
Commit: de4f5b715c58a9d04945f14259351c886cf962a0
Parents: a3c5bf7
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 17:12:35 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000
----------------------------------------------------------------------
ForgeActivity/forgeactivity/nf/activity/js/activity.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/de4f5b71/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 80b79d8..0ed3b0e 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -21,7 +21,7 @@ ASOptions = {
maxPages: 3,
maintainScrollHistory: true,
usePjax: true,
- useHash: true,
+ useHash: false, // not worth the jitter
forceAdvancedScroll: false,
useShowMore: false,
useInfiniteScroll: true
[9/9] git commit: [#4257] Fixed page controls not showing on last
page of activity stream
Posted by jo...@apache.org.
[#4257] Fixed page controls not showing on last page of activity stream
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/c77b366c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c77b366c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c77b366c
Branch: refs/heads/master
Commit: c77b366cf65c146f7fad3582504a9e5c5575c3bb
Parents: 23ad424
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jan 21 23:25:57 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000
----------------------------------------------------------------------
ForgeActivity/forgeactivity/main.py | 14 ++++++++------
ForgeActivity/forgeactivity/templates/index.html | 4 ++--
2 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c77b366c/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 09d0c62..f269336 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -106,13 +106,15 @@ class ForgeActivityController(BaseController):
limit=kw.get('limit', 100),
actor_only=actor_only,
filter_func=perm_check(c.user))
+ page = asint(kw.get('page', 0))
+ limit = asint(kw.get('limit', 100))
return dict(
- followee=followee,
- following=following,
- timeline=timeline,
- page=asint(kw.get('page', 0)),
- limit=asint(kw.get('limit', 100)),
- )
+ followee=followee,
+ following=following,
+ timeline=timeline,
+ page=page,
+ limit=limit,
+ has_more=len(timeline) == limit)
@expose('jinja:forgeactivity:templates/index.html')
@with_trailing_slash
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c77b366c/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 5b222f7..fef165a 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -43,12 +43,12 @@
<div class="activity">
{% if not timeline %}
- No activity to display.
+ No {% if page > 0 %} more {% endif %} activity to display.
{% else %}
<ul class="timeline" data-limit="{{limit}}">
{% include 'forgeactivity:templates/timeline.html' %}
</ul>
- {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
{% endif %}
+ {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=has_more)}}
</div>
{% endblock %}
[3/9] git commit: [#4257] Added PJAX Show More paging with scroll
state saving
Posted by jo...@apache.org.
[#4257] Added PJAX Show More paging with scroll state saving
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/df82f288
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/df82f288
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/df82f288
Branch: refs/heads/master
Commit: df82f2887de3791b8070b12402791a98da454d0c
Parents: 28f74b1
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sat Jan 18 00:50:38 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:03 2014 +0000
----------------------------------------------------------------------
Allura/LICENSE | 2 +
Allura/allura/public/nf/js/jquery.viewport.js | 58 +++++
ForgeActivity/forgeactivity/main.py | 4 +
.../forgeactivity/nf/activity/css/activity.css | 10 +
.../forgeactivity/nf/activity/js/activity.js | 209 +++++++++++++++++++
.../forgeactivity/templates/index.html | 21 +-
.../forgeactivity/templates/timeline.html | 35 ++++
7 files changed, 324 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/Allura/LICENSE
----------------------------------------------------------------------
diff --git a/Allura/LICENSE b/Allura/LICENSE
index 7e0be3d..36c9038 100644
--- a/Allura/LICENSE
+++ b/Allura/LICENSE
@@ -232,6 +232,8 @@ under the MIT license. For details, see the individual files:
allura/lib/widgets/resources/js/jquery.tools.min.js
allura/public/nf/js/jquery.flot.js
allura/public/nf/js/jquery.maxlength.min.js
+ allura/public/nf/js/jquery.viewport.js
+ allura/public/nf/js/jquery.pjax.js
Blueprint, which is available under the MIT license.
For details, see allura/public/nf/css/blueprint/
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/Allura/allura/public/nf/js/jquery.viewport.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/jquery.viewport.js b/Allura/allura/public/nf/js/jquery.viewport.js
new file mode 100644
index 0000000..7826000
--- /dev/null
+++ b/Allura/allura/public/nf/js/jquery.viewport.js
@@ -0,0 +1,58 @@
+/*
+ * Viewport - jQuery selectors for finding elements in viewport
+ *
+ * Copyright (c) 2008-2009 Mika Tuupola
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Project home:
+ * http://www.appelsiini.net/projects/viewport
+ *
+ */
+(function($) {
+
+ $.belowthefold = function(element, settings) {
+ var fold = $(window).height() + $(window).scrollTop();
+ return fold <= $(element).offset().top - settings.threshold;
+ };
+
+ $.abovethetop = function(element, settings) {
+ var top = $(window).scrollTop();
+ return top >= $(element).offset().top + $(element).height() - settings.threshold;
+ };
+
+ $.rightofscreen = function(element, settings) {
+ var fold = $(window).width() + $(window).scrollLeft();
+ return fold <= $(element).offset().left - settings.threshold;
+ };
+
+ $.leftofscreen = function(element, settings) {
+ var left = $(window).scrollLeft();
+ return left >= $(element).offset().left + $(element).width() - settings.threshold;
+ };
+
+ $.inviewport = function(element, settings) {
+ return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
+ };
+
+ $.extend($.expr[':'], {
+ "below-the-fold": function(a, i, m) {
+ return $.belowthefold(a, {threshold : 0});
+ },
+ "above-the-top": function(a, i, m) {
+ return $.abovethetop(a, {threshold : 0});
+ },
+ "left-of-screen": function(a, i, m) {
+ return $.leftofscreen(a, {threshold : 0});
+ },
+ "right-of-screen": function(a, i, m) {
+ return $.rightofscreen(a, {threshold : 0});
+ },
+ "in-viewport": function(a, i, m) {
+ return $.inviewport(a, {threshold : 0});
+ }
+ });
+
+
+})(jQuery);
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 991bb61..09d0c62 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -119,6 +119,10 @@ class ForgeActivityController(BaseController):
def index(self, **kw):
return self._get_activities_data(**kw)
+ @expose('jinja:forgeactivity:templates/timeline.html')
+ def pjax(self, **kw):
+ return self._get_activities_data(**kw)
+
@without_trailing_slash
@expose()
def feed(self, **kw):
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/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 dc71608..66395ff 100644
--- a/ForgeActivity/forgeactivity/nf/activity/css/activity.css
+++ b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
@@ -46,3 +46,13 @@
float: left;
margin: 10px 10px 0 0;
}
+.activity .page_list {
+ margin-top: 5px;
+}
+.activity .show-more {
+ display: block;
+ text-align: center;
+}
+.activity .show-more.older {
+ margin-top: 10px;
+}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/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
new file mode 100644
index 0000000..e8c0346
--- /dev/null
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -0,0 +1,209 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+ActivityBrowseOptions = {
+ maintainScrollState: true,
+ usePjax: true,
+ useHash: true,
+ forceAdvancedScroll: false,
+ useShowMore: true,
+ useInfiniteScroll: false
+}
+
+$(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;
+ }
+ if (!ActivityBrowseOptions.forceAdvancedScroll) {
+ ActivityBrowseOptions.useShowMore = false;
+ ActivityBrowseOptions.useInfiniteScroll = false;
+ }
+ }
+
+ var firstVisibleId = null;
+ var oldScrollTop = null;
+ var oldTop = null;
+ function saveScrollPosition() {
+ var $firstVisible = $('.timeline li:in-viewport:first');
+ firstVisibleId = $firstVisible.attr('id');
+ oldScrollTop = $(window).scrollTop();
+ oldTop = $firstVisible.offset().top;
+ }
+ function restoreScrollPosition() {
+ var $window = $(window);
+ var $firstVisible = $('#'+firstVisibleId);
+ if (!$firstVisible.length) {
+ return;
+ }
+ var newTop = $firstVisible.offset().top;
+ var scrollTop = $window.scrollTop();
+ var elemAdjustment = newTop - oldTop;
+ var viewportAdjustment = scrollTop - oldScrollTop;
+ $window.scrollTop(scrollTop + elemAdjustment - viewportAdjustment);
+ //console.log('restoreSP', oldTop, newTop, elemAdjustment, viewportAdjustment, scrollTop, $window.scrollTop());
+ $(window).trigger('scroll');
+ }
+
+ function maintainScrollState_pjax() {
+ var $firstVisibleActivity = $('.timeline li:in-viewport:first');
+ var page = $firstVisibleActivity.data('page');
+ var limit = $('.timeline').data('limit');
+ var hash = $firstVisibleActivity.attr('id');
+ if (page != null && limit != null && hash != null) {
+ history.replaceState(null, null, '?page='+page+'&limit='+limit+'#'+hash);
+ }
+ }
+
+ function maintainScrollState_hash() {
+ var $firstVisibleActivity = $('.timeline li:in-viewport:first');
+ saveScrollPosition();
+ window.location.hash = $firstVisibleActivity.attr('id'); // causes jump...
+ restoreScrollPosition();
+ }
+
+ var delayed = null;
+ function scrollHandler(event) {
+ clearTimeout(delayed);
+ delayed = setTimeout(ActivityBrowseOptions.usePjax
+ ? maintainScrollState_pjax
+ : maintainScrollState_hash, 100);
+ }
+
+ function maintainScrollState() {
+ if (!ActivityBrowseOptions.maintainScrollState) {
+ return;
+ }
+ $(window).scroll(scrollHandler);
+ }
+
+ function pageOut(newer) {
+ var $timeline = $('.timeline li');
+ var limit = $('.timeline').data('limit') || 100;
+ 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();
+ }
+ }
+ window.pageOut = pageOut;
+
+ function pageIn(newer, url) {
+ $.get(url, function(html) {
+ saveScrollPosition();
+ if (newer) {
+ $('.timeline').prepend(html);
+ } else {
+ if (html.match(/^\s*$/)) {
+ $('.show-more.older').addClass('no-more');
+ } else {
+ $('.timeline').append(html);
+ }
+ }
+ var firstPage = $('.timeline li:first').data('page');
+ var lastPage = $('.timeline li:last').data('page');
+ if (lastPage - firstPage >= 3) {
+ pageOut(!newer);
+ }
+ if (ActivityBrowseOptions.useShowMore) {
+ updateShowMore();
+ }
+ restoreScrollPosition();
+ }).fail(function() {
+ flash('Error loading activities', 'error');
+ });
+ }
+
+ 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>');
+ $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
+ return $link;
+ }
+
+ function updateShowMore() {
+ 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) {
+ $timeline.before(makeShowMoreLink(true, firstPage-1, limit));
+ }
+ if (noMoreActivities) {
+ $timeline.after('<div class="show-more older no-more">No more activities</div>');
+ } else {
+ $timeline.after(makeShowMoreLink(false, lastPage+1, limit));
+ }
+ }
+ window.updateShowMore = updateShowMore;
+
+ function enableInfiniteScroll() {
+ }
+
+ function enableAdvancedPaging() {
+ if (ActivityBrowseOptions.useInfiniteScroll) {
+ enableInfiniteScroll();
+ } else if (ActivityBrowseOptions.useShowMore) {
+ updateShowMore();
+ }
+ }
+
+ maintainScrollState(); // http://xkcd.com/1309/
+ enableAdvancedPaging();
+});
+
+function markTop() {
+ var $marker = $('#offset-marker');
+ if (!$marker.length) {
+ $marker = $('<div id="offset-marker"> </div>');
+ $marker.css({
+ 'position': 'absolute',
+ 'top': 0,
+ 'width': '100%',
+ 'border-top': '1px solid green'
+ });
+ $marker.appendTo($('body'));
+ }
+ $marker.css({'top': $(window).scrollTop()});
+}
+
+function markFirst() {
+ $('.timeline li:in-viewport:first').css({'background-color': '#f0fff0'});
+}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index e63c904..4b8c162 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -38,27 +38,18 @@
{% endblock %}
{% block content %}
+{% do g.register_forge_js('js/jquery.viewport.js') %}
+{% do g.register_app_js('js/activity.js') %}
+
<div class="activity">
{% if not timeline %}
No activity to display.
{% else %}
- <ul class="timeline">
- {% for a in timeline %}
- <li>
- <time datetime="{{a.published|datetimeformat}}" title="{{a.published|datetimeformat}}">{{h.ago(a.published, show_date_after=None)}}</time>
- <h1>
- {{ am.icon(a.actor, 32, 'avatar') }}
- {{am.activity_obj(a.actor)}} {{a.verb}} {{am.activity_obj(a.obj)}} {% if a.target.activity_name %}on {{am.activity_obj(a.target)}}{% endif %}
- </h1>
- {% if a.obj.activity_extras.get('summary') %}
- <p>
- {{ a.obj.activity_extras.get('summary') }}
- </p>
- {% endif %}
- </li>
- {% endfor %}
+ <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 %}
</div>
{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/templates/timeline.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/timeline.html b/ForgeActivity/forgeactivity/templates/timeline.html
new file mode 100644
index 0000000..499fe03
--- /dev/null
+++ b/ForgeActivity/forgeactivity/templates/timeline.html
@@ -0,0 +1,35 @@
+{#-
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-#}
+
+{% import 'forgeactivity:templates/macros.html' as am with context %}
+
+{% for a in timeline %}
+<li id="{{a._id}}" data-page="{{page}}">
+ <time datetime="{{a.published|datetimeformat}}" title="{{a.published|datetimeformat}}">{{h.ago(a.published, show_date_after=None)}}</time>
+ <h1>
+ {{ am.icon(a.actor, 32, 'avatar') }}
+ {{am.activity_obj(a.actor)}} {{a.verb}} {{am.activity_obj(a.obj)}} {% if a.target.activity_name %}on {{am.activity_obj(a.target)}}{% endif %}
+ </h1>
+ {% if a.obj.activity_extras.get('summary') %}
+ <p>
+ {{ a.obj.activity_extras.get('summary') }}
+ </p>
+ {% endif %}
+</li>
+{% endfor %}
[5/9] git commit: [#4257] Fixed page back to start, and more refactors
Posted by jo...@apache.org.
[#4257] Fixed page back to start, and more refactors
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/3d9ff04e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3d9ff04e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3d9ff04e
Branch: refs/heads/master
Commit: 3d9ff04e51d3a5ef3e1a4871954b3253f00a5b70
Parents: f1f4ff4
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sun Jan 19 01:14:51 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000
----------------------------------------------------------------------
.../forgeactivity/nf/activity/js/activity.js | 66 ++++++++++++--------
1 file changed, 41 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3d9ff04e/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 a1313c6..48b699f 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -18,6 +18,7 @@
*/
ASOptions = {
+ maxPages: 3,
maintainScrollHistory: true,
usePjax: true,
useHash: true,
@@ -27,6 +28,17 @@ ASOptions = {
}
$(function() {
+ if (!$('.timeline li').length) {
+ return; // no timeline, no paging
+ }
+
+ $.expr[':']['timeline-page'] = $.expr.createPseudo(function(page) {
+ // Select timeline elements by their page. NB: only works on activity LIs.
+ return function(elem) {
+ return $(elem).data('page') == page;
+ }
+ });
+
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/);
@@ -72,7 +84,6 @@ $(function() {
var elemAdjustment = newTop - oldTop;
var viewportAdjustment = scrollTop - oldScrollTop;
$window.scrollTop(scrollTop + elemAdjustment - viewportAdjustment);
- //console.log('restoreSP', oldTop, newTop, elemAdjustment, viewportAdjustment, scrollTop, $window.scrollTop());
$(window).trigger('scroll');
}
@@ -125,36 +136,35 @@ $(function() {
}
function pageOut(newer) {
- // Remove a single page of either newer or older content.
+ // Remove newest or oldest page to keep memory usage in check.
var $timeline = $('.timeline li');
- var limit = $('.timeline').data('limit');
- var range = newer ? [0, limit] : [-limit, undefined];
- $timeline.slice(range[0], range[1]).remove();
+ var firstPage = $timeline.first().data('page');
+ var lastPage = $timeline.last().data('page');
+ var numPages = lastPage - firstPage + 1;
+ if (numPages <= ASOptions.maxPages) {
+ return;
+ }
+ var pageToRemove = newer ? firstPage : lastPage;
+ $('.timeline li:timeline-page('+pageToRemove+')').remove();
$('.no-more.'+(newer ? 'newer' : 'older')).remove();
}
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
+ // Then calls pageOut to ensure that not too many are loaded at once,
// 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 newPage = $html.data('page');
var limit = $('.timeline').data('limit');
saveScrollPosition();
- 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 ($html.length < limit || newPage == 0) {
+ makeNoMore(newer);
}
+ $timeline[newer ? 'prepend' : 'append']($html);
+ pageOut(!newer);
if (ASOptions.useShowMore) {
// this has to be here instead of showMoreLink handler to
// ensure that scroll changes between added / removed content
@@ -168,6 +178,13 @@ $(function() {
});
}
+ function makeNoMore(newer) {
+ var $timeline = $('.timeline');
+ var method = newer ? 'before' : 'after';
+ var cls = newer ? 'newer' : 'older';
+ $timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
+ }
+
function makeShowMoreLink(newer, targetPage, limit) {
var $link = $('<a class="show-more">Show More</a>');
$link.addClass(newer ? 'newer' : 'older');
@@ -176,32 +193,31 @@ $(function() {
event.preventDefault();
pageIn(newer, this.href);
});
- return $link;
+ $('.timeline')[newer ? 'before' : 'after']($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 limit = $('.timeline').data('limit');
var firstPage = $('.timeline li:first').data('page');
var lastPage = $('.timeline li:last').data('page');
- var noMoreNewer = firstPage == 0 || $('.no-more.newer').length;
+ var noMoreNewer = $('.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));
+ makeShowMoreLink(true, firstPage-1, limit);
}
if (!noMoreOlder) {
- $timeline.after(makeShowMoreLink(false, lastPage+1, limit));
+ makeShowMoreLink(false, lastPage+1, limit);
}
}
function enableShowMore() {
$('.page_list').remove();
+ if ($('.timeline li:first').data('page') == 0) {
+ makeNoMore(true);
+ }
updateShowMore();
}
[6/9] git commit: [#4257] Ugly hack to fix Access Denied error in IE
Posted by jo...@apache.org.
[#4257] Ugly hack to fix Access Denied error in IE
It seems that some combination of IE11, jQuery 1.8.0, and possibly
something else on our page, doing $('<li>elem</li>') causes IE to raise
an "Access denied" error claiming that we're attempting cross-site
javascript iframe access. However, doing $('#elem').append('<li>elem</li>')
works fine. I'd prefer to upgrade jQuery but this is a quicker work-around.
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/a3c5bf7f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a3c5bf7f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a3c5bf7f
Branch: refs/heads/master
Commit: a3c5bf7f2328c21303f17a6a1f1aeffb7fab02d2
Parents: c77b366
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 17:05:58 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000
----------------------------------------------------------------------
.../forgeactivity/nf/activity/js/activity.js | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a3c5bf7f/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 f6807d7..80b79d8 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -164,16 +164,21 @@ $(function() {
}
var newerText = newer ? 'newer' : 'older';
$.get(url, function(html) {
- var $html = $(html);
var $timeline = $('.timeline');
- var newPage = $html.data('page');
+ var empty = html.match(/^\s*$/);
+ var newestPage = newer && $('.timeline li:first').data('page') <= 1;
var limit = $('.timeline').data('limit');
+ var fullPage = true;
saveScrollPosition();
- if ($html.length < limit || newPage == 0) {
+ if (!empty) {
+ $timeline[newer ? 'prepend' : 'append'](html);
+ var newPage = $timeline.find('li:' + (newer ? 'first' : 'last')).data('page');
+ fullPage = $timeline.find('li:timeline-page('+newPage+')').length == limit;
+ pageOut(!newer);
+ }
+ if (empty || !fullPage || newestPage) {
makeNoMore(newer);
}
- $timeline[newer ? 'prepend' : 'append']($html);
- pageOut(!newer);
if (ASOptions.useShowMore) {
// this has to be here instead of showMoreLink handler to
// ensure that scroll changes between added / removed content
[4/9] git commit: [#4257] More IE hacks to avoid Access Denied
Posted by jo...@apache.org.
[#4257] More IE hacks to avoid Access Denied
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/e276acfa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/e276acfa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/e276acfa
Branch: refs/heads/master
Commit: e276acfa3a48acb28862af6213c8284ba4331d44
Parents: de4f5b7
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 21:34:56 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000
----------------------------------------------------------------------
ForgeActivity/forgeactivity/nf/activity/js/activity.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e276acfa/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 0ed3b0e..ad835d2 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -210,14 +210,14 @@ $(function() {
}
function makeShowMoreLink(newer, targetPage) {
- var $link = $('<a class="show-more">Show More</a>');
- $link.addClass(newer ? 'newer' : 'older');
- $link.attr('href', makePageUrl(targetPage));
- $link.click(function(event) {
+ var cls = newer ? 'newer' : 'older';
+ var url = makePageUrl(targetPage);
+ var link = '<a class="show-more '+cls+'" href="'+url+'">Show More</a>';
+ $('.timeline')[newer ? 'before' : 'after'](link);
+ $('.show-more.'+cls).click(function(event) {
event.preventDefault();
pageIn(newer, this.href);
});
- $('.timeline')[newer ? 'before' : 'after']($link);
}
function updateShowMore() {
[8/9] git commit: [#4257] Added infinite scroll
Posted by jo...@apache.org.
[#4257] Added infinite scroll
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/23ad4247
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/23ad4247
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/23ad4247
Branch: refs/heads/master
Commit: 23ad4247bb7b7f9461d8f79c715f2954f5d5b4ec
Parents: 3d9ff04
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sun Jan 19 18:58:10 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000
----------------------------------------------------------------------
.../forgeactivity/nf/activity/js/activity.js | 65 +++++++++++++++++---
1 file changed, 55 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23ad4247/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 48b699f..f6807d7 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -23,8 +23,8 @@ ASOptions = {
usePjax: true,
useHash: true,
forceAdvancedScroll: false,
- useShowMore: true,
- useInfiniteScroll: false
+ useShowMore: false,
+ useInfiniteScroll: true
}
$(function() {
@@ -111,16 +111,16 @@ $(function() {
restoreScrollPosition();
}
- var delayed = null;
+ var scrollHandlerDelayed = null;
function scrollHandler(event) {
- clearTimeout(delayed);
+ clearTimeout(scrollHandlerDelayed);
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);
+ scrollHandlerDelayed = setTimeout(method, delay);
}
function enableScrollHistory() {
@@ -149,11 +149,20 @@ $(function() {
$('.no-more.'+(newer ? 'newer' : 'older')).remove();
}
+ var pageInQueue = [];
function pageIn(newer, url) {
// Load a single page of either newer or older content from the URL.
// Then calls pageOut to ensure that not too many are loaded at once,
// to keep memory usage in check. Also uses save/restoreScrollPosition
// to try to keep the same content in view at the same place.
+ if ($('.no-more.'+(newer ? 'newer' : 'older')).length) {
+ return;
+ }
+ pageInQueue.push({newer: newer, url: url});
+ if (pageInQueue.length > 1) {
+ return;
+ }
+ var newerText = newer ? 'newer' : 'older';
$.get(url, function(html) {
var $html = $(html);
var $timeline = $('.timeline');
@@ -173,6 +182,11 @@ $(function() {
updateShowMore();
}
restoreScrollPosition();
+ pageInQueue.shift();
+ if (pageInQueue.length) {
+ var next = pageInQueue.shift();
+ pageIn(next.newer, next.url);
+ }
}).fail(function() {
flash('Error loading activities', 'error');
});
@@ -185,10 +199,15 @@ $(function() {
$timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
}
- function makeShowMoreLink(newer, targetPage, limit) {
+ function makePageUrl(targetPage) {
+ var limit = $('.timeline').data('limit');
+ return 'pjax?page='+targetPage+'&limit='+limit;
+ }
+
+ function makeShowMoreLink(newer, targetPage) {
var $link = $('<a class="show-more">Show More</a>');
$link.addClass(newer ? 'newer' : 'older');
- $link.attr('href', 'pjax?page='+targetPage+'&limit='+limit);
+ $link.attr('href', makePageUrl(targetPage));
$link.click(function(event) {
event.preventDefault();
pageIn(newer, this.href);
@@ -199,17 +218,16 @@ $(function() {
function updateShowMore() {
// Update the state of the Show More links when using "Show More"-style
// advanced paging.
- var limit = $('.timeline').data('limit');
var firstPage = $('.timeline li:first').data('page');
var lastPage = $('.timeline li:last').data('page');
var noMoreNewer = $('.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) {
- makeShowMoreLink(true, firstPage-1, limit);
+ makeShowMoreLink(true, firstPage-1);
}
if (!noMoreOlder) {
- makeShowMoreLink(false, lastPage+1, limit);
+ makeShowMoreLink(false, lastPage+1);
}
}
@@ -221,7 +239,34 @@ $(function() {
updateShowMore();
}
+ var currentPage = null;
+ function handleInfiniteScroll(event) {
+ var newPage = $('.timeline li:in-viewport:first').data('page');
+ if (newPage == currentPage) {
+ return;
+ }
+ var firstPage = $('.timeline li:first').data('page');
+ var lastPage = $('.timeline li:last').data('page');
+ var noMoreNewer = $('.no-more.newer').length;
+ var noMoreOlder = $('.no-more.older').length;
+ if (newPage < currentPage && !noMoreNewer) {
+ pageIn(true, makePageUrl(firstPage-1));
+ } else if (newPage > currentPage && !noMoreOlder) {
+ pageIn(false, makePageUrl(lastPage+1));
+ }
+ currentPage = newPage;
+ }
+
function enableInfiniteScroll() {
+ $('.page_list').remove();
+ currentPage = $('.timeline li:first').data('page');
+ if (currentPage == 0) {
+ makeNoMore(true);
+ } else {
+ pageIn(true, makePageUrl(currentPage-1));
+ }
+ pageIn(false, makePageUrl(currentPage+1));
+ $(window).scroll(handleInfiniteScroll);
}
function enableAdvancedPaging() {
[2/9] git commit: [#4257] Refactors, added doc comments,
fixed duplicate paging controls
Posted by jo...@apache.org.
[#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/master
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 %}