Commit 04f381eb by Paul Klimov

Merge branch 'master' of github.com:yiisoft/yii2

parents 518954da afefcd6e
......@@ -27,7 +27,7 @@
// the options object.
//
// Returns the jQuery object
function fnPjax(selector, container, options) {
function fnPjax(selector, container, options) {
var context = this
return this.on('click.pjax', selector, function(event) {
var opts = $.extend({}, optionsFor(container, options))
......@@ -35,7 +35,7 @@ function fnPjax(selector, container, options) {
opts.container = $(this).attr('data-pjax') || context
handleClick(event, opts)
})
}
}
// Public: pjax on click handler
//
......@@ -56,7 +56,7 @@ function fnPjax(selector, container, options) {
// })
//
// Returns nothing.
function handleClick(event, container, options) {
function handleClick(event, container, options) {
options = optionsFor(container, options)
var link = event.currentTarget
......@@ -95,8 +95,9 @@ function handleClick(event, container, options) {
if (!clickEvent.isDefaultPrevented()) {
pjax(opts)
event.preventDefault()
$(link).trigger('pjax:clicked', [opts])
}
}
}
// Public: pjax on form submit handler
//
......@@ -113,7 +114,7 @@ function handleClick(event, container, options) {
// })
//
// Returns nothing.
function handleSubmit(event, container, options) {
function handleSubmit(event, container, options) {
options = optionsFor(container, options)
var form = event.currentTarget
......@@ -132,7 +133,7 @@ function handleSubmit(event, container, options) {
pjax($.extend({}, defaults, options))
event.preventDefault()
}
}
// Loads a URL with ajax, puts the response body inside a container,
// then pushState()'s the loaded URL.
......@@ -153,7 +154,7 @@ function handleSubmit(event, container, options) {
// console.log( xhr.readyState )
//
// Returns whatever $.ajax returns.
function pjax(options) {
function pjax(options) {
options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
if ($.isFunction(options.url)) {
......@@ -344,12 +345,12 @@ function pjax(options) {
}
return pjax.xhr
}
}
// Public: Reload current page with pjax.
//
// Returns whatever $.pjax returns.
function pjaxReload(container, options) {
function pjaxReload(container, options) {
var defaults = {
url: window.location.href,
push: false,
......@@ -358,7 +359,7 @@ function pjaxReload(container, options) {
}
return pjax($.extend(defaults, optionsFor(container, options)))
}
}
// Internal: Hard replace current state with url.
//
......@@ -366,33 +367,33 @@ function pjaxReload(container, options) {
// https://bugs.webkit.org/show_bug.cgi?id=93506
//
// Returns nothing.
function locationReplace(url) {
function locationReplace(url) {
window.history.replaceState(null, "", "#")
window.location.replace(url)
}
}
var initialPop = true
var initialURL = window.location.href
var initialState = window.history.state
var initialPop = true
var initialURL = window.location.href
var initialState = window.history.state
// Initialize $.pjax.state if possible
// Happens when reloading a page and coming forward from a different
// session history.
if (initialState && initialState.container) {
if (initialState && initialState.container) {
pjax.state = initialState
}
}
// Non-webkit browsers don't fire an initial popstate event
if ('state' in window.history) {
if ('state' in window.history) {
initialPop = false
}
}
// popstate handler takes care of the back and forward buttons
//
// You probably shouldn't use pjax on pages with other pushState
// stuff yet.
function onPjaxPopstate(event) {
function onPjaxPopstate(event) {
var state = event.state
if (state && state.container) {
......@@ -455,13 +456,13 @@ function onPjaxPopstate(event) {
}
}
initialPop = false
}
}
// Fallback version of main pjax function for browsers that don't
// support pushState.
//
// Returns nothing since it retriggers a hard form submission.
function fallbackPjax(options) {
function fallbackPjax(options) {
var url = $.isFunction(options.url) ? options.url() : options.url,
method = options.type ? options.type.toUpperCase() : 'GET'
......@@ -492,7 +493,7 @@ function fallbackPjax(options) {
$(document.body).append(form)
form.submit()
}
}
// Internal: Generate unique id for state object.
//
......@@ -500,32 +501,32 @@ function fallbackPjax(options) {
// unique across page loads.
//
// Returns Number.
function uniqueId() {
function uniqueId() {
return (new Date).getTime()
}
}
// Internal: Strips _pjax param from url
//
// url - String
//
// Returns String.
function stripPjaxParam(url) {
function stripPjaxParam(url) {
return url
.replace(/\?_pjax=[^&]+&?/, '?')
.replace(/_pjax=[^&]+&?/, '')
.replace(/[\?&]$/, '')
}
}
// Internal: Parse URL components and returns a Locationish object.
//
// url - String URL
//
// Returns HTMLAnchorElement that acts like Location.
function parseURL(url) {
function parseURL(url) {
var a = document.createElement('a')
a.href = url
return a
}
}
// Internal: Build options Object for arguments.
//
......@@ -544,7 +545,7 @@ function parseURL(url) {
// // => {container: '#container', push: true}
//
// Returns options Object.
function optionsFor(container, options) {
function optionsFor(container, options) {
// Both container and options
if ( container && options )
options.container = container
......@@ -562,7 +563,7 @@ function optionsFor(container, options) {
options.container = findContainerFor(options.container)
return options
}
}
// Internal: Find container element for a variety of inputs.
//
......@@ -572,7 +573,7 @@ function optionsFor(container, options) {
// container - A selector String, jQuery object, or DOM Element.
//
// Returns a jQuery object whose context is `document` and has a selector.
function findContainerFor(container) {
function findContainerFor(container) {
container = $(container)
if ( !container.length ) {
......@@ -584,7 +585,7 @@ function findContainerFor(container) {
} else {
throw "cant get selector for pjax container!"
}
}
}
// Internal: Filter and find all elements matching the selector.
//
......@@ -595,13 +596,13 @@ function findContainerFor(container) {
// selector - String selector to match
//
// Returns a jQuery object.
function findAll(elems, selector) {
function findAll(elems, selector) {
return elems.filter(selector).add(elems.find(selector));
}
}
function parseHTML(html) {
function parseHTML(html) {
return $.parseHTML(html, document, true)
}
}
// Internal: Extracts container and metadata from response.
//
......@@ -614,7 +615,7 @@ function parseHTML(html) {
// options - pjax options Object
//
// Returns an Object with url, title, and contents keys.
function extractContainer(data, xhr, options) {
function extractContainer(data, xhr, options) {
var obj = {}
// Prefer X-PJAX-URL header if it was set, otherwise fallback to
......@@ -676,7 +677,7 @@ function extractContainer(data, xhr, options) {
if (obj.title) obj.title = $.trim(obj.title)
return obj
}
}
// Load an execute scripts using standard script request.
//
......@@ -686,7 +687,7 @@ function extractContainer(data, xhr, options) {
// scripts - jQuery object of script Elements
//
// Returns nothing.
function executeScriptTags(scripts) {
function executeScriptTags(scripts) {
if (!scripts) return
var existingScripts = $('script[src]')
......@@ -703,12 +704,12 @@ function executeScriptTags(scripts) {
script.src = $(this).attr('src')
document.head.appendChild(script)
})
}
}
// Internal: History DOM caching class.
var cacheMapping = {}
var cacheForwardStack = []
var cacheBackStack = []
var cacheMapping = {}
var cacheForwardStack = []
var cacheBackStack = []
// Push previous state id and container contents into the history
// cache. Should be called in conjunction with `pushState` to save the
......@@ -718,7 +719,7 @@ var cacheBackStack = []
// value - DOM Element to cache
//
// Returns nothing.
function cachePush(id, value) {
function cachePush(id, value) {
cacheMapping[id] = value
cacheBackStack.push(id)
......@@ -730,7 +731,7 @@ function cachePush(id, value) {
// Trim back history stack to max cache length.
while (cacheBackStack.length > pjax.defaults.maxCacheLength)
delete cacheMapping[cacheBackStack.shift()]
}
}
// Shifts cache from directional history cache. Should be
// called on `popstate` with the previous state id and container
......@@ -741,7 +742,7 @@ function cachePush(id, value) {
// value - DOM Element to cache
//
// Returns nothing.
function cachePop(direction, id, value) {
function cachePop(direction, id, value) {
var pushStack, popStack
cacheMapping[id] = value
......@@ -756,17 +757,17 @@ function cachePop(direction, id, value) {
pushStack.push(id)
if (id = popStack.pop())
delete cacheMapping[id]
}
}
// Public: Find version identifier for the initial page load.
//
// Returns String version or undefined.
function findVersion() {
function findVersion() {
return $('meta').filter(function() {
var name = $(this).attr('http-equiv')
return name && name.toUpperCase() === 'X-PJAX-VERSION'
}).attr('content')
}
}
// Install pjax functions on $.pjax to enable pushState behavior.
//
......@@ -777,7 +778,7 @@ function findVersion() {
// $.pjax.enable()
//
// Returns nothing.
function enable() {
function enable() {
$.fn.pjax = fnPjax
$.pjax = pjax
$.pjax.enable = $.noop
......@@ -796,7 +797,7 @@ function enable() {
version: findVersion
}
$(window).on('popstate.pjax', onPjaxPopstate)
}
}
// Disable pushState behavior.
//
......@@ -809,7 +810,7 @@ function enable() {
// $.pjax.disable()
//
// Returns nothing.
function disable() {
function disable() {
$.fn.pjax = function() { return this }
$.pjax = fallbackPjax
$.pjax.enable = enable
......@@ -819,20 +820,20 @@ function disable() {
$.pjax.reload = function() { window.location.reload() }
$(window).off('popstate.pjax', onPjaxPopstate)
}
}
// Add the state property to jQuery's event object so we can use it in
// $(window).bind('popstate')
if ( $.inArray('state', $.event.props) < 0 )
if ( $.inArray('state', $.event.props) < 0 )
$.event.props.push('state')
// Is pjax supported by this browser?
$.support.pjax =
$.support.pjax =
window.history && window.history.pushState && window.history.replaceState &&
// pushState isn't reliable on iOS until 5.
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)
$.support.pjax ? enable() : disable()
$.support.pjax ? enable() : disable()
})(jQuery);
......@@ -50,10 +50,16 @@ class Pjax extends Widget
/**
* @var string the jQuery selector of the links that should trigger pjax requests.
* If not set, all links within the enclosed content of Pjax will trigger pjax requests.
* Note that the pjax response to a link is a full page, a normal request will be sent again.
* Note that if the response to the pjax request is a full page, a normal request will be sent again.
*/
public $linkSelector;
/**
* @var string the jQuery selector of the forms whose submissions should trigger pjax requests.
* If not set, all forms with `data-pjax` attribute within the enclosed content of Pjax will trigger pjax requests.
* Note that if the response to the pjax request is a full page, a normal request will be sent again.
*/
public $formSelector;
/**
* @var boolean whether to enable push state.
*/
public $enablePushState = true;
......@@ -148,9 +154,11 @@ class Pjax extends Widget
$this->clientOptions['timeout'] = $this->timeout;
$options = Json::encode($this->clientOptions);
$linkSelector = Json::encode($this->linkSelector !== null ? $this->linkSelector : '#' . $id . ' a');
$formSelector = Json::encode($this->formSelector !== null ? $this->formSelector : '#' . $id . ' form[data-pjax]');
$view = $this->getView();
PjaxAsset::register($view);
$js = "jQuery(document).pjax($linkSelector, \"#$id\", $options);";
$js .= "jQuery(document).on('submit', $formSelector, function (event) {jQuery.pjax.submit(event, '#$id');});";
$view->registerJs($js);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment