pjax_rails 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/pjax.rb +2 -2
- data/lib/pjax_rails.rb +5 -3
- data/vendor/assets/javascripts/jquery.pjax.js +131 -32
- metadata +86 -16
- data/lib/assets/javascripts/pjax.js +0 -5
- data/lib/assets/javascripts/pjax/enable_pjax.js +0 -7
- data/lib/assets/javascripts/pjax/page_triggers.js +0 -18
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 097fb0fd95fb00440599199ed502f5c2a25267e7
|
4
|
+
data.tar.gz: eb7d75f29172e733146484d404c436a692c5c8e8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c4dde951c62dbff0cc9b0d9b7628a6a09e8d8c06ea8b1f0cdde2b8f1f01af7ff9dd619a1b29c7c737517441fefd4accab2e6f7d3478e1d41effa7799f00b0494
|
7
|
+
data.tar.gz: 0e810bd47708b355702028630a96c91a722548768fc9f9693d11088c2ae9ca80741981af24821cfa0c697dde7c29f912e7068e35eaf716f9019dd662d4dc2354
|
data/lib/pjax.rb
CHANGED
@@ -2,7 +2,7 @@ module Pjax
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
included do
|
5
|
-
layout proc { |c| pjax_request? ? pjax_layout :
|
5
|
+
layout proc { |c| pjax_request? ? pjax_layout : nil }
|
6
6
|
helper_method :pjax_request?
|
7
7
|
|
8
8
|
rescue_from Pjax::Unsupported, :with => :pjax_unsupported
|
@@ -16,7 +16,7 @@ module Pjax
|
|
16
16
|
|
17
17
|
protected
|
18
18
|
def pjax_request?
|
19
|
-
env['HTTP_X_PJAX'].present?
|
19
|
+
request.env['HTTP_X_PJAX'].present?
|
20
20
|
end
|
21
21
|
|
22
22
|
def pjax_layout
|
data/lib/pjax_rails.rb
CHANGED
@@ -2,8 +2,10 @@ require 'pjax'
|
|
2
2
|
|
3
3
|
module PjaxRails
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
-
initializer
|
6
|
-
|
5
|
+
initializer 'pjax_rails.add_controller' do
|
6
|
+
ActiveSupport.on_load :action_controller do
|
7
|
+
ActionController::Base.send :include, Pjax
|
8
|
+
end
|
7
9
|
end
|
8
10
|
end
|
9
|
-
end
|
11
|
+
end
|
@@ -70,7 +70,7 @@ function handleClick(event, container, options) {
|
|
70
70
|
return
|
71
71
|
|
72
72
|
// Ignore cross origin links
|
73
|
-
if ( location.protocol !== link.protocol || location.
|
73
|
+
if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
|
74
74
|
return
|
75
75
|
|
76
76
|
// Ignore anchors on the same page
|
@@ -85,13 +85,17 @@ function handleClick(event, container, options) {
|
|
85
85
|
var defaults = {
|
86
86
|
url: link.href,
|
87
87
|
container: $(link).attr('data-pjax'),
|
88
|
-
target: link
|
89
|
-
fragment: null
|
88
|
+
target: link
|
90
89
|
}
|
91
90
|
|
92
|
-
|
91
|
+
var opts = $.extend({}, defaults, options)
|
92
|
+
var clickEvent = $.Event('pjax:click')
|
93
|
+
$(link).trigger(clickEvent, [opts])
|
93
94
|
|
94
|
-
|
95
|
+
if (!clickEvent.isDefaultPrevented()) {
|
96
|
+
pjax(opts)
|
97
|
+
event.preventDefault()
|
98
|
+
}
|
95
99
|
}
|
96
100
|
|
97
101
|
// Public: pjax on form submit handler
|
@@ -118,13 +122,11 @@ function handleSubmit(event, container, options) {
|
|
118
122
|
throw "$.pjax.submit requires a form element"
|
119
123
|
|
120
124
|
var defaults = {
|
121
|
-
type: form.method,
|
125
|
+
type: form.method.toUpperCase(),
|
122
126
|
url: form.action,
|
123
127
|
data: $(form).serializeArray(),
|
124
128
|
container: $(form).attr('data-pjax'),
|
125
|
-
target: form
|
126
|
-
fragment: null,
|
127
|
-
timeout: 0
|
129
|
+
target: form
|
128
130
|
}
|
129
131
|
|
130
132
|
pjax($.extend({}, defaults, options))
|
@@ -186,6 +188,12 @@ function pjax(options) {
|
|
186
188
|
settings.timeout = 0
|
187
189
|
}
|
188
190
|
|
191
|
+
xhr.setRequestHeader('X-PJAX', 'true')
|
192
|
+
xhr.setRequestHeader('X-PJAX-Container', context.selector)
|
193
|
+
|
194
|
+
if (!fire('pjax:beforeSend', [xhr, settings]))
|
195
|
+
return false
|
196
|
+
|
189
197
|
if (settings.timeout > 0) {
|
190
198
|
timeoutTimer = setTimeout(function() {
|
191
199
|
if (fire('pjax:timeout', [xhr, options]))
|
@@ -196,14 +204,6 @@ function pjax(options) {
|
|
196
204
|
settings.timeout = 0
|
197
205
|
}
|
198
206
|
|
199
|
-
xhr.setRequestHeader('X-PJAX', 'true')
|
200
|
-
xhr.setRequestHeader('X-PJAX-Container', context.selector)
|
201
|
-
|
202
|
-
var result
|
203
|
-
|
204
|
-
if (!fire('pjax:beforeSend', [xhr, settings]))
|
205
|
-
return false
|
206
|
-
|
207
207
|
options.requestUrl = parseURL(settings.url).href
|
208
208
|
}
|
209
209
|
|
@@ -226,8 +226,23 @@ function pjax(options) {
|
|
226
226
|
}
|
227
227
|
|
228
228
|
options.success = function(data, status, xhr) {
|
229
|
+
// If $.pjax.defaults.version is a function, invoke it first.
|
230
|
+
// Otherwise it can be a static string.
|
231
|
+
var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
|
232
|
+
$.pjax.defaults.version() :
|
233
|
+
$.pjax.defaults.version
|
234
|
+
|
235
|
+
var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
|
236
|
+
|
229
237
|
var container = extractContainer(data, xhr, options)
|
230
238
|
|
239
|
+
// If there is a layout version mismatch, hard load the new url
|
240
|
+
if (currentVersion && latestVersion && currentVersion !== latestVersion) {
|
241
|
+
locationReplace(container.url)
|
242
|
+
return
|
243
|
+
}
|
244
|
+
|
245
|
+
// If the new response is missing a body, hard load the page
|
231
246
|
if (!container.contents) {
|
232
247
|
locationReplace(container.url)
|
233
248
|
return
|
@@ -246,17 +261,28 @@ function pjax(options) {
|
|
246
261
|
window.history.replaceState(pjax.state, container.title, container.url)
|
247
262
|
}
|
248
263
|
|
264
|
+
// Clear out any focused controls before inserting new page contents.
|
265
|
+
document.activeElement.blur()
|
266
|
+
|
249
267
|
if (container.title) document.title = container.title
|
250
268
|
context.html(container.contents)
|
251
269
|
|
270
|
+
// FF bug: Won't autofocus fields that are inserted via JS.
|
271
|
+
// This behavior is incorrect. So if theres no current focus, autofocus
|
272
|
+
// the last field.
|
273
|
+
//
|
274
|
+
// http://www.w3.org/html/wg/drafts/html/master/forms.html
|
275
|
+
var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
|
276
|
+
if (autofocusEl && document.activeElement !== autofocusEl) {
|
277
|
+
autofocusEl.focus();
|
278
|
+
}
|
279
|
+
|
280
|
+
executeScriptTags(container.scripts)
|
281
|
+
|
252
282
|
// Scroll to top by default
|
253
283
|
if (typeof options.scrollTo === 'number')
|
254
284
|
$(window).scrollTop(options.scrollTo)
|
255
285
|
|
256
|
-
// Google Analytics support
|
257
|
-
if ( (options.replace || options.push) && window._gaq )
|
258
|
-
_gaq.push(['_trackPageview'])
|
259
|
-
|
260
286
|
// If the URL has a hash in it, make sure the browser
|
261
287
|
// knows to navigate to the hash.
|
262
288
|
if ( hash !== '' ) {
|
@@ -345,6 +371,23 @@ function locationReplace(url) {
|
|
345
371
|
window.location.replace(url)
|
346
372
|
}
|
347
373
|
|
374
|
+
|
375
|
+
var initialPop = true
|
376
|
+
var initialURL = window.location.href
|
377
|
+
var initialState = window.history.state
|
378
|
+
|
379
|
+
// Initialize $.pjax.state if possible
|
380
|
+
// Happens when reloading a page and coming forward from a different
|
381
|
+
// session history.
|
382
|
+
if (initialState && initialState.container) {
|
383
|
+
pjax.state = initialState
|
384
|
+
}
|
385
|
+
|
386
|
+
// Non-webkit browsers don't fire an initial popstate event
|
387
|
+
if ('state' in window.history) {
|
388
|
+
initialPop = false
|
389
|
+
}
|
390
|
+
|
348
391
|
// popstate handler takes care of the back and forward buttons
|
349
392
|
//
|
350
393
|
// You probably shouldn't use pjax on pages with other pushState
|
@@ -353,14 +396,23 @@ function onPjaxPopstate(event) {
|
|
353
396
|
var state = event.state
|
354
397
|
|
355
398
|
if (state && state.container) {
|
399
|
+
// When coming forward from a separate history session, will get an
|
400
|
+
// initial pop with a state we are already at. Skip reloading the current
|
401
|
+
// page.
|
402
|
+
if (initialPop && initialURL == state.url) return
|
403
|
+
|
404
|
+
// If popping back to the same state, just skip.
|
405
|
+
// Could be clicking back from hashchange rather than a pushState.
|
406
|
+
if (pjax.state.id === state.id) return
|
407
|
+
|
356
408
|
var container = $(state.container)
|
357
409
|
if (container.length) {
|
358
|
-
var contents = cacheMapping[state.id]
|
410
|
+
var direction, contents = cacheMapping[state.id]
|
359
411
|
|
360
412
|
if (pjax.state) {
|
361
413
|
// Since state ids always increase, we can deduce the history
|
362
414
|
// direction from the previous state.
|
363
|
-
|
415
|
+
direction = pjax.state.id < state.id ? 'forward' : 'back'
|
364
416
|
|
365
417
|
// Cache current container before replacement and inform the
|
366
418
|
// cache which direction the history shifted.
|
@@ -402,6 +454,7 @@ function onPjaxPopstate(event) {
|
|
402
454
|
locationReplace(location.href)
|
403
455
|
}
|
404
456
|
}
|
457
|
+
initialPop = false
|
405
458
|
}
|
406
459
|
|
407
460
|
// Fallback version of main pjax function for browsers that don't
|
@@ -546,6 +599,10 @@ function findAll(elems, selector) {
|
|
546
599
|
return elems.filter(selector).add(elems.find(selector));
|
547
600
|
}
|
548
601
|
|
602
|
+
function parseHTML(html) {
|
603
|
+
return $.parseHTML(html, document, true)
|
604
|
+
}
|
605
|
+
|
549
606
|
// Internal: Extracts container and metadata from response.
|
550
607
|
//
|
551
608
|
// 1. Extracts X-PJAX-URL header if set
|
@@ -566,10 +623,10 @@ function extractContainer(data, xhr, options) {
|
|
566
623
|
|
567
624
|
// Attempt to parse response html into elements
|
568
625
|
if (/<html/i.test(data)) {
|
569
|
-
var $head = $(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0])
|
570
|
-
var $body = $(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0])
|
626
|
+
var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
|
627
|
+
var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
|
571
628
|
} else {
|
572
|
-
var $head = $body = $(data)
|
629
|
+
var $head = $body = $(parseHTML(data))
|
573
630
|
}
|
574
631
|
|
575
632
|
// If response data is empty, return fast
|
@@ -605,10 +662,14 @@ function extractContainer(data, xhr, options) {
|
|
605
662
|
// Clean up any <title> tags
|
606
663
|
if (obj.contents) {
|
607
664
|
// Remove any parent title elements
|
608
|
-
obj.contents = obj.contents.not('title')
|
665
|
+
obj.contents = obj.contents.not(function() { return $(this).is('title') })
|
609
666
|
|
610
|
-
// Then scrub any titles from their
|
667
|
+
// Then scrub any titles from their descendants
|
611
668
|
obj.contents.find('title').remove()
|
669
|
+
|
670
|
+
// Gather all script[src] elements
|
671
|
+
obj.scripts = findAll(obj.contents, 'script[src]').remove()
|
672
|
+
obj.contents = obj.contents.not(obj.scripts)
|
612
673
|
}
|
613
674
|
|
614
675
|
// Trim any whitespace off the title
|
@@ -617,6 +678,33 @@ function extractContainer(data, xhr, options) {
|
|
617
678
|
return obj
|
618
679
|
}
|
619
680
|
|
681
|
+
// Load an execute scripts using standard script request.
|
682
|
+
//
|
683
|
+
// Avoids jQuery's traditional $.getScript which does a XHR request and
|
684
|
+
// globalEval.
|
685
|
+
//
|
686
|
+
// scripts - jQuery object of script Elements
|
687
|
+
//
|
688
|
+
// Returns nothing.
|
689
|
+
function executeScriptTags(scripts) {
|
690
|
+
if (!scripts) return
|
691
|
+
|
692
|
+
var existingScripts = $('script[src]')
|
693
|
+
|
694
|
+
scripts.each(function() {
|
695
|
+
var src = this.src
|
696
|
+
var matchedScripts = existingScripts.filter(function() {
|
697
|
+
return this.src === src
|
698
|
+
})
|
699
|
+
if (matchedScripts.length) return
|
700
|
+
|
701
|
+
var script = document.createElement('script')
|
702
|
+
script.type = $(this).attr('type')
|
703
|
+
script.src = $(this).attr('src')
|
704
|
+
document.head.appendChild(script)
|
705
|
+
})
|
706
|
+
}
|
707
|
+
|
620
708
|
// Internal: History DOM caching class.
|
621
709
|
var cacheMapping = {}
|
622
710
|
var cacheForwardStack = []
|
@@ -670,6 +758,16 @@ function cachePop(direction, id, value) {
|
|
670
758
|
delete cacheMapping[id]
|
671
759
|
}
|
672
760
|
|
761
|
+
// Public: Find version identifier for the initial page load.
|
762
|
+
//
|
763
|
+
// Returns String version or undefined.
|
764
|
+
function findVersion() {
|
765
|
+
return $('meta').filter(function() {
|
766
|
+
var name = $(this).attr('http-equiv')
|
767
|
+
return name && name.toUpperCase() === 'X-PJAX-VERSION'
|
768
|
+
}).attr('content')
|
769
|
+
}
|
770
|
+
|
673
771
|
// Install pjax functions on $.pjax to enable pushState behavior.
|
674
772
|
//
|
675
773
|
// Does nothing if already enabled.
|
@@ -694,9 +792,10 @@ function enable() {
|
|
694
792
|
type: 'GET',
|
695
793
|
dataType: 'html',
|
696
794
|
scrollTo: 0,
|
697
|
-
maxCacheLength: 20
|
795
|
+
maxCacheLength: 20,
|
796
|
+
version: findVersion
|
698
797
|
}
|
699
|
-
$(window).
|
798
|
+
$(window).on('popstate.pjax', onPjaxPopstate)
|
700
799
|
}
|
701
800
|
|
702
801
|
// Disable pushState behavior.
|
@@ -719,7 +818,7 @@ function disable() {
|
|
719
818
|
$.pjax.submit = $.noop
|
720
819
|
$.pjax.reload = function() { window.location.reload() }
|
721
820
|
|
722
|
-
$(window).
|
821
|
+
$(window).off('popstate.pjax', onPjaxPopstate)
|
723
822
|
}
|
724
823
|
|
725
824
|
|
@@ -728,7 +827,7 @@ function disable() {
|
|
728
827
|
if ( $.inArray('state', $.event.props) < 0 )
|
729
828
|
$.event.props.push('state')
|
730
829
|
|
731
|
-
|
830
|
+
// Is pjax supported by this browser?
|
732
831
|
$.support.pjax =
|
733
832
|
window.history && window.history.pushState && window.history.replaceState &&
|
734
833
|
// pushState isn't reliable on iOS until 5.
|
metadata
CHANGED
@@ -1,30 +1,103 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pjax_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- David Heinemeier Hansson (PJAX by Chris Wanstrath)
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-12-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: railties
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
- - <
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.2'
|
30
|
+
- - <
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.0'
|
14
33
|
- !ruby/object:Gem::Dependency
|
15
34
|
name: jquery-rails
|
16
35
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
36
|
requirements:
|
19
|
-
- -
|
37
|
+
- - '>='
|
20
38
|
- !ruby/object:Gem::Version
|
21
39
|
version: '0'
|
22
40
|
type: :runtime
|
23
41
|
prerelease: false
|
24
42
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
43
|
requirements:
|
27
|
-
- -
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rails
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: capybara
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: poltergeist
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '>='
|
28
101
|
- !ruby/object:Gem::Version
|
29
102
|
version: '0'
|
30
103
|
description:
|
@@ -35,32 +108,29 @@ extra_rdoc_files: []
|
|
35
108
|
files:
|
36
109
|
- lib/pjax.rb
|
37
110
|
- lib/pjax_rails.rb
|
38
|
-
- lib/assets/javascripts/pjax/enable_pjax.js
|
39
|
-
- lib/assets/javascripts/pjax/page_triggers.js
|
40
|
-
- lib/assets/javascripts/pjax.js
|
41
111
|
- vendor/assets/javascripts/jquery.pjax.js
|
42
112
|
homepage:
|
43
113
|
licenses: []
|
114
|
+
metadata: {}
|
44
115
|
post_install_message:
|
45
116
|
rdoc_options: []
|
46
117
|
require_paths:
|
47
118
|
- lib
|
48
119
|
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
120
|
requirements:
|
51
|
-
- -
|
121
|
+
- - '>='
|
52
122
|
- !ruby/object:Gem::Version
|
53
123
|
version: '0'
|
54
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
56
125
|
requirements:
|
57
|
-
- -
|
126
|
+
- - '>='
|
58
127
|
- !ruby/object:Gem::Version
|
59
128
|
version: '0'
|
60
129
|
requirements: []
|
61
130
|
rubyforge_project:
|
62
|
-
rubygems_version: 1.
|
131
|
+
rubygems_version: 2.1.11
|
63
132
|
signing_key:
|
64
|
-
specification_version:
|
133
|
+
specification_version: 4
|
65
134
|
summary: PJAX integration for Rails 3.1+
|
66
135
|
test_files: []
|
136
|
+
has_rdoc:
|
@@ -1,18 +0,0 @@
|
|
1
|
-
// DEPRECATED: Move these events into your application if you want to
|
2
|
-
// continue using them.
|
3
|
-
//
|
4
|
-
// This file will be removed in 0.3.
|
5
|
-
|
6
|
-
$(document).ready(function() {
|
7
|
-
$(document).trigger('pageChanged');
|
8
|
-
$(document).trigger('pageUpdated');
|
9
|
-
});
|
10
|
-
|
11
|
-
$(document).bind('pjax:end', function() {
|
12
|
-
$(document).trigger('pageChanged');
|
13
|
-
$(document).trigger('pageUpdated');
|
14
|
-
});
|
15
|
-
|
16
|
-
$(document).bind('ajaxComplete', function() {
|
17
|
-
$(document).trigger('pageUpdated');
|
18
|
-
});
|