forked from cowboy/jquery-bbq
-
Notifications
You must be signed in to change notification settings - Fork 1
/
jquery.bbq.pjax.js
121 lines (100 loc) · 3.81 KB
/
jquery.bbq.pjax.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
(function($, undefined){
var cache = {}
var rootUrlPlaceholder = '__root__'
var $container = $currentPage = options = null
var $pjaxWrapTemplate = $('<div class="pjax-page" />')
$.fn.bbq_pjax = function(options){
options = $.extend({
linkSelector: 'a',
transition: function($from, $to) {
$from.hide()
$to.show()
}
}, options)
// We assume that the initial content is current when pushState is available,
// but that we still need to load the initial content if we're using the fallback.
if ($.support.pushState) {
var lastURL = currentUrl()
} else {
// Unless we're at the root
var lastURL = rootUrlPlaceholder
}
// We should only use the first matched element as the content container.
this.each(function(){
$container = $(this)
// Set up the initial pjax-page content.
var $pjaxPage = $pjaxWrapTemplate.clone()
$pjaxPage.append($container.children()).appendTo($container)
$pjaxPage.data('pjax-title', document.title)
$currentPage = cache[lastURL] = $pjaxPage
$(options.linkSelector).live('click', function(event){
$link = $(this)
// Get the url from the link's href attribute, stripping any leading #.
$.bbq.pushState( $link.attr( 'href' ).replace( /^#/, '' ), 2 )
// Prevent the default link click behavior.
return false
})
})
// Bind an event to window.onhashchange
$(window).bind( 'hashchange', function(e) {
var url = currentUrl()
if (url === lastURL) { return }
lastURL = url;
var rel_url = rootRelativeUrl(url)
//
if (cache[rel_url]) {
transition(cache[rel_url])
} else {
$container.addClass('pjax-loading')
cache[rel_url] = $pjaxWrapTemplate.clone().data('pjax-url', rel_url)
var delim = url.indexOf('?') == -1 ? '?' : '&'
cache[rel_url].load(url+delim+'_pjax=true', function(){
$(this).find('meta').remove()
$(this).data('pjax-title', $.trim( $(this).find('title').remove().text() ))
$(this).hide().appendTo($container)
transition(cache[rel_url])
$container.removeClass('pjax-loading')
})
}
})
var transition = function($to){
// Make some guesses about the direction we're navigating by inspecting the URLs.
var dir = 'same'
var initialDepth = initialUrl.replace(/\/$/, '').split('/').length
var fromDepth = $currentPage.data('pjax-url') ? $currentPage.data('pjax-url').replace(/\/$/, '').split('/').length : initialDepth
var toDepth = $to.data('pjax-url') ? $to.data('pjax-url').replace(/\/$/, '').split('/').length : initialDepth
if (fromDepth > toDepth) {
dir = 'up'
} else if (fromDepth < toDepth) {
dir = 'down'
}
options.transition($currentPage, $to, dir)
$currentPage = $to
}
// Since the event is only triggered when the hash changes, we need to trigger
// the event now, to handle the hash the page may have loaded with.
$(window).trigger( 'hashchange' );
}
var rootRelativeUrl = function(url){
var l = window.location
if (url == rootUrlPlaceholder) {
return url
} else if (url.indexOf('http') === 0) {
return url.replace(/^(?:\/\/|[^\/]+)*\//, '/')
} else if (url.indexOf('/') === 0) {
return url
} else {
var path = l.pathname.split('/')
path.pop()
path.push(url)
return path.join('/')
}
}
var currentUrl = function(){
var url = ($.support.pushState)
? window.location.href.replace(/^(?:\/\/|[^\/]+)*\//, '/')
: window.location.hash.replace(/^#/, '')
return url != '' ? url : rootUrlPlaceholder
}
var initialUrl = rootRelativeUrl(window.location.href)
})(jQuery)