preserve filters on ajax SERP (bug 695659)
This commit is contained in:
Родитель
21d3e6459e
Коммит
58a3e66e96
|
@ -40,7 +40,8 @@
|
|||
<ul class="facet-group">
|
||||
{% for link in links recursive %}
|
||||
<li{% if link.selected %} class="selected"{% endif %}>
|
||||
<a href="{{ request.get_full_path()|urlparams(page=None, **link.urlparams) }}">
|
||||
<a href="{{ request.get_full_path()|urlparams(page=None, **link.urlparams) }}"
|
||||
data-params="{{ link.urlparams|json }}">
|
||||
{{ link.text }}</a>
|
||||
{% if link.children %}
|
||||
<ul>{{ loop(link.children) }}</ul>
|
||||
|
|
|
@ -20,16 +20,27 @@ $(function() {
|
|||
if ($this.html() != newCount.html()) {
|
||||
$this.replaceWith(newCount);
|
||||
}
|
||||
}).delegate('a[data-params]', 'rebuild', function(e) {
|
||||
var $this = $(this),
|
||||
url = rebuildLink($this.attr('href'), $this.attr('data-params'));
|
||||
$this.attr('href', url);
|
||||
});
|
||||
|
||||
if ($('body').hasClass('pjax') && $.support.pjax) {
|
||||
initSearchPjax('#pjax-results');
|
||||
if ($('body').hasClass('pjax') && $.support.pjax && z.capabilities.JSON) {
|
||||
$('#pjax-results').initSearchPjax($('#search-facets'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function initSearchPjax(container) {
|
||||
var $container = $(container),
|
||||
function rebuildLink(url, urlparams, qs) {
|
||||
var params = JSON.parseNonNull(urlparams),
|
||||
newVars = $.extend(z.getVars(qs), params);
|
||||
return url.split('?')[0] + '?' + $.param(newVars);
|
||||
}
|
||||
|
||||
|
||||
$.fn.initSearchPjax = function($filters) {
|
||||
var $container = $(this),
|
||||
container = $container.selector,
|
||||
timeouts = 0;
|
||||
|
||||
function pjaxOpen(url) {
|
||||
|
@ -72,6 +83,8 @@ function initSearchPjax(container) {
|
|||
|
||||
// Insert the loading throbber.
|
||||
$('<div>', {'class': cls, 'html': msg}).insertBefore($container);
|
||||
|
||||
$container.trigger('search.loading');
|
||||
}
|
||||
|
||||
function finished() {
|
||||
|
@ -84,14 +97,19 @@ function initSearchPjax(container) {
|
|||
initListingCompat();
|
||||
});
|
||||
|
||||
// Remove the loading indicator.
|
||||
// Remove the loading throbber.
|
||||
$wrapper.removeClass('loading').find('.updating').remove();
|
||||
|
||||
// Update the # of matching results on sidebar.
|
||||
$('#search-facets .cnt').trigger('recount', [$wrapper.find('.cnt')]);
|
||||
$filters.find('.cnt').trigger('recount', [$wrapper.find('.cnt')]);
|
||||
|
||||
// Scroll up.
|
||||
// Update GET parameters of sidebar anchors.
|
||||
$filters.find('a[data-params]').trigger('rebuild');
|
||||
|
||||
// Scroll up to top of page.
|
||||
$('html, body').animate({scrollTop: 0}, 200);
|
||||
|
||||
$container.trigger('search.finished');
|
||||
}
|
||||
|
||||
function turnPages(e) {
|
||||
|
@ -113,4 +131,4 @@ function initSearchPjax(container) {
|
|||
$('.pjax-trigger a').live('click', _pd(hijackLink));
|
||||
$container.bind('start.pjax', loading).bind('end.pjax', finished);
|
||||
$(document).keyup(_.throttle(turnPages, 300));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
z.getVars = function(qs) {
|
||||
if (typeof qs === 'undefined') {
|
||||
qs = location.search;
|
||||
}
|
||||
var vars = {};
|
||||
if (qs.length > 1) {
|
||||
var items = qs.substr(1).split('&'),
|
||||
item;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
item = items[i].split('=');
|
||||
if (!!item[1]) {
|
||||
vars[escape_(unescape(item[0]))] = escape_(unescape(item[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
|
||||
JSON.parseNonNull = function(text) {
|
||||
return JSON.parse(text, function(key, value) {
|
||||
if (typeof value === 'object' && value === null) {
|
||||
return '';
|
||||
}
|
||||
return value;
|
||||
});
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
module('Pjax Search', {
|
||||
setup: function() {
|
||||
this.container = $('#pjax-results', this.sandbox);
|
||||
this.filters = $('#search-facets', this.sandbox);
|
||||
this.container.initSearchPjax(this.filters);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test('Loading', function() {
|
||||
var loaded = false;
|
||||
this.container.bind('search.loading', function() {
|
||||
loaded = true;
|
||||
});
|
||||
$.when(this.container.trigger('start.pjax')).done(function() {
|
||||
ok(loaded);
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
test('Finished', function() {
|
||||
var finished = false;
|
||||
this.container.bind('search.finished', function() {
|
||||
finished = true;
|
||||
});
|
||||
$.when(this.container.trigger('end.pjax')).done(function() {
|
||||
ok(finished);
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
test('Rebuild links', function() {
|
||||
function check(s, expected) {
|
||||
// rebuildLink accepts the following parameters:
|
||||
// 1) previous target URL,
|
||||
// 2) fixed URL params,
|
||||
// 3) new query string (i.e, location.search)
|
||||
equal(rebuildLink(s[0], s[1], s[2]), expected);
|
||||
}
|
||||
|
||||
// We're showing results for Macs, so the filter URLs should get updated
|
||||
// to reflect that.
|
||||
check(['/en-US/firefox/search/?q=adblock&appver=10.0',
|
||||
'{"appver": "10.0"}',
|
||||
'?q=adblock&platform=mac'],
|
||||
'/en-US/firefox/search/?q=adblock&platform=mac&appver=10.0');
|
||||
|
||||
// We're showing results filtered by cat 14, so the filter URL for cat 72
|
||||
// should not change values.
|
||||
check(['/en-US/firefox/search/?q=adblock&appver=8.0&cat=72&atype=1',
|
||||
'{"atype": 1, "cat": 72}',
|
||||
'?q=adblock&cat=14&atype=1'],
|
||||
'/en-US/firefox/search/?q=adblock&cat=72&atype=1');
|
||||
|
||||
// We're showing results filtered by cat 14, so the filter URL to show
|
||||
// all categories/types should not contain cat=14.
|
||||
check(['/en-US/firefox/search/?q=adblock',
|
||||
'{"atype": null, "cat": null}',
|
||||
'?q=adblock&cat=14'],
|
||||
'/en-US/firefox/search/?q=adblock&cat=&atype=');
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
module('Serializers');
|
||||
|
||||
|
||||
test('getVars', function() {
|
||||
function check(s, expected) {
|
||||
tests.equalObjects(z.getVars(s), expected);
|
||||
}
|
||||
check('', {});
|
||||
check('?', {});
|
||||
check('?a', {});
|
||||
check('?==a', {});
|
||||
check('?a=apple&a=apricot', {'a': 'apricot'});
|
||||
check('?a=apple&b=banana&c=carrot',
|
||||
{'a': 'apple', 'b': 'banana', 'c': 'carrot'});
|
||||
check('?a?a=apple', {'a?a': 'apple'});
|
||||
check('?a=apple&b?c=banana', {'a': 'apple', 'b?c': 'banana'});
|
||||
check('?a=b=c&d=e', {'a': 'b', 'd': 'e'});
|
||||
check('?<script>alert("xss")</script>="a"',
|
||||
{'<script>alert("xss")</script>': '"a"'});
|
||||
check('?"a"=<script>alert("xss")</script>',
|
||||
{'"a"': '<script>alert("xss")</script>'});
|
||||
});
|
||||
|
||||
|
||||
test('JSON.parseNonNull', function() {
|
||||
function check(s, expected) {
|
||||
tests.equalObjects(JSON.parseNonNull(s), JSON.parse(expected));
|
||||
}
|
||||
check('[]', '[]');
|
||||
check('{}', '{}');
|
||||
check('{"x": "xxx", "y": "yyy"}',
|
||||
'{"x": "xxx", "y": "yyy"}');
|
||||
check('{"x": "null", "y": null}',
|
||||
'{"x": "null", "y": ""}');
|
||||
check('[{"x": "null", "y": null}, {"x": "null", "y": null}]',
|
||||
'[{"x": "null", "y": ""}, {"x": "null", "y": ""}]');
|
||||
check('[{"w": {"x": null, "y": {"z": null}}}]',
|
||||
'[{"w": {"x": "", "y": {"z": ""}}}]');
|
||||
});
|
|
@ -3,21 +3,11 @@
|
|||
"extra_media_urls": [
|
||||
"js/lib/jstestnet.js",
|
||||
"js/zamboni/tests.js",
|
||||
"js/zamboni/buttons.js",
|
||||
"js/impala/global.js",
|
||||
"js/zamboni/devhub.js",
|
||||
"js/zamboni/validator.js",
|
||||
"js/zamboni/l10n.js",
|
||||
"js/zamboni/truncation.js",
|
||||
"js/zamboni/storage.js",
|
||||
"js/zamboni/editors.js",
|
||||
"js/zamboni/upload.js",
|
||||
"js/zamboni/files.js",
|
||||
"js/zamboni/contributions.js",
|
||||
"js/zamboni/password-strength.js",
|
||||
"js/impala/persona_creation.js",
|
||||
"js/zamboni/browserid_support.js",
|
||||
"js/impala/ajaxcache.js",
|
||||
"js/impala/search.js"
|
||||
"js/zamboni/browserid_support.js"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -662,6 +662,7 @@ MINIFY_BUNDLES = {
|
|||
'js/impala/users.js',
|
||||
|
||||
# Search
|
||||
'js/impala/serializers.js',
|
||||
'js/impala/search.js',
|
||||
'js/impala/suggestions.js',
|
||||
|
||||
|
|
|
@ -201,4 +201,11 @@
|
|||
</form>
|
||||
</div>
|
||||
|
||||
<div id="pjax-search">
|
||||
<div id="search-facets">
|
||||
<ul class="facets island pjax-trigger"></ul>
|
||||
</div>
|
||||
<div id="pjax-results"></div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
Загрузка…
Ссылка в новой задаче