rails-pjax 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +4 -4
- data/pjax_rails.gemspec +1 -1
- data/rails-pjax-0.0.1.gem +0 -0
- data/vendor/assets/javascripts/jquery.pjax.js +89 -298
- metadata +4 -3
data/README.md
CHANGED
@@ -29,7 +29,7 @@ The PJAX container has to be marked with data-pjax-container attribute, so for e
|
|
29
29
|
|
30
30
|
FIXME: Currently the layout is hardcoded to "application". Need to delegate that to the specific layout of the controller.
|
31
31
|
|
32
|
-
Examples for
|
32
|
+
Examples for redirect_pjax_to
|
33
33
|
-----------------------------
|
34
34
|
|
35
35
|
class ProjectsController < ApplicationController
|
@@ -44,19 +44,19 @@ Examples for redirect_to
|
|
44
44
|
|
45
45
|
def create
|
46
46
|
@project = Project.create params[:project]
|
47
|
-
|
47
|
+
redirect_pjax_to :show, @project
|
48
48
|
end
|
49
49
|
|
50
50
|
def update
|
51
51
|
@project.update_attributes params[:project]
|
52
|
-
|
52
|
+
redirect_pjax_to :show, @project
|
53
53
|
end
|
54
54
|
|
55
55
|
def destroy
|
56
56
|
@project.destroy
|
57
57
|
|
58
58
|
index # set the objects needed for rendering index
|
59
|
-
|
59
|
+
redirect_pjax_to :index
|
60
60
|
end
|
61
61
|
|
62
62
|
private
|
data/pjax_rails.gemspec
CHANGED
Binary file
|
@@ -24,8 +24,8 @@
|
|
24
24
|
//
|
25
25
|
// Returns the jQuery object
|
26
26
|
$.fn.pjax = function( container, options ) {
|
27
|
-
return this.live('click
|
28
|
-
handleClick(event, container, options)
|
27
|
+
return this.live('click', function(event){
|
28
|
+
return handleClick(event, container, options)
|
29
29
|
})
|
30
30
|
}
|
31
31
|
|
@@ -53,11 +53,7 @@ function handleClick(event, container, options) {
|
|
53
53
|
|
54
54
|
var link = event.currentTarget
|
55
55
|
|
56
|
-
// If current target isnt a link, try to find the first A descendant
|
57
56
|
if (link.tagName.toUpperCase() !== 'A')
|
58
|
-
link = $(link).find('a')[0]
|
59
|
-
|
60
|
-
if (!link)
|
61
57
|
throw "$.fn.pjax or $.pjax.click requires an anchor element"
|
62
58
|
|
63
59
|
// Middle click, cmd click, and ctrl click should open
|
@@ -85,6 +81,30 @@ function handleClick(event, container, options) {
|
|
85
81
|
$.pjax($.extend({}, defaults, options))
|
86
82
|
|
87
83
|
event.preventDefault()
|
84
|
+
return false
|
85
|
+
}
|
86
|
+
|
87
|
+
// Internal: Strips _pjax param from url
|
88
|
+
//
|
89
|
+
// url - String
|
90
|
+
//
|
91
|
+
// Returns String.
|
92
|
+
function stripPjaxParam(url) {
|
93
|
+
return url
|
94
|
+
.replace(/\?_pjax=[^&]+&?/, '?')
|
95
|
+
.replace(/_pjax=[^&]+&?/, '')
|
96
|
+
.replace(/[\?&]$/, '')
|
97
|
+
}
|
98
|
+
|
99
|
+
// Internal: Parse URL components and returns a Locationish object.
|
100
|
+
//
|
101
|
+
// url - String URL
|
102
|
+
//
|
103
|
+
// Returns HTMLAnchorElement that acts like Location.
|
104
|
+
function parseURL(url) {
|
105
|
+
var a = document.createElement('a')
|
106
|
+
a.href = url
|
107
|
+
return a
|
88
108
|
}
|
89
109
|
|
90
110
|
|
@@ -119,7 +139,8 @@ var pjax = $.pjax = function( options ) {
|
|
119
139
|
// DEPRECATED: use options.target
|
120
140
|
if (!target && options.clickedElement) target = options.clickedElement[0]
|
121
141
|
|
122
|
-
var
|
142
|
+
var url = options.url
|
143
|
+
var hash = parseURL(url).hash
|
123
144
|
|
124
145
|
// DEPRECATED: Save references to original event callbacks. However,
|
125
146
|
// listening for custom pjax:* events is prefered.
|
@@ -146,6 +167,8 @@ var pjax = $.pjax = function( options ) {
|
|
146
167
|
var timeoutTimer
|
147
168
|
|
148
169
|
options.beforeSend = function(xhr, settings) {
|
170
|
+
url = stripPjaxParam(settings.url)
|
171
|
+
|
149
172
|
if (settings.timeout > 0) {
|
150
173
|
timeoutTimer = setTimeout(function() {
|
151
174
|
if (fire('pjax:timeout', [xhr, options]))
|
@@ -169,18 +192,9 @@ var pjax = $.pjax = function( options ) {
|
|
169
192
|
|
170
193
|
if (!fire('pjax:beforeSend', [xhr, settings])) return false
|
171
194
|
|
172
|
-
if (options.push && !options.replace) {
|
173
|
-
// Cache current container element before replacing it
|
174
|
-
containerCache.push(pjax.state.id, context.clone(true, true).contents())
|
175
|
-
|
176
|
-
window.history.pushState(null, "", options.url)
|
177
|
-
}
|
178
|
-
|
179
195
|
fire('pjax:start', [xhr, options])
|
180
196
|
// start.pjax is deprecated
|
181
197
|
fire('start.pjax', [xhr, options])
|
182
|
-
|
183
|
-
fire('pjax:send', [xhr, settings])
|
184
198
|
}
|
185
199
|
|
186
200
|
options.complete = function(xhr, textStatus) {
|
@@ -198,42 +212,72 @@ var pjax = $.pjax = function( options ) {
|
|
198
212
|
}
|
199
213
|
|
200
214
|
options.error = function(xhr, textStatus, errorThrown) {
|
201
|
-
var
|
215
|
+
var respUrl = xhr.getResponseHeader('X-PJAX-URL')
|
216
|
+
if (respUrl) url = stripPjaxParam(respUrl)
|
202
217
|
|
203
218
|
// DEPRECATED: Invoke original `error` handler
|
204
219
|
if (oldError) oldError.apply(this, arguments)
|
205
220
|
|
206
221
|
var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
|
207
222
|
if (textStatus !== 'abort' && allowed)
|
208
|
-
window.location =
|
223
|
+
window.location = url
|
209
224
|
}
|
210
225
|
|
211
226
|
options.success = function(data, status, xhr) {
|
212
|
-
var
|
227
|
+
var respUrl = xhr.getResponseHeader('X-PJAX-URL')
|
228
|
+
if (respUrl) url = stripPjaxParam(respUrl)
|
229
|
+
|
230
|
+
var title, oldTitle = document.title
|
231
|
+
|
232
|
+
if ( options.fragment ) {
|
233
|
+
// If they specified a fragment, look for it in the response
|
234
|
+
// and pull it out.
|
235
|
+
var html = $('<html>').html(data)
|
236
|
+
var $fragment = html.find(options.fragment)
|
237
|
+
if ( $fragment.length ) {
|
238
|
+
this.html($fragment.contents())
|
239
|
+
|
240
|
+
// If there's a <title> tag in the response, use it as
|
241
|
+
// the page's title. Otherwise, look for data-title and title attributes.
|
242
|
+
title = html.find('title').text() || $fragment.attr('title') || $fragment.data('title')
|
243
|
+
} else {
|
244
|
+
return window.location = url
|
245
|
+
}
|
246
|
+
} else {
|
247
|
+
// If we got no data or an entire web page, go directly
|
248
|
+
// to the page and let normal error handling happen.
|
249
|
+
if ( !$.trim(data) || /<html/i.test(data) )
|
250
|
+
return window.location = url
|
251
|
+
|
252
|
+
this.html(data)
|
213
253
|
|
214
|
-
|
215
|
-
|
216
|
-
|
254
|
+
// If there's a <title> tag in the response, use it as
|
255
|
+
// the page's title.
|
256
|
+
title = this.find('title').remove().text()
|
217
257
|
}
|
218
258
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
259
|
+
if ( title ) document.title = $.trim(title)
|
260
|
+
|
261
|
+
var state = {
|
262
|
+
url: url,
|
263
|
+
pjax: this.selector,
|
223
264
|
fragment: options.fragment,
|
224
265
|
timeout: options.timeout
|
225
266
|
}
|
226
267
|
|
227
|
-
if (
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
268
|
+
if ( options.replace ) {
|
269
|
+
pjax.active = true
|
270
|
+
window.history.replaceState(state, document.title, url)
|
271
|
+
} else if ( options.push ) {
|
272
|
+
// this extra replaceState before first push ensures good back
|
273
|
+
// button behavior
|
274
|
+
if ( !pjax.active ) {
|
275
|
+
window.history.replaceState($.extend({}, state, {url:null}), oldTitle)
|
276
|
+
pjax.active = true
|
277
|
+
}
|
233
278
|
|
234
|
-
|
235
|
-
|
236
|
-
$(window).scrollTop(options.scrollTo)
|
279
|
+
window.history.pushState(state, document.title, url)
|
280
|
+
}
|
237
281
|
|
238
282
|
// Google Analytics support
|
239
283
|
if ( (options.replace || options.push) && window._gaq )
|
@@ -252,21 +296,6 @@ var pjax = $.pjax = function( options ) {
|
|
252
296
|
}
|
253
297
|
|
254
298
|
|
255
|
-
// Initialize pjax.state for the initial page load. Assume we're
|
256
|
-
// using the container and options of the link we're loading for the
|
257
|
-
// back button to the initial page. This ensures good back button
|
258
|
-
// behavior.
|
259
|
-
if (!pjax.state) {
|
260
|
-
pjax.state = {
|
261
|
-
id: uniqueId(),
|
262
|
-
url: window.location.href,
|
263
|
-
container: context.selector,
|
264
|
-
fragment: options.fragment,
|
265
|
-
timeout: options.timeout
|
266
|
-
}
|
267
|
-
window.history.replaceState(pjax.state, document.title)
|
268
|
-
}
|
269
|
-
|
270
299
|
// Cancel the current request if we're already pjaxing
|
271
300
|
var xhr = pjax.xhr
|
272
301
|
if ( xhr && xhr.readyState < 4) {
|
@@ -276,47 +305,12 @@ var pjax = $.pjax = function( options ) {
|
|
276
305
|
|
277
306
|
pjax.options = options
|
278
307
|
pjax.xhr = $.ajax(options)
|
279
|
-
|
280
|
-
// pjax event is deprecated
|
281
308
|
$(document).trigger('pjax', [pjax.xhr, options])
|
282
309
|
|
283
310
|
return pjax.xhr
|
284
311
|
}
|
285
312
|
|
286
313
|
|
287
|
-
// Internal: Generate unique id for state object.
|
288
|
-
//
|
289
|
-
// Use a timestamp instead of a counter since ids should still be
|
290
|
-
// unique across page loads.
|
291
|
-
//
|
292
|
-
// Returns Number.
|
293
|
-
function uniqueId() {
|
294
|
-
return (new Date).getTime()
|
295
|
-
}
|
296
|
-
|
297
|
-
// Internal: Strips _pjax param from url
|
298
|
-
//
|
299
|
-
// url - String
|
300
|
-
//
|
301
|
-
// Returns String.
|
302
|
-
function stripPjaxParam(url) {
|
303
|
-
return url
|
304
|
-
.replace(/\?_pjax=[^&]+&?/, '?')
|
305
|
-
.replace(/_pjax=[^&]+&?/, '')
|
306
|
-
.replace(/[\?&]$/, '')
|
307
|
-
}
|
308
|
-
|
309
|
-
// Internal: Parse URL components and returns a Locationish object.
|
310
|
-
//
|
311
|
-
// url - String URL
|
312
|
-
//
|
313
|
-
// Returns HTMLAnchorElement that acts like Location.
|
314
|
-
function parseURL(url) {
|
315
|
-
var a = document.createElement('a')
|
316
|
-
a.href = url
|
317
|
-
return a
|
318
|
-
}
|
319
|
-
|
320
314
|
// Internal: Build options Object for arguments.
|
321
315
|
//
|
322
316
|
// For convenience the first parameter can be either the container or
|
@@ -376,181 +370,15 @@ function findContainerFor(container) {
|
|
376
370
|
}
|
377
371
|
}
|
378
372
|
|
379
|
-
// Internal: Filter and find all elements matching the selector.
|
380
|
-
//
|
381
|
-
// Where $.fn.find only matches descendants, findAll will test all the
|
382
|
-
// top level elements in the jQuery object as well.
|
383
|
-
//
|
384
|
-
// elems - jQuery object of Elements
|
385
|
-
// selector - String selector to match
|
386
|
-
//
|
387
|
-
// Returns a jQuery object.
|
388
|
-
function findAll(elems, selector) {
|
389
|
-
var results = $()
|
390
|
-
elems.each(function() {
|
391
|
-
if ($(this).is(selector))
|
392
|
-
results = results.add(this)
|
393
|
-
results = results.add(selector, this)
|
394
|
-
})
|
395
|
-
return results
|
396
|
-
}
|
397
|
-
|
398
|
-
// Internal: Extracts container and metadata from response.
|
399
|
-
//
|
400
|
-
// 1. Extracts X-PJAX-URL header if set
|
401
|
-
// 2. Extracts inline <title> tags
|
402
|
-
// 3. Builds response Element and extracts fragment if set
|
403
|
-
//
|
404
|
-
// data - String response data
|
405
|
-
// xhr - XHR response
|
406
|
-
// options - pjax options Object
|
407
|
-
//
|
408
|
-
// Returns an Object with url, title, and contents keys.
|
409
|
-
function extractContainer(data, xhr, options) {
|
410
|
-
var obj = {}
|
411
|
-
|
412
|
-
// Prefer X-PJAX-URL header if it was set, otherwise fallback to
|
413
|
-
// using the original requested url.
|
414
|
-
obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.url)
|
415
|
-
|
416
|
-
// Attempt to parse response html into elements
|
417
|
-
var $data = $(data)
|
418
|
-
|
419
|
-
// If response data is empty, return fast
|
420
|
-
if ($data.length === 0)
|
421
|
-
return obj
|
422
|
-
|
423
|
-
// If there's a <title> tag in the response, use it as
|
424
|
-
// the page's title.
|
425
|
-
obj.title = findAll($data, 'title').last().text()
|
426
|
-
|
427
|
-
if (options.fragment) {
|
428
|
-
// If they specified a fragment, look for it in the response
|
429
|
-
// and pull it out.
|
430
|
-
var $fragment = findAll($data, options.fragment).first()
|
431
|
-
|
432
|
-
if ($fragment.length) {
|
433
|
-
obj.contents = $fragment.contents()
|
434
|
-
|
435
|
-
// If there's no title, look for data-title and title attributes
|
436
|
-
// on the fragment
|
437
|
-
if (!obj.title)
|
438
|
-
obj.title = $fragment.attr('title') || $fragment.data('title')
|
439
|
-
}
|
440
|
-
|
441
|
-
} else if (!/<html/i.test(data)) {
|
442
|
-
obj.contents = $data
|
443
|
-
}
|
444
|
-
|
445
|
-
// Clean up any <title> tags
|
446
|
-
if (obj.contents) {
|
447
|
-
// Remove any parent title elements
|
448
|
-
obj.contents = obj.contents.not('title')
|
449
|
-
|
450
|
-
// Then scrub any titles from their descendents
|
451
|
-
obj.contents.find('title').remove()
|
452
|
-
}
|
453
|
-
|
454
|
-
// Trim any whitespace off the title
|
455
|
-
if (obj.title) obj.title = $.trim(obj.title)
|
456
|
-
|
457
|
-
return obj
|
458
|
-
}
|
459
|
-
|
460
|
-
// Public: Reload current page with pjax.
|
461
|
-
//
|
462
|
-
// Returns whatever $.pjax returns.
|
463
|
-
pjax.reload = function(container, options) {
|
464
|
-
var defaults = {
|
465
|
-
url: window.location.href,
|
466
|
-
push: false,
|
467
|
-
replace: true,
|
468
|
-
scrollTo: false
|
469
|
-
}
|
470
|
-
|
471
|
-
return $.pjax($.extend(defaults, optionsFor(container, options)))
|
472
|
-
}
|
473
|
-
|
474
373
|
|
475
374
|
pjax.defaults = {
|
476
375
|
timeout: 650,
|
477
376
|
push: true,
|
478
377
|
replace: false,
|
479
378
|
type: 'GET',
|
480
|
-
dataType: 'html'
|
481
|
-
scrollTo: 0,
|
482
|
-
maxCacheLength: 20
|
379
|
+
dataType: 'html'
|
483
380
|
}
|
484
381
|
|
485
|
-
// Internal: History DOM caching class.
|
486
|
-
function Cache() {
|
487
|
-
this.mapping = {}
|
488
|
-
this.forwardStack = []
|
489
|
-
this.backStack = []
|
490
|
-
}
|
491
|
-
// Push previous state id and container contents into the history
|
492
|
-
// cache. Should be called in conjunction with `pushState` to save the
|
493
|
-
// previous container contents.
|
494
|
-
//
|
495
|
-
// id - State ID Number
|
496
|
-
// value - DOM Element to cache
|
497
|
-
//
|
498
|
-
// Returns nothing.
|
499
|
-
Cache.prototype.push = function(id, value) {
|
500
|
-
this.mapping[id] = value
|
501
|
-
this.backStack.push(id)
|
502
|
-
|
503
|
-
// Remove all entires in forward history stack after pushing
|
504
|
-
// a new page.
|
505
|
-
while (this.forwardStack.length)
|
506
|
-
delete this.mapping[this.forwardStack.shift()]
|
507
|
-
|
508
|
-
// Trim back history stack to max cache length.
|
509
|
-
while (this.backStack.length > pjax.defaults.maxCacheLength)
|
510
|
-
delete this.mapping[this.backStack.shift()]
|
511
|
-
}
|
512
|
-
// Retrieve cached DOM Element for state id.
|
513
|
-
//
|
514
|
-
// id - State ID Number
|
515
|
-
//
|
516
|
-
// Returns DOM Element(s) or undefined if cache miss.
|
517
|
-
Cache.prototype.get = function(id) {
|
518
|
-
return this.mapping[id]
|
519
|
-
}
|
520
|
-
// Shifts cache from forward history cache to back stack. Should be
|
521
|
-
// called on `popstate` with the previous state id and container
|
522
|
-
// contents.
|
523
|
-
//
|
524
|
-
// id - State ID Number
|
525
|
-
// value - DOM Element to cache
|
526
|
-
//
|
527
|
-
// Returns nothing.
|
528
|
-
Cache.prototype.forward = function(id, value) {
|
529
|
-
this.mapping[id] = value
|
530
|
-
this.backStack.push(id)
|
531
|
-
|
532
|
-
if (id = this.forwardStack.pop())
|
533
|
-
delete this.mapping[id]
|
534
|
-
}
|
535
|
-
// Shifts cache from back history cache to forward stack. Should be
|
536
|
-
// called on `popstate` with the previous state id and container
|
537
|
-
// contents.
|
538
|
-
//
|
539
|
-
// id - State ID Number
|
540
|
-
// value - DOM Element to cache
|
541
|
-
//
|
542
|
-
// Returns nothing.
|
543
|
-
Cache.prototype.back = function(id, value) {
|
544
|
-
this.mapping[id] = value
|
545
|
-
this.forwardStack.push(id)
|
546
|
-
|
547
|
-
if (id = this.backStack.pop())
|
548
|
-
delete this.mapping[id]
|
549
|
-
}
|
550
|
-
|
551
|
-
var containerCache = new Cache
|
552
|
-
|
553
|
-
|
554
382
|
// Export $.pjax.click
|
555
383
|
pjax.click = handleClick
|
556
384
|
|
@@ -572,54 +400,18 @@ $(window).bind('popstate', function(event){
|
|
572
400
|
|
573
401
|
var state = event.state
|
574
402
|
|
575
|
-
if (state && state.
|
576
|
-
var container =
|
577
|
-
if (container.length)
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
// Since state ids always increase, we can deduce the history
|
582
|
-
// direction from the previous state.
|
583
|
-
var direction = pjax.state.id < state.id ? 'forward' : 'back'
|
584
|
-
|
585
|
-
// Cache current container before replacement and inform the
|
586
|
-
// cache which direction the history shifted.
|
587
|
-
containerCache[direction](pjax.state.id, container.clone(true, true).contents())
|
588
|
-
}
|
589
|
-
|
590
|
-
var options = {
|
591
|
-
id: state.id,
|
592
|
-
url: state.url,
|
403
|
+
if ( state && state.pjax ) {
|
404
|
+
var container = state.pjax
|
405
|
+
if ( $(container+'').length )
|
406
|
+
$.pjax({
|
407
|
+
url: state.url || location.href,
|
408
|
+
fragment: state.fragment,
|
593
409
|
container: container,
|
594
410
|
push: false,
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
}
|
599
|
-
|
600
|
-
if (contents) {
|
601
|
-
// pjax event is deprecated
|
602
|
-
$(document).trigger('pjax', [null, options])
|
603
|
-
container.trigger('pjax:start', [null, options])
|
604
|
-
// end.pjax event is deprecated
|
605
|
-
container.trigger('start.pjax', [null, options])
|
606
|
-
|
607
|
-
container.html(contents)
|
608
|
-
pjax.state = state
|
609
|
-
|
610
|
-
container.trigger('pjax:end', [null, options])
|
611
|
-
// end.pjax event is deprecated
|
612
|
-
container.trigger('end.pjax', [null, options])
|
613
|
-
} else {
|
614
|
-
$.pjax(options)
|
615
|
-
}
|
616
|
-
|
617
|
-
// Force reflow/relayout before the browser tries to restore the
|
618
|
-
// scroll position.
|
619
|
-
container[0].offsetHeight
|
620
|
-
} else {
|
411
|
+
timeout: state.timeout
|
412
|
+
})
|
413
|
+
else
|
621
414
|
window.location = location.href
|
622
|
-
}
|
623
415
|
}
|
624
416
|
})
|
625
417
|
|
@@ -672,7 +464,6 @@ if ( !$.support.pjax ) {
|
|
672
464
|
form.submit()
|
673
465
|
}
|
674
466
|
$.pjax.click = $.noop
|
675
|
-
$.pjax.reload = window.location.reload
|
676
467
|
$.fn.pjax = function() { return this }
|
677
468
|
}
|
678
469
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-pjax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Helioid (original David Heinemeier Hansson and PJAX by Chris Wanstrath)
|
@@ -42,6 +42,7 @@ extra_rdoc_files: []
|
|
42
42
|
files:
|
43
43
|
- ./pjax_rails.gemspec
|
44
44
|
- ./README.md
|
45
|
+
- ./rails-pjax-0.0.1.gem
|
45
46
|
- ./vendor/assets/javascripts/jquery.pjax.js
|
46
47
|
- ./lib/pjax_rails.rb
|
47
48
|
- ./lib/pjax.rb
|