launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #11827
[Merge] lp:~wallyworld/launchpad/bug-nav-links-924801 into lp:launchpad
Ian Booth has proposed merging lp:~wallyworld/launchpad/bug-nav-links-924801 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #924801 in Launchpad itself: ""First • Previous • Next • Last" links are active when they don't do anything"
https://bugs.launchpad.net/launchpad/+bug/924801
For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/bug-nav-links-924801/+merge/123872
== Implementation ==
After much experimentation, the easiest thing to do here was to update some existing rules - "invalid-link" has been used with disabled anchors, so :hover and :selected pseudo classes were added so that the links appear fully disabled. This change ensures the cursor doesn't change to a pointer and the link stays grey etc when hovered over or clicked. The click handler for the links was updated to check for the 'invalid-link' class and return if set.
A bot of refactoring was also done to eliminate the need for the namespace method "linkify_navigation". It is better that this be an internal method which is called by the widget itself rather than requiring the callsites to invoke it.
== Tests ==
Update the test_listing_navigator yui tests.
== Lint ==
Checking for conflicts and issues in changed files.
Linting changed files:
lib/canonical/launchpad/icing/css/typography.css
lib/lp/app/javascript/listing_navigator.js
lib/lp/app/javascript/tests/test_listing_navigator.js
lib/lp/bugs/javascript/buglisting.js
lib/lp/registry/javascript/sharing/granteetable.js
--
https://code.launchpad.net/~wallyworld/launchpad/bug-nav-links-924801/+merge/123872
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/bug-nav-links-924801 into lp:launchpad.
=== modified file 'lib/canonical/launchpad/icing/css/typography.css'
--- lib/canonical/launchpad/icing/css/typography.css 2012-06-15 18:21:34 +0000
+++ lib/canonical/launchpad/icing/css/typography.css 2012-09-12 02:03:23 +0000
@@ -77,8 +77,7 @@
a.help.icon, a.sprite.maybe.help {
border: none;
}
-a.invalid-link {
- disabled: True;
+a.invalid-link, a.invalid-link:active, a.invalid-link:hover {
color: #909090;
text-decoration: none;
cursor: default;
=== modified file 'lib/lp/app/javascript/listing_navigator.js'
--- lib/lp/app/javascript/listing_navigator.js 2012-07-18 14:08:32 +0000
+++ lib/lp/app/javascript/listing_navigator.js 2012-09-12 02:03:23 +0000
@@ -16,6 +16,21 @@
}
/**
+ * Rewrite all nodes with navigation classes so that they are hyperlinks.
+ * Content is retained.
+ */
+function linkify_navigation(container_node) {
+ Y.each(['previous', 'next', 'first', 'last'], function(class_name) {
+ container_node.all('.' + class_name).each(function(node) {
+ var new_node = Y.Node.create('<a href="#"></a>');
+ new_node.addClass(class_name);
+ new_node.setContent(node.getContent());
+ node.replace(new_node);
+ });
+ });
+}
+
+/**
* If there is no context (say /bugs/+bugs) we need to generate a weblink for
* the lp.client to use for things. This is a helper to take the current url
* and try to generate a likely web_link value to build a url off of.
@@ -110,6 +125,15 @@
pre_fetch: {value: false},
navigation_indices: {valueFn: empty_nodelist},
target: {value: null},
+ container: {
+ value: null,
+ getter: function(value) {
+ if (!Y.Lang.isValue(value)) {
+ return this.get('target');
+ }
+ return value;
+ }
+ },
template: {value: null}
};
@@ -149,6 +173,7 @@
this.get('model').get('history').after(
'change', this.default_history_changed, this);
}
+ linkify_navigation(this.get('container'));
},
/**
@@ -189,7 +214,15 @@
clickAction: function(selector, callback) {
var nodes = this.get('target').get('parentNode').all(selector);
nodes.on('click', function(e) {
- e.preventDefault();
+ e.halt();
+ // If the target link is disabled, we want to ignore the click.
+ var link = e.target;
+ if (link.get('tagName').toLowerCase() !== 'a' ) {
+ link = link.ancestor('a');
+ }
+ if (!Y.Lang.isValue(link) || link.hasClass('invalid-link')) {
+ return;
+ }
callback.call(this);
}, this);
nodes.addClass('js-action');
@@ -307,9 +340,9 @@
*/
update_navigation_links: function() {
this.get('backwards_navigation').toggleClass(
- 'inactive', !this.has_prev());
+ 'invalid-link', !this.has_prev());
this.get('forwards_navigation').toggleClass(
- 'inactive', !this.has_next());
+ 'invalid-link', !this.has_next());
},
update_from_new_model: function(query, fetch_only, model) {
@@ -519,22 +552,6 @@
/**
- * Rewrite all nodes with navigation classes so that they are hyperlinks.
- * Content is retained.
- */
-module.linkify_navigation = function(container_node) {
- Y.each(['previous', 'next', 'first', 'last'], function(class_name) {
- container_node.all('.' + class_name).each(function(node) {
- new_node = Y.Node.create('<a href="#"></a>');
- new_node.addClass(class_name);
- new_node.setContent(node.getContent());
- node.replace(new_node);
- });
- });
-};
-
-
-/**
* Return the value for a given feature flag in the current scope.
* Only flags declared as "related_features" on the view are available.
*/
=== modified file 'lib/lp/app/javascript/tests/test_listing_navigator.js'
--- lib/lp/app/javascript/tests/test_listing_navigator.js 2012-09-10 21:02:05 +0000
+++ lib/lp/app/javascript/tests/test_listing_navigator.js 2012-09-12 02:03:23 +0000
@@ -88,7 +88,7 @@
Y.lp.testing.helpers.reset_history();
},
- get_render_navigator: function() {
+ get_render_navigator: function(container) {
var lp_cache = {
mustache_model: {
items: [{foo: 'bar', show_foo: true}]
@@ -105,7 +105,8 @@
var navigator = new TestListingNavigator({
cache: lp_cache,
template: template,
- target: this.target
+ target: this.target,
+ container: container
});
var index = Y.Node.create(
'<div><strong>3</strong> → <strong>4</strong>' +
@@ -132,7 +133,7 @@
var navigator = this.get_render_navigator();
var action = navigator.get('backwards_navigation').item(0);
navigator.update_navigation_links();
- Y.Assert.isTrue(action.hasClass('inactive'));
+ Y.Assert.isTrue(action.hasClass('invalid-link'));
},
/**
* update_navigation_links should enable "previous" and "first" if
@@ -147,7 +148,7 @@
start: 1, memo: 'pi'
};
navigator.update_navigation_links();
- Y.Assert.isFalse(action.hasClass('inactive'));
+ Y.Assert.isFalse(action.hasClass('invalid-link'));
},
/**
* update_navigation_links should disable "next" and "last" if there is
@@ -158,7 +159,7 @@
var navigator = this.get_render_navigator();
var action = navigator.get('forwards_navigation').item(0);
navigator.update_navigation_links();
- Y.Assert.isTrue(action.hasClass('inactive'));
+ Y.Assert.isTrue(action.hasClass('invalid-link'));
},
/**
* update_navigation_links should enable "next" and "last" if there is a
@@ -173,10 +174,10 @@
start: 1, memo: 'pi'
};
navigator.update_navigation_links();
- Y.Assert.isFalse(action.hasClass('inactive'));
+ Y.Assert.isFalse(action.hasClass('invalid-link'));
},
/**
- * linkify_navigation should convert previous, next, first last into
+ * Creating a navigator should convert previous, next, first last into
* hyperlinks, while retaining the original content.
*/
test_linkify_navigation: function() {
@@ -188,11 +189,12 @@
'<span class="first">FiRST</span>' +
'<span class="last">lAst</span>' +
'</div>');
- module.linkify_navigation(Y.one('#bugs-table-listing'));
+ this.target = Y.one('#bugs-table-listing');
+ this.get_render_navigator(this.target);
function checkNav(selector, content) {
var nodelist = Y.all(selector);
nodelist.each(function (node) {
- if (node.get('id') != 'notme') {
+ if (node.get('id') !== 'notme') {
Y.Assert.areEqual('a',
node.get('tagName').toLowerCase());
Y.Assert.areEqual(content, node.getContent());
@@ -234,7 +236,6 @@
this.target = Y.Node.create('<div></div>').set(
'id', 'client-listing');
Y.one('body').appendChild(this.target);
- console.log('setup', Y.config.win.history.state);
Y.config.win.history.state = {};
},
=== modified file 'lib/lp/bugs/javascript/buglisting.js'
--- lib/lp/bugs/javascript/buglisting.js 2012-07-24 16:06:11 +0000
+++ lib/lp/bugs/javascript/buglisting.js 2012-09-12 02:03:23 +0000
@@ -161,12 +161,12 @@
var navigation_indices = Y.all('.batch-navigation-index');
var pre_fetch = Y.lp.app.listing_navigator.get_feature_flag(
'bugs.dynamic_bug_listings.pre_fetch');
- Y.lp.app.listing_navigator.linkify_navigation(container);
var navigator = new module.BugListingNavigator({
current_url: window.location,
cache: LP.cache,
template: LP.mustache_listings,
target: target,
+ container: container,
navigation_indices: navigation_indices,
pre_fetch: Boolean(pre_fetch)
});
=== modified file 'lib/lp/registry/javascript/sharing/granteetable.js'
--- lib/lp/registry/javascript/sharing/granteetable.js 2012-09-06 14:42:26 +0000
+++ lib/lp/registry/javascript/sharing/granteetable.js 2012-09-12 02:03:23 +0000
@@ -110,7 +110,6 @@
var target = Y.one('#grantee-table');
var container = target.get('parentNode');
var navigation_indices = Y.all('.batch-navigation-index');
- Y.lp.app.listing_navigator.linkify_navigation(target);
var ns = Y.lp.registry.sharing.granteelisting_navigator;
var cache = LP.cache;
cache.total = this.get('grantees').length;
@@ -118,6 +117,7 @@
current_url: window.location,
cache: cache,
target: target,
+ container: container,
navigation_indices: navigation_indices,
batch_info_template: '<div></div>'
});
Follow ups