Skip to content

Commit f053509

Browse files
committed
Merge branch 'jquery3'
Closes #665, fixes #634, closes #669, closes #644
2 parents d76e840 + 445f5e9 commit f053509

File tree

15 files changed

+28320
-6811
lines changed

15 files changed

+28320
-6811
lines changed

Gemfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
source 'http://rubygems.org'
2-
3-
ruby '1.9.3'
1+
source 'https://rubygems.org'
42

53
gem 'sinatra'

Gemfile.lock

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
GEM
2-
remote: http://rubygems.org/
2+
remote: https://rubygems.org/
33
specs:
44
rack (1.5.2)
55
rack-protection (1.5.3)
@@ -15,3 +15,6 @@ PLATFORMS
1515

1616
DEPENDENCIES
1717
sinatra
18+
19+
BUNDLED WITH
20+
1.14.6

jquery.pjax.js

Lines changed: 52 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
// pjax specific options:
2020
//
2121
//
22-
// container - Where to stick the response body. Usually a String selector.
23-
// $(container).html(xhr.responseBody)
24-
// (default: current jquery context)
22+
// container - String selector for the element where to place the response body.
2523
// push - Whether to pushState the URL. Defaults to true (of course).
2624
// replace - Want to use replaceState instead? That's cool.
2725
//
@@ -30,11 +28,13 @@
3028
//
3129
// Returns the jQuery object
3230
function fnPjax(selector, container, options) {
33-
var context = this
31+
options = optionsFor(container, options)
3432
return this.on('click.pjax', selector, function(event) {
35-
var opts = $.extend({}, optionsFor(container, options))
36-
if (!opts.container)
37-
opts.container = $(this).attr('data-pjax') || context
33+
var opts = options
34+
if (!opts.container) {
35+
opts = $.extend({}, options)
36+
opts.container = $(this).attr('data-pjax')
37+
}
3838
handleClick(event, opts)
3939
})
4040
}
@@ -52,16 +52,12 @@ function fnPjax(selector, container, options) {
5252
// // is the same as
5353
// $(document).pjax('a')
5454
//
55-
// $(document).on('click', 'a', function(event) {
56-
// var container = $(this).closest('[data-pjax-container]')
57-
// $.pjax.click(event, container)
58-
// })
59-
//
6055
// Returns nothing.
6156
function handleClick(event, container, options) {
6257
options = optionsFor(container, options)
6358

6459
var link = event.currentTarget
60+
var $link = $(link)
6561

6662
if (link.tagName.toUpperCase() !== 'A')
6763
throw "$.fn.pjax or $.pjax.click requires an anchor element"
@@ -85,18 +81,18 @@ function handleClick(event, container, options) {
8581

8682
var defaults = {
8783
url: link.href,
88-
container: $(link).attr('data-pjax'),
84+
container: $link.attr('data-pjax'),
8985
target: link
9086
}
9187

9288
var opts = $.extend({}, defaults, options)
9389
var clickEvent = $.Event('pjax:click')
94-
$(link).trigger(clickEvent, [opts])
90+
$link.trigger(clickEvent, [opts])
9591

9692
if (!clickEvent.isDefaultPrevented()) {
9793
pjax(opts)
9894
event.preventDefault()
99-
$(link).trigger('pjax:clicked', [opts])
95+
$link.trigger('pjax:clicked', [opts])
10096
}
10197
}
10298

@@ -110,8 +106,7 @@ function handleClick(event, container, options) {
110106
// Examples
111107
//
112108
// $(document).on('submit', 'form', function(event) {
113-
// var container = $(this).closest('[data-pjax-container]')
114-
// $.pjax.submit(event, container)
109+
// $.pjax.submit(event, '[data-pjax-container]')
115110
// })
116111
//
117112
// Returns nothing.
@@ -132,17 +127,17 @@ function handleSubmit(event, container, options) {
132127
}
133128

134129
if (defaults.type !== 'GET' && window.FormData !== undefined) {
135-
defaults.data = new FormData(form);
136-
defaults.processData = false;
137-
defaults.contentType = false;
130+
defaults.data = new FormData(form)
131+
defaults.processData = false
132+
defaults.contentType = false
138133
} else {
139134
// Can't handle file uploads, exit
140-
if ($(form).find(':file').length) {
141-
return;
135+
if ($form.find(':file').length) {
136+
return
142137
}
143138

144139
// Fallback to manually serializing the fields
145-
defaults.data = $(form).serializeArray();
140+
defaults.data = $form.serializeArray()
146141
}
147142

148143
pjax($.extend({}, defaults, options))
@@ -158,8 +153,7 @@ function handleSubmit(event, container, options) {
158153
//
159154
// Accepts these extra keys:
160155
//
161-
// container - Where to stick the response body.
162-
// $(container).html(xhr.responseBody)
156+
// container - String selector for where to stick the response body.
163157
// push - Whether to pushState the URL. Defaults to true (of course).
164158
// replace - Want to use replaceState instead? That's cool.
165159
//
@@ -176,26 +170,31 @@ function pjax(options) {
176170
options.url = options.url()
177171
}
178172

179-
var target = options.target
180-
181173
var hash = parseURL(options.url).hash
182174

183-
var context = options.context = findContainerFor(options.container)
175+
var containerType = $.type(options.container)
176+
if (containerType !== 'string') {
177+
throw "expected string value for 'container' option; got " + containerType
178+
}
179+
var context = options.context = $(options.container)
180+
if (!context.length) {
181+
throw "the container selector '" + options.container + "' did not match anything"
182+
}
184183

185184
// We want the browser to maintain two separate internal caches: one
186185
// for pjax'd partial page loads and one for normal page loads.
187186
// Without adding this secret parameter, some browsers will often
188187
// confuse the two.
189188
if (!options.data) options.data = {}
190189
if ($.isArray(options.data)) {
191-
options.data.push({name: '_pjax', value: context.selector})
190+
options.data.push({name: '_pjax', value: options.container})
192191
} else {
193-
options.data._pjax = context.selector
192+
options.data._pjax = options.container
194193
}
195194

196195
function fire(type, args, props) {
197196
if (!props) props = {}
198-
props.relatedTarget = target
197+
props.relatedTarget = options.target
199198
var event = $.Event(type, props)
200199
context.trigger(event, args)
201200
return !event.isDefaultPrevented()
@@ -211,7 +210,7 @@ function pjax(options) {
211210
}
212211

213212
xhr.setRequestHeader('X-PJAX', 'true')
214-
xhr.setRequestHeader('X-PJAX-Container', context.selector)
213+
xhr.setRequestHeader('X-PJAX-Container', options.container)
215214

216215
if (!fire('pjax:beforeSend', [xhr, settings]))
217216
return false
@@ -250,7 +249,7 @@ function pjax(options) {
250249
}
251250

252251
options.success = function(data, status, xhr) {
253-
var previousState = pjax.state;
252+
var previousState = pjax.state
254253

255254
// If $.pjax.defaults.version is a function, invoke it first.
256255
// Otherwise it can be a static string.
@@ -284,7 +283,7 @@ function pjax(options) {
284283
id: options.id || uniqueId(),
285284
url: container.url,
286285
title: container.title,
287-
container: context.selector,
286+
container: options.container,
288287
fragment: options.fragment,
289288
timeout: options.timeout
290289
}
@@ -318,7 +317,7 @@ function pjax(options) {
318317
// http://www.w3.org/html/wg/drafts/html/master/forms.html
319318
var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
320319
if (autofocusEl && document.activeElement !== autofocusEl) {
321-
autofocusEl.focus();
320+
autofocusEl.focus()
322321
}
323322

324323
executeScriptTags(container.scripts)
@@ -347,7 +346,7 @@ function pjax(options) {
347346
id: uniqueId(),
348347
url: window.location.href,
349348
title: document.title,
350-
container: context.selector,
349+
container: options.container,
351350
fragment: options.fragment,
352351
timeout: options.timeout
353352
}
@@ -363,7 +362,7 @@ function pjax(options) {
363362
if (xhr.readyState > 0) {
364363
if (options.push && !options.replace) {
365364
// Cache current container element before replacing it
366-
cachePush(pjax.state.id, cloneContents(context))
365+
cachePush(pjax.state.id, [options.container, cloneContents(context)])
367366

368367
window.history.pushState(null, "", options.requestUrl)
369368
}
@@ -448,13 +447,14 @@ function onPjaxPopstate(event) {
448447
}
449448

450449
var cache = cacheMapping[state.id] || []
451-
var container = $(cache[0] || state.container), contents = cache[1]
450+
var containerSelector = cache[0] || state.container
451+
var container = $(containerSelector), contents = cache[1]
452452

453453
if (container.length) {
454454
if (previousState) {
455455
// Cache current container before replacement and inform the
456456
// cache which direction the history shifted.
457-
cachePop(direction, previousState.id, cloneContents(container))
457+
cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
458458
}
459459

460460
var popstateEvent = $.Event('pjax:popstate', {
@@ -466,7 +466,7 @@ function onPjaxPopstate(event) {
466466
var options = {
467467
id: state.id,
468468
url: state.url,
469-
container: container,
469+
container: containerSelector,
470470
push: false,
471471
fragment: state.fragment,
472472
timeout: state.timeout,
@@ -568,7 +568,7 @@ function cloneContents(container) {
568568
cloned.find('script').each(function(){
569569
if (!this.src) jQuery._data(this, 'globalEval', false)
570570
})
571-
return [container.selector, cloned.contents()]
571+
return cloned.contents()
572572
}
573573

574574
// Internal: Strip internal query params from parsed URL.
@@ -618,44 +618,14 @@ function stripHash(location) {
618618
//
619619
// Returns options Object.
620620
function optionsFor(container, options) {
621-
// Both container and options
622-
if ( container && options )
621+
if (container && options) {
622+
options = $.extend({}, options)
623623
options.container = container
624-
625-
// First argument is options Object
626-
else if ( $.isPlainObject(container) )
627-
options = container
628-
629-
// Only container
630-
else
631-
options = {container: container}
632-
633-
// Find and validate container
634-
if (options.container)
635-
options.container = findContainerFor(options.container)
636-
637-
return options
638-
}
639-
640-
// Internal: Find container element for a variety of inputs.
641-
//
642-
// Because we can't persist elements using the history API, we must be
643-
// able to find a String selector that will consistently find the Element.
644-
//
645-
// container - A selector String, jQuery object, or DOM Element.
646-
//
647-
// Returns a jQuery object whose context is `document` and has a selector.
648-
function findContainerFor(container) {
649-
container = $(container)
650-
651-
if ( !container.length ) {
652-
throw "no pjax container for " + container.selector
653-
} else if ( container.selector !== '' && container.context === document ) {
624+
return options
625+
} else if ($.isPlainObject(container)) {
654626
return container
655-
} else if ( container.attr('id') ) {
656-
return $('#' + container.attr('id'))
657627
} else {
658-
throw "cant get selector for pjax container!"
628+
return {container: container}
659629
}
660630
}
661631

@@ -669,7 +639,7 @@ function findContainerFor(container) {
669639
//
670640
// Returns a jQuery object.
671641
function findAll(elems, selector) {
672-
return elems.filter(selector).add(elems.find(selector));
642+
return elems.filter(selector).add(elems.find(selector))
673643
}
674644

675645
function parseHTML(html) {
@@ -911,8 +881,11 @@ function disable() {
911881

912882
// Add the state property to jQuery's event object so we can use it in
913883
// $(window).bind('popstate')
914-
if ( $.inArray('state', $.event.props) < 0 )
884+
if ($.event.props && $.inArray('state', $.event.props) < 0) {
915885
$.event.props.push('state')
886+
} else if (!('state' in $.Event.prototype)) {
887+
$.event.addProp('state')
888+
}
916889

917890
// Is pjax supported by this browser?
918891
$.support.pjax =
@@ -922,4 +895,4 @@ $.support.pjax =
922895

923896
$.support.pjax ? enable() : disable()
924897

925-
})(jQuery);
898+
})(jQuery)

script/test

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ while ! lsof -i :$port >/dev/null; do
1111
sleep .05
1212
done
1313

14-
phantomjs ./test/run-qunit.coffee "http://localhost:$port/"
14+
[ -z "$CI" ] || echo "PhantomJS $(phantomjs --version)"
15+
16+
phantomjs ./test/run-qunit.js \
17+
"http://localhost:$port/?jquery=3.2" \
18+
"http://localhost:$port/?jquery=2.2" \
19+
"http://localhost:$port/?jquery=1.12"

test/app.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
set :public_folder, File.dirname(settings.root)
55
enable :static
66

7+
jquery_version = '3.2'
8+
79
helpers do
810
def pjax?
911
env['HTTP_X_PJAX'] && !params[:layout]
@@ -17,6 +19,10 @@ def title(str)
1719
nil
1820
end
1921
end
22+
23+
define_method(:jquery_version) do
24+
jquery_version
25+
end
2026
end
2127

2228
after do
@@ -28,6 +34,7 @@ def title(str)
2834

2935

3036
get '/' do
37+
jquery_version = params[:jquery] if params[:jquery]
3138
erb :qunit
3239
end
3340

0 commit comments

Comments
 (0)