From e002d09d2b6b2317fec6caa8836b20e6709c5da3 Mon Sep 17 00:00:00 2001 From: Jinwei Zhao Date: Mon, 4 Apr 2016 14:00:39 +0800 Subject: jinwei.me --- Code/jinweiclarkchao.github.io/assets/pjax.js | 838 -------------------------- 1 file changed, 838 deletions(-) delete mode 100644 Code/jinweiclarkchao.github.io/assets/pjax.js (limited to 'Code/jinweiclarkchao.github.io/assets/pjax.js') diff --git a/Code/jinweiclarkchao.github.io/assets/pjax.js b/Code/jinweiclarkchao.github.io/assets/pjax.js deleted file mode 100644 index a51124f..0000000 --- a/Code/jinweiclarkchao.github.io/assets/pjax.js +++ /dev/null @@ -1,838 +0,0 @@ -// jquery.pjax.js -// copyright chris wanstrath -// https://github.com/defunkt/jquery-pjax - -(function($){ - -// When called on a container with a selector, fetches the href with -// ajax into the container or with the data-pjax attribute on the link -// itself. -// -// Tries to make sure the back button and ctrl+click work the way -// you'd expect. -// -// Exported as $.fn.pjax -// -// Accepts a jQuery ajax options object that may include these -// pjax specific options: -// -// -// container - Where to stick the response body. Usually a String selector. -// $(container).html(xhr.responseBody) -// (default: current jquery context) -// push - Whether to pushState the URL. Defaults to true (of course). -// replace - Want to use replaceState instead? That's cool. -// -// For convenience the second parameter can be either the container or -// the options object. -// -// Returns the jQuery object -function fnPjax(selector, container, options) { - var context = this - return this.on('click.pjax', selector, function(event) { - var opts = $.extend({}, optionsFor(container, options)) - if (!opts.container) - opts.container = $(this).attr('data-pjax') || context - handleClick(event, opts) - }) -} - -// Public: pjax on click handler -// -// Exported as $.pjax.click. -// -// event - "click" jQuery.Event -// options - pjax options -// -// Examples -// -// $(document).on('click', 'a', $.pjax.click) -// // is the same as -// $(document).pjax('a') -// -// $(document).on('click', 'a', function(event) { -// var container = $(this).closest('[data-pjax-container]') -// $.pjax.click(event, container) -// }) -// -// Returns nothing. -function handleClick(event, container, options) { - options = optionsFor(container, options) - - var link = event.currentTarget - - if (link.tagName.toUpperCase() !== 'A') - throw "$.fn.pjax or $.pjax.click requires an anchor element" - - // Middle click, cmd click, and ctrl click should open - // links in a new tab as normal. - if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey ) - return - - // Ignore cross origin links - if ( location.protocol !== link.protocol || location.hostname !== link.hostname ) - return - - // Ignore anchors on the same page - if (link.hash && link.href.replace(link.hash, '') === - location.href.replace(location.hash, '')) - return - - // Ignore empty anchor "foo.html#" - if (link.href === location.href + '#') - return - - var defaults = { - url: link.href, - container: $(link).attr('data-pjax'), - target: link - } - - var opts = $.extend({}, defaults, options) - var clickEvent = $.Event('pjax:click') - $(link).trigger(clickEvent, [opts]) - - if (!clickEvent.isDefaultPrevented()) { - pjax(opts) - event.preventDefault() - } -} - -// Public: pjax on form submit handler -// -// Exported as $.pjax.submit -// -// event - "click" jQuery.Event -// options - pjax options -// -// Examples -// -// $(document).on('submit', 'form', function(event) { -// var container = $(this).closest('[data-pjax-container]') -// $.pjax.submit(event, container) -// }) -// -// Returns nothing. -function handleSubmit(event, container, options) { - options = optionsFor(container, options) - - var form = event.currentTarget - - if (form.tagName.toUpperCase() !== 'FORM') - throw "$.pjax.submit requires a form element" - - var defaults = { - type: form.method.toUpperCase(), - url: form.action, - data: $(form).serializeArray(), - container: $(form).attr('data-pjax'), - target: form - } - - pjax($.extend({}, defaults, options)) - - event.preventDefault() -} - -// Loads a URL with ajax, puts the response body inside a container, -// then pushState()'s the loaded URL. -// -// Works just like $.ajax in that it accepts a jQuery ajax -// settings object (with keys like url, type, data, etc). -// -// Accepts these extra keys: -// -// container - Where to stick the response body. -// $(container).html(xhr.responseBody) -// push - Whether to pushState the URL. Defaults to true (of course). -// replace - Want to use replaceState instead? That's cool. -// -// Use it just like $.ajax: -// -// var xhr = $.pjax({ url: this.href, container: '#main' }) -// console.log( xhr.readyState ) -// -// Returns whatever $.ajax returns. -function pjax(options) { - options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options) - - if ($.isFunction(options.url)) { - options.url = options.url() - } - - var target = options.target - - var hash = parseURL(options.url).hash - - var context = options.context = findContainerFor(options.container) - - // We want the browser to maintain two separate internal caches: one - // for pjax'd partial page loads and one for normal page loads. - // Without adding this secret parameter, some browsers will often - // confuse the two. - if (!options.data) options.data = {} - options.data._pjax = context.selector - - function fire(type, args) { - var event = $.Event(type, { relatedTarget: target }) - context.trigger(event, args) - return !event.isDefaultPrevented() - } - - var timeoutTimer - - options.beforeSend = function(xhr, settings) { - // No timeout for non-GET requests - // Its not safe to request the resource again with a fallback method. - if (settings.type !== 'GET') { - settings.timeout = 0 - } - - xhr.setRequestHeader('X-PJAX', 'true') - xhr.setRequestHeader('X-PJAX-Container', context.selector) - - if (!fire('pjax:beforeSend', [xhr, settings])) - return false - - if (settings.timeout > 0) { - timeoutTimer = setTimeout(function() { - if (fire('pjax:timeout', [xhr, options])) - xhr.abort('timeout') - }, settings.timeout) - - // Clear timeout setting so jquerys internal timeout isn't invoked - settings.timeout = 0 - } - - options.requestUrl = parseURL(settings.url).href - } - - options.complete = function(xhr, textStatus) { - if (timeoutTimer) - clearTimeout(timeoutTimer) - - fire('pjax:complete', [xhr, textStatus, options]) - - fire('pjax:end', [xhr, options]) - } - - options.error = function(xhr, textStatus, errorThrown) { - var container = extractContainer("", xhr, options) - - var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options]) - if (options.type == 'GET' && textStatus !== 'abort' && allowed) { - locationReplace(container.url) - } - } - - options.success = function(data, status, xhr) { - // If $.pjax.defaults.version is a function, invoke it first. - // Otherwise it can be a static string. - var currentVersion = (typeof $.pjax.defaults.version === 'function') ? - $.pjax.defaults.version() : - $.pjax.defaults.version - - var latestVersion = xhr.getResponseHeader('X-PJAX-Version') - - var container = extractContainer(data, xhr, options) - - // If there is a layout version mismatch, hard load the new url - if (currentVersion && latestVersion && currentVersion !== latestVersion) { - locationReplace(container.url) - return - } - - // If the new response is missing a body, hard load the page - if (!container.contents) { - locationReplace(container.url) - return - } - - pjax.state = { - id: options.id || uniqueId(), - url: container.url, - title: container.title, - container: context.selector, - fragment: options.fragment, - timeout: options.timeout - } - - if (options.push || options.replace) { - window.history.replaceState(pjax.state, container.title, container.url) - } - - // Clear out any focused controls before inserting new page contents. - document.activeElement.blur() - - if (container.title) document.title = container.title - context.html(container.contents) - - // FF bug: Won't autofocus fields that are inserted via JS. - // This behavior is incorrect. So if theres no current focus, autofocus - // the last field. - // - // http://www.w3.org/html/wg/drafts/html/master/forms.html - var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0] - if (autofocusEl && document.activeElement !== autofocusEl) { - autofocusEl.focus(); - } - - executeScriptTags(container.scripts) - - // Scroll to top by default - if (typeof options.scrollTo === 'number') - $(window).scrollTop(options.scrollTo) - - // If the URL has a hash in it, make sure the browser - // knows to navigate to the hash. - if ( hash !== '' ) { - // Avoid using simple hash set here. Will add another history - // entry. Replace the url with replaceState and scroll to target - // by hand. - // - // window.location.hash = hash - var url = parseURL(container.url) - url.hash = hash - - pjax.state.url = url.href - window.history.replaceState(pjax.state, container.title, url.href) - - var target = $(url.hash) - if (target.length) $(window).scrollTop(target.offset().top) - } - - fire('pjax:success', [data, status, xhr, options]) - } - - - // Initialize pjax.state for the initial page load. Assume we're - // using the container and options of the link we're loading for the - // back button to the initial page. This ensures good back button - // behavior. - if (!pjax.state) { - pjax.state = { - id: uniqueId(), - url: window.location.href, - title: document.title, - container: context.selector, - fragment: options.fragment, - timeout: options.timeout - } - window.history.replaceState(pjax.state, document.title) - } - - // Cancel the current request if we're already pjaxing - var xhr = pjax.xhr - if ( xhr && xhr.readyState < 4) { - xhr.onreadystatechange = $.noop - xhr.abort() - } - - pjax.options = options - var xhr = pjax.xhr = $.ajax(options) - - if (xhr.readyState > 0) { - if (options.push && !options.replace) { - // Cache current container element before replacing it - cachePush(pjax.state.id, context.clone().contents()) - - window.history.pushState(null, "", stripPjaxParam(options.requestUrl)) - } - - fire('pjax:start', [xhr, options]) - fire('pjax:send', [xhr, options]) - } - - return pjax.xhr -} - -// Public: Reload current page with pjax. -// -// Returns whatever $.pjax returns. -function pjaxReload(container, options) { - var defaults = { - url: window.location.href, - push: false, - replace: true, - scrollTo: false - } - - return pjax($.extend(defaults, optionsFor(container, options))) -} - -// Internal: Hard replace current state with url. -// -// Work for around WebKit -// https://bugs.webkit.org/show_bug.cgi?id=93506 -// -// Returns nothing. -function locationReplace(url) { - window.history.replaceState(null, "", "#") - window.location.replace(url) -} - - -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) { - pjax.state = initialState -} - -// Non-webkit browsers don't fire an initial popstate event -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) { - var state = event.state - - if (state && state.container) { - // When coming forward from a separate history session, will get an - // initial pop with a state we are already at. Skip reloading the current - // page. - if (initialPop && initialURL == state.url) return - - // If popping back to the same state, just skip. - // Could be clicking back from hashchange rather than a pushState. - if (pjax.state.id === state.id) return - - var container = $(state.container) - if (container.length) { - var direction, contents = cacheMapping[state.id] - - if (pjax.state) { - // Since state ids always increase, we can deduce the history - // direction from the previous state. - direction = pjax.state.id < state.id ? 'forward' : 'back' - - // Cache current container before replacement and inform the - // cache which direction the history shifted. - cachePop(direction, pjax.state.id, container.clone().contents()) - } - - var popstateEvent = $.Event('pjax:popstate', { - state: state, - direction: direction - }) - container.trigger(popstateEvent) - - var options = { - id: state.id, - url: state.url, - container: container, - push: false, - fragment: state.fragment, - timeout: state.timeout, - scrollTo: false - } - - if (contents) { - container.trigger('pjax:start', [null, options]) - - if (state.title) document.title = state.title - container.html(contents) - pjax.state = state - - container.trigger('pjax:end', [null, options]) - } else { - pjax(options) - } - - // Force reflow/relayout before the browser tries to restore the - // scroll position. - container[0].offsetHeight - } else { - locationReplace(location.href) - } - } - 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) { - var url = $.isFunction(options.url) ? options.url() : options.url, - method = options.type ? options.type.toUpperCase() : 'GET' - - var form = $('
', { - method: method === 'GET' ? 'GET' : 'POST', - action: url, - style: 'display:none' - }) - - if (method !== 'GET' && method !== 'POST') { - form.append($('', { - type: 'hidden', - name: '_method', - value: method.toLowerCase() - })) - } - - var data = options.data - if (typeof data === 'string') { - $.each(data.split('&'), function(index, value) { - var pair = value.split('=') - form.append($('', {type: 'hidden', name: pair[0], value: pair[1]})) - }) - } else if (typeof data === 'object') { - for (key in data) - form.append($('', {type: 'hidden', name: key, value: data[key]})) - } - - $(document.body).append(form) - form.submit() -} - -// Internal: Generate unique id for state object. -// -// Use a timestamp instead of a counter since ids should still be -// unique across page loads. -// -// Returns Number. -function uniqueId() { - return (new Date).getTime() -} - -// Internal: Strips _pjax param from url -// -// url - String -// -// Returns String. -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) { - var a = document.createElement('a') - a.href = url - return a -} - -// Internal: Build options Object for arguments. -// -// For convenience the first parameter can be either the container or -// the options object. -// -// Examples -// -// optionsFor('#container') -// // => {container: '#container'} -// -// optionsFor('#container', {push: true}) -// // => {container: '#container', push: true} -// -// optionsFor({container: '#container', push: true}) -// // => {container: '#container', push: true} -// -// Returns options Object. -function optionsFor(container, options) { - // Both container and options - if ( container && options ) - options.container = container - - // First argument is options Object - else if ( $.isPlainObject(container) ) - options = container - - // Only container - else - options = {container: container} - - // Find and validate container - if (options.container) - options.container = findContainerFor(options.container) - - return options -} - -// Internal: Find container element for a variety of inputs. -// -// Because we can't persist elements using the history API, we must be -// able to find a String selector that will consistently find the Element. -// -// container - A selector String, jQuery object, or DOM Element. -// -// Returns a jQuery object whose context is `document` and has a selector. -function findContainerFor(container) { - container = $(container) - - if ( !container.length ) { - throw "no pjax container for " + container.selector - } else if ( container.selector !== '' && container.context === document ) { - return container - } else if ( container.attr('id') ) { - return $('#' + container.attr('id')) - } else { - throw "cant get selector for pjax container!" - } -} - -// Internal: Filter and find all elements matching the selector. -// -// Where $.fn.find only matches descendants, findAll will test all the -// top level elements in the jQuery object as well. -// -// elems - jQuery object of Elements -// selector - String selector to match -// -// Returns a jQuery object. -function findAll(elems, selector) { - return elems.filter(selector).add(elems.find(selector)); -} - -function parseHTML(html) { - return $.parseHTML(html, document, true) -} - -// Internal: Extracts container and metadata from response. -// -// 1. Extracts X-PJAX-URL header if set -// 2. Extracts inline tags -// 3. Builds response Element and extracts fragment if set -// -// data - String response data -// xhr - XHR response -// options - pjax options Object -// -// Returns an Object with url, title, and contents keys. -function extractContainer(data, xhr, options) { - var obj = {} - - // Prefer X-PJAX-URL header if it was set, otherwise fallback to - // using the original requested url. - obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl) - - // Attempt to parse response html into elements - if (/<html/i.test(data)) { - var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0])) - var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0])) - } else { - var $head = $body = $(parseHTML(data)) - } - - // If response data is empty, return fast - if ($body.length === 0) - return obj - - // If there's a <title> tag in the header, use it as - // the page's title. - obj.title = findAll($head, 'title').last().text() - - if (options.fragment) { - // If they specified a fragment, look for it in the response - // and pull it out. - if (options.fragment === 'body') { - var $fragment = $body - } else { - var $fragment = findAll($body, options.fragment).first() - } - - if ($fragment.length) { - obj.contents = $fragment.contents() - - // If there's no title, look for data-title and title attributes - // on the fragment - if (!obj.title) - obj.title = $fragment.attr('title') || $fragment.data('title') - } - - } else if (!/<html/i.test(data)) { - obj.contents = $body - } - - // Clean up any <title> tags - if (obj.contents) { - // Remove any parent title elements - obj.contents = obj.contents.not(function() { return $(this).is('title') }) - - // Then scrub any titles from their descendants - obj.contents.find('title').remove() - - // Gather all script[src] elements - obj.scripts = findAll(obj.contents, 'script[src]').remove() - obj.contents = obj.contents.not(obj.scripts) - } - - // Trim any whitespace off the title - if (obj.title) obj.title = $.trim(obj.title) - - return obj -} - -// Load an execute scripts using standard script request. -// -// Avoids jQuery's traditional $.getScript which does a XHR request and -// globalEval. -// -// scripts - jQuery object of script Elements -// -// Returns nothing. -function executeScriptTags(scripts) { - if (!scripts) return - - var existingScripts = $('script[src]') - - scripts.each(function() { - var src = this.src - var matchedScripts = existingScripts.filter(function() { - return this.src === src - }) - if (matchedScripts.length) return - - var script = document.createElement('script') - script.type = $(this).attr('type') - script.src = $(this).attr('src') - document.head.appendChild(script) - }) -} - -// Internal: History DOM caching class. -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 -// previous container contents. -// -// id - State ID Number -// value - DOM Element to cache -// -// Returns nothing. -function cachePush(id, value) { - cacheMapping[id] = value - cacheBackStack.push(id) - - // Remove all entires in forward history stack after pushing - // a new page. - while (cacheForwardStack.length) - delete cacheMapping[cacheForwardStack.shift()] - - // 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 -// contents. -// -// direction - "forward" or "back" String -// id - State ID Number -// value - DOM Element to cache -// -// Returns nothing. -function cachePop(direction, id, value) { - var pushStack, popStack - cacheMapping[id] = value - - if (direction === 'forward') { - pushStack = cacheBackStack - popStack = cacheForwardStack - } else { - pushStack = cacheForwardStack - popStack = cacheBackStack - } - - 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() { - 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. -// -// Does nothing if already enabled. -// -// Examples -// -// $.pjax.enable() -// -// Returns nothing. -function enable() { - $.fn.pjax = fnPjax - $.pjax = pjax - $.pjax.enable = $.noop - $.pjax.disable = disable - $.pjax.click = handleClick - $.pjax.submit = handleSubmit - $.pjax.reload = pjaxReload - $.pjax.defaults = { - timeout: 650, - push: true, - replace: false, - type: 'GET', - dataType: 'html', - scrollTo: 0, - maxCacheLength: 20, - version: findVersion - } - $(window).on('popstate.pjax', onPjaxPopstate) -} - -// Disable pushState behavior. -// -// This is the case when a browser doesn't support pushState. It is -// sometimes useful to disable pushState for debugging on a modern -// browser. -// -// Examples -// -// $.pjax.disable() -// -// Returns nothing. -function disable() { - $.fn.pjax = function() { return this } - $.pjax = fallbackPjax - $.pjax.enable = enable - $.pjax.disable = $.noop - $.pjax.click = $.noop - $.pjax.submit = $.noop - $.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 ) - $.event.props.push('state') - -// Is pjax supported by this browser? -$.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() - -})(jQuery); \ No newline at end of file -- cgit v1.2.3