891 lines
31 KiB
JavaScript
891 lines
31 KiB
JavaScript
/*! Dependencies for Locomotive Boilerplate - 2018-02-01 */
|
||
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Pjax=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
|
||
var clone = _dereq_('./lib/clone.js')
|
||
var executeScripts = _dereq_('./lib/execute-scripts.js')
|
||
|
||
var forEachEls = _dereq_("./lib/foreach-els.js")
|
||
|
||
var newUid = _dereq_("./lib/uniqueid.js")
|
||
|
||
var on = _dereq_("./lib/events/on.js")
|
||
// var off = require("./lib/events/on.js")
|
||
var trigger = _dereq_("./lib/events/trigger.js")
|
||
|
||
|
||
var Pjax = function(options) {
|
||
this.firstrun = true
|
||
|
||
var parseOptions = _dereq_("./lib/proto/parse-options.js");
|
||
parseOptions.apply(this,[options])
|
||
this.log("Pjax options", this.options)
|
||
|
||
this.maxUid = this.lastUid = newUid()
|
||
|
||
this.parseDOM(document)
|
||
|
||
on(window, "popstate", function(st) {
|
||
if (st.state) {
|
||
var opt = clone(this.options)
|
||
opt.url = st.state.url
|
||
opt.title = st.state.title
|
||
opt.history = false
|
||
|
||
if (st.state.uid < this.lastUid) {
|
||
opt.backward = true
|
||
}
|
||
else {
|
||
opt.forward = true
|
||
}
|
||
this.lastUid = st.state.uid
|
||
|
||
// @todo implement history cache here, based on uid
|
||
this.loadUrl(st.state.url, opt)
|
||
}
|
||
}.bind(this))
|
||
}
|
||
|
||
Pjax.prototype = {
|
||
log: _dereq_("./lib/proto/log.js"),
|
||
|
||
getElements: _dereq_("./lib/proto/get-elements.js"),
|
||
|
||
parseDOM: _dereq_("./lib/proto/parse-dom.js"),
|
||
|
||
refresh: _dereq_("./lib/proto/refresh.js"),
|
||
|
||
reload: _dereq_("./lib/reload.js"),
|
||
|
||
attachLink: _dereq_("./lib/proto/attach-link.js"),
|
||
|
||
forEachSelectors: function(cb, context, DOMcontext) {
|
||
return _dereq_("./lib/foreach-selectors.js").bind(this)(this.options.selectors, cb, context, DOMcontext)
|
||
},
|
||
|
||
switchSelectors: function(selectors, fromEl, toEl, options) {
|
||
return _dereq_("./lib/switches-selectors.js").bind(this)(this.options.switches, this.options.switchesOptions, selectors, fromEl, toEl, options)
|
||
},
|
||
|
||
// too much problem with the code below
|
||
// + it’s too dangerous
|
||
// switchFallback: function(fromEl, toEl) {
|
||
// this.switchSelectors(["head", "body"], fromEl, toEl)
|
||
// // execute script when DOM is like it should be
|
||
// Pjax.executeScripts(document.querySelector("head"))
|
||
// Pjax.executeScripts(document.querySelector("body"))
|
||
// }
|
||
|
||
latestChance: function(href) {
|
||
window.location = href
|
||
},
|
||
|
||
onSwitch: function() {
|
||
trigger(window, "resize scroll")
|
||
},
|
||
|
||
loadContent: function(html, options) {
|
||
var tmpEl = document.implementation.createHTMLDocument()
|
||
|
||
// parse HTML attributes to copy them
|
||
// since we are forced to use documentElement.innerHTML (outerHTML can't be used for <html>)
|
||
var htmlRegex = /<html[^>]+>/gi
|
||
var htmlAttribsRegex = /\s?[a-z:]+(?:\=(?:\'|\")[^\'\">]+(?:\'|\"))*/gi
|
||
var matches = html.match(htmlRegex)
|
||
if (matches && matches.length) {
|
||
matches = matches[0].match(htmlAttribsRegex)
|
||
if (matches.length) {
|
||
matches.shift()
|
||
matches.forEach(function(htmlAttrib) {
|
||
var attr = htmlAttrib.trim().split("=")
|
||
if (attr.length === 1) {
|
||
tmpEl.documentElement.setAttribute(attr[0], true)
|
||
}
|
||
else {
|
||
tmpEl.documentElement.setAttribute(attr[0], attr[1].slice(1, -1))
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
tmpEl.documentElement.innerHTML = html
|
||
this.log("load content", tmpEl.documentElement.attributes, tmpEl.documentElement.innerHTML.length)
|
||
|
||
// Clear out any focused controls before inserting new page contents.
|
||
// we clear focus on non form elements
|
||
if (document.activeElement && !document.activeElement.value) {
|
||
try {
|
||
document.activeElement.blur()
|
||
} catch (e) { }
|
||
}
|
||
|
||
// try {
|
||
this.switchSelectors(this.options.selectors, tmpEl, document, options)
|
||
|
||
// 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 = Array.prototype.slice.call(document.querySelectorAll("[autofocus]")).pop()
|
||
if (autofocusEl && document.activeElement !== autofocusEl) {
|
||
autofocusEl.focus();
|
||
}
|
||
|
||
// execute scripts when DOM have been completely updated
|
||
this.options.selectors.forEach(function(selector) {
|
||
forEachEls(document.querySelectorAll(selector), function(el) {
|
||
executeScripts(el)
|
||
})
|
||
})
|
||
// }
|
||
// catch(e) {
|
||
// if (this.options.debug) {
|
||
// this.log("Pjax switch fail: ", e)
|
||
// }
|
||
// this.switchFallback(tmpEl, document)
|
||
// }
|
||
},
|
||
|
||
doRequest: _dereq_("./lib/request.js"),
|
||
|
||
loadUrl: function(href, options) {
|
||
this.log("load href", href, options)
|
||
|
||
trigger(document, "pjax:send", options);
|
||
|
||
// Do the request
|
||
this.doRequest(href, function(html) {
|
||
// Fail if unable to load HTML via AJAX
|
||
if (html === false) {
|
||
trigger(document,"pjax:complete pjax:error", options)
|
||
|
||
return
|
||
}
|
||
|
||
// Clear out any focused controls before inserting new page contents.
|
||
document.activeElement.blur()
|
||
|
||
try {
|
||
this.loadContent(html, options)
|
||
}
|
||
catch (e) {
|
||
if (!this.options.debug) {
|
||
if (console && console.error) {
|
||
console.error("Pjax switch fail: ", e)
|
||
}
|
||
this.latestChance(href)
|
||
return
|
||
}
|
||
else {
|
||
throw e
|
||
}
|
||
}
|
||
|
||
if (options.history) {
|
||
if (this.firstrun) {
|
||
this.lastUid = this.maxUid = newUid()
|
||
this.firstrun = false
|
||
window.history.replaceState({
|
||
url: window.location.href,
|
||
title: document.title,
|
||
uid: this.maxUid
|
||
},
|
||
document.title)
|
||
}
|
||
|
||
// Update browser history
|
||
this.lastUid = this.maxUid = newUid()
|
||
window.history.pushState({
|
||
url: href,
|
||
title: options.title,
|
||
uid: this.maxUid
|
||
},
|
||
options.title,
|
||
href)
|
||
}
|
||
|
||
this.forEachSelectors(function(el) {
|
||
this.parseDOM(el)
|
||
}, this)
|
||
|
||
// Fire Events
|
||
trigger(document,"pjax:complete pjax:success", options)
|
||
|
||
options.analytics()
|
||
|
||
// Scroll page to top on new page load
|
||
if (options.scrollTo !== false) {
|
||
if (options.scrollTo.length > 1) {
|
||
window.scrollTo(options.scrollTo[0], options.scrollTo[1])
|
||
}
|
||
else {
|
||
window.scrollTo(0, options.scrollTo)
|
||
}
|
||
}
|
||
}.bind(this))
|
||
}
|
||
}
|
||
|
||
Pjax.isSupported = _dereq_("./lib/is-supported.js");
|
||
|
||
//arguably could do `if( require("./lib/is-supported.js")()) {` but that might be a little to simple
|
||
if (Pjax.isSupported()) {
|
||
module.exports = Pjax
|
||
}
|
||
// if there isn’t required browser functions, returning stupid api
|
||
else {
|
||
var stupidPjax = function() {}
|
||
for (var key in Pjax.prototype) {
|
||
if (Pjax.prototype.hasOwnProperty(key) && typeof Pjax.prototype[key] === "function") {
|
||
stupidPjax[key] = stupidPjax
|
||
}
|
||
}
|
||
|
||
module.exports = stupidPjax
|
||
}
|
||
|
||
},{"./lib/clone.js":2,"./lib/events/on.js":4,"./lib/events/trigger.js":5,"./lib/execute-scripts.js":6,"./lib/foreach-els.js":7,"./lib/foreach-selectors.js":8,"./lib/is-supported.js":9,"./lib/proto/attach-link.js":11,"./lib/proto/get-elements.js":12,"./lib/proto/log.js":13,"./lib/proto/parse-dom.js":14,"./lib/proto/parse-options.js":16,"./lib/proto/refresh.js":17,"./lib/reload.js":18,"./lib/request.js":19,"./lib/switches-selectors.js":20,"./lib/uniqueid.js":22}],2:[function(_dereq_,module,exports){
|
||
module.exports = function(obj) {
|
||
if (null === obj || "object" != typeof obj) {
|
||
return obj
|
||
}
|
||
var copy = obj.constructor()
|
||
for (var attr in obj) {
|
||
if (obj.hasOwnProperty(attr)) {
|
||
copy[attr] = obj[attr]
|
||
}
|
||
}
|
||
return copy
|
||
}
|
||
|
||
},{}],3:[function(_dereq_,module,exports){
|
||
module.exports = function(el) {
|
||
// console.log("going to execute script", el)
|
||
|
||
var code = (el.text || el.textContent || el.innerHTML || "")
|
||
var head = document.querySelector("head") || document.documentElement
|
||
var script = document.createElement("script")
|
||
|
||
if (code.match("document.write")) {
|
||
if (console && console.log) {
|
||
console.log("Script contains document.write. Can’t be executed correctly. Code skipped ", el)
|
||
}
|
||
return false
|
||
}
|
||
|
||
script.type = "text/javascript"
|
||
try {
|
||
script.appendChild(document.createTextNode(code))
|
||
}
|
||
catch (e) {
|
||
// old IEs have funky script nodes
|
||
script.text = code
|
||
}
|
||
|
||
// execute
|
||
head.insertBefore(script, head.firstChild)
|
||
head.removeChild(script) // avoid pollution
|
||
|
||
return true
|
||
}
|
||
|
||
},{}],4:[function(_dereq_,module,exports){
|
||
var forEachEls = _dereq_("../foreach-els")
|
||
|
||
module.exports = function(els, events, listener, useCapture) {
|
||
events = (typeof events === "string" ? events.split(" ") : events)
|
||
|
||
events.forEach(function(e) {
|
||
forEachEls(els, function(el) {
|
||
el.addEventListener(e, listener, useCapture)
|
||
})
|
||
})
|
||
}
|
||
|
||
},{"../foreach-els":7}],5:[function(_dereq_,module,exports){
|
||
var forEachEls = _dereq_("../foreach-els")
|
||
|
||
module.exports = function(els, events, opts) {
|
||
events = (typeof events === "string" ? events.split(" ") : events)
|
||
|
||
events.forEach(function(e) {
|
||
var event // = new CustomEvent(e) // doesn't everywhere yet
|
||
event = document.createEvent("HTMLEvents")
|
||
event.initEvent(e, true, true)
|
||
event.eventName = e
|
||
if (opts) {
|
||
Object.keys(opts).forEach(function(key) {
|
||
event[key] = opts[key]
|
||
})
|
||
}
|
||
|
||
forEachEls(els, function(el) {
|
||
var domFix = false
|
||
if (!el.parentNode && el !== document && el !== window) {
|
||
// THANKS YOU IE (9/10//11 concerned)
|
||
// dispatchEvent doesn't work if element is not in the dom
|
||
domFix = true
|
||
document.body.appendChild(el)
|
||
}
|
||
el.dispatchEvent(event)
|
||
if (domFix) {
|
||
el.parentNode.removeChild(el)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
},{"../foreach-els":7}],6:[function(_dereq_,module,exports){
|
||
var forEachEls = _dereq_("./foreach-els")
|
||
var evalScript = _dereq_("./eval-script")
|
||
// Finds and executes scripts (used for newly added elements)
|
||
// Needed since innerHTML does not run scripts
|
||
module.exports = function(el) {
|
||
// console.log("going to execute scripts for ", el)
|
||
forEachEls(el.querySelectorAll("script"), function(script) {
|
||
if (!script.type || script.type.toLowerCase() === "text/javascript") {
|
||
if (script.parentNode) {
|
||
script.parentNode.removeChild(script)
|
||
}
|
||
evalScript(script)
|
||
}
|
||
})
|
||
}
|
||
|
||
},{"./eval-script":3,"./foreach-els":7}],7:[function(_dereq_,module,exports){
|
||
/* global HTMLCollection: true */
|
||
|
||
module.exports = function(els, fn, context) {
|
||
if (els instanceof HTMLCollection || els instanceof NodeList || els instanceof Array) {
|
||
return Array.prototype.forEach.call(els, fn, context)
|
||
}
|
||
// assume simple dom element
|
||
return fn.call(context, els)
|
||
}
|
||
|
||
},{}],8:[function(_dereq_,module,exports){
|
||
var forEachEls = _dereq_("./foreach-els")
|
||
|
||
module.exports = function(selectors, cb, context, DOMcontext) {
|
||
DOMcontext = DOMcontext || document
|
||
selectors.forEach(function(selector) {
|
||
forEachEls(DOMcontext.querySelectorAll(selector), cb, context)
|
||
})
|
||
}
|
||
|
||
},{"./foreach-els":7}],9:[function(_dereq_,module,exports){
|
||
module.exports = function() {
|
||
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
|
||
return 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]\D|WebApps\/.+CFNetwork)/)
|
||
}
|
||
|
||
},{}],10:[function(_dereq_,module,exports){
|
||
if (!Function.prototype.bind) {
|
||
Function.prototype.bind = function(oThis) {
|
||
if (typeof this !== "function") {
|
||
// closest thing possible to the ECMAScript 5 internal IsCallable function
|
||
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")
|
||
}
|
||
|
||
var aArgs = Array.prototype.slice.call(arguments, 1)
|
||
var that = this
|
||
var Fnoop = function() {}
|
||
var fBound = function() {
|
||
return that.apply(this instanceof Fnoop && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)))
|
||
}
|
||
|
||
Fnoop.prototype = this.prototype
|
||
fBound.prototype = new Fnoop()
|
||
|
||
return fBound
|
||
}
|
||
}
|
||
|
||
},{}],11:[function(_dereq_,module,exports){
|
||
_dereq_("../polyfills/Function.prototype.bind")
|
||
|
||
var on = _dereq_("../events/on")
|
||
var clone = _dereq_("../clone")
|
||
|
||
var attrClick = "data-pjax-click-state"
|
||
var attrKey = "data-pjax-keyup-state"
|
||
|
||
var linkAction = function(el, event) {
|
||
// Don’t break browser special behavior on links (like page in new window)
|
||
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
||
el.setAttribute(attrClick, "modifier")
|
||
return
|
||
}
|
||
|
||
// we do test on href now to prevent unexpected behavior if for some reason
|
||
// user have href that can be dynamically updated
|
||
|
||
// Ignore external links.
|
||
if (el.protocol !== window.location.protocol || el.host !== window.location.host) {
|
||
el.setAttribute(attrClick, "external")
|
||
return
|
||
}
|
||
|
||
// Ignore click if we are on an anchor on the same page
|
||
if (el.pathname === window.location.pathname && el.hash.length > 0) {
|
||
el.setAttribute(attrClick, "anchor-present")
|
||
return
|
||
}
|
||
|
||
// Ignore anchors on the same page (keep native behavior)
|
||
if (el.hash && el.href.replace(el.hash, "") === window.location.href.replace(location.hash, "")) {
|
||
el.setAttribute(attrClick, "anchor")
|
||
return
|
||
}
|
||
|
||
// Ignore empty anchor "foo.html#"
|
||
if (el.href === window.location.href.split("#")[0] + "#") {
|
||
el.setAttribute(attrClick, "anchor-empty")
|
||
return
|
||
}
|
||
|
||
event.preventDefault()
|
||
|
||
// don’t do "nothing" if user try to reload the page by clicking the same link twice
|
||
if (
|
||
this.options.currentUrlFullReload &&
|
||
el.href === window.location.href.split("#")[0]
|
||
) {
|
||
el.setAttribute(attrClick, "reload")
|
||
this.reload()
|
||
return
|
||
}
|
||
|
||
el.setAttribute(attrClick, "load")
|
||
this.loadUrl(el.href, clone(this.options))
|
||
}
|
||
|
||
var isDefaultPrevented = function(event) {
|
||
return event.defaultPrevented || event.returnValue === false;
|
||
}
|
||
|
||
module.exports = function(el) {
|
||
var that = this
|
||
|
||
on(el, "click", function(event) {
|
||
if (isDefaultPrevented(event)) {
|
||
return
|
||
}
|
||
|
||
linkAction.call(that, el, event)
|
||
})
|
||
|
||
on(el, "keyup", function(event) {
|
||
if (isDefaultPrevented(event)) {
|
||
return
|
||
}
|
||
|
||
// Don’t break browser special behavior on links (like page in new window)
|
||
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
||
el.setAttribute(attrKey, "modifier")
|
||
return
|
||
}
|
||
|
||
if (event.keyCode == 13) {
|
||
linkAction.call(that, el, event)
|
||
}
|
||
}.bind(this))
|
||
}
|
||
|
||
},{"../clone":2,"../events/on":4,"../polyfills/Function.prototype.bind":10}],12:[function(_dereq_,module,exports){
|
||
module.exports = function(el) {
|
||
return el.querySelectorAll(this.options.elements)
|
||
}
|
||
|
||
},{}],13:[function(_dereq_,module,exports){
|
||
module.exports = function() {
|
||
if (this.options.debug && console) {
|
||
if (typeof console.log === "function") {
|
||
console.log.apply(console, arguments);
|
||
}
|
||
// ie is weird
|
||
else if (console.log) {
|
||
console.log(arguments);
|
||
}
|
||
}
|
||
}
|
||
|
||
},{}],14:[function(_dereq_,module,exports){
|
||
var forEachEls = _dereq_("../foreach-els")
|
||
|
||
var parseElement = _dereq_("./parse-element")
|
||
|
||
module.exports = function(el) {
|
||
forEachEls(this.getElements(el), parseElement, this)
|
||
}
|
||
|
||
},{"../foreach-els":7,"./parse-element":15}],15:[function(_dereq_,module,exports){
|
||
module.exports = function(el) {
|
||
switch (el.tagName.toLowerCase()) {
|
||
case "a":
|
||
// only attach link if el does not already have link attached
|
||
if (!el.hasAttribute('data-pjax-click-state')) {
|
||
this.attachLink(el)
|
||
}
|
||
break
|
||
|
||
case "form":
|
||
throw "Pjax doesnt support <form> yet."
|
||
break
|
||
|
||
default:
|
||
throw "Pjax can only be applied on <a> or <form> submit"
|
||
}
|
||
}
|
||
|
||
},{}],16:[function(_dereq_,module,exports){
|
||
/* global _gaq: true, ga: true */
|
||
|
||
module.exports = function(options){
|
||
this.options = options
|
||
this.options.elements = this.options.elements || "a[href], form[action]"
|
||
this.options.selectors = this.options.selectors || ["title", ".js-Pjax"]
|
||
this.options.switches = this.options.switches || {}
|
||
this.options.switchesOptions = this.options.switchesOptions || {}
|
||
this.options.history = this.options.history || true
|
||
this.options.analytics = this.options.analytics || function() {
|
||
// options.backward or options.foward can be true or undefined
|
||
// by default, we do track back/foward hit
|
||
// https://productforums.google.com/forum/#!topic/analytics/WVwMDjLhXYk
|
||
if (window._gaq) {
|
||
_gaq.push(["_trackPageview"])
|
||
}
|
||
if (window.ga) {
|
||
ga("send", "pageview", {page: location.pathname, title: document.title})
|
||
}
|
||
}
|
||
this.options.scrollTo = (typeof this.options.scrollTo === 'undefined') ? 0 : this.options.scrollTo;
|
||
this.options.cacheBust = (typeof this.options.cacheBust === 'undefined') ? true : this.options.cacheBust
|
||
this.options.debug = this.options.debug || false
|
||
|
||
// we can’t replace body.outerHTML or head.outerHTML
|
||
// it create a bug where new body or new head are created in the dom
|
||
// if you set head.outerHTML, a new body tag is appended, so the dom get 2 body
|
||
// & it break the switchFallback which replace head & body
|
||
if (!this.options.switches.head) {
|
||
this.options.switches.head = this.switchElementsAlt
|
||
}
|
||
if (!this.options.switches.body) {
|
||
this.options.switches.body = this.switchElementsAlt
|
||
}
|
||
if (typeof options.analytics !== "function") {
|
||
options.analytics = function() {}
|
||
}
|
||
}
|
||
},{}],17:[function(_dereq_,module,exports){
|
||
module.exports = function(el) {
|
||
this.parseDOM(el || document)
|
||
}
|
||
|
||
},{}],18:[function(_dereq_,module,exports){
|
||
module.exports = function() {
|
||
window.location.reload()
|
||
}
|
||
|
||
},{}],19:[function(_dereq_,module,exports){
|
||
module.exports = function(location, callback) {
|
||
var request = new XMLHttpRequest()
|
||
|
||
request.onreadystatechange = function() {
|
||
if (request.readyState === 4) {
|
||
if (request.status === 200) {
|
||
callback(request.responseText, request)
|
||
}
|
||
else {
|
||
callback(null, request)
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add a timestamp as part of the query string if cache busting is enabled
|
||
if (this.options.cacheBust) {
|
||
location += (!/[?&]/.test(location) ? "?" : "&") + new Date().getTime()
|
||
}
|
||
|
||
request.open("GET", location, true)
|
||
request.setRequestHeader("X-Requested-With", "XMLHttpRequest")
|
||
request.send(null)
|
||
return request
|
||
}
|
||
|
||
},{}],20:[function(_dereq_,module,exports){
|
||
var forEachEls = _dereq_("./foreach-els")
|
||
|
||
var defaultSwitches = _dereq_("./switches")
|
||
|
||
module.exports = function(switches, switchesOptions, selectors, fromEl, toEl, options) {
|
||
selectors.forEach(function(selector) {
|
||
var newEls = fromEl.querySelectorAll(selector)
|
||
var oldEls = toEl.querySelectorAll(selector)
|
||
if (this.log) {
|
||
this.log("Pjax switch", selector, newEls, oldEls)
|
||
}
|
||
if (newEls.length !== oldEls.length) {
|
||
// forEachEls(newEls, function(el) {
|
||
// this.log("newEl", el, el.outerHTML)
|
||
// }, this)
|
||
// forEachEls(oldEls, function(el) {
|
||
// this.log("oldEl", el, el.outerHTML)
|
||
// }, this)
|
||
throw "DOM doesn’t look the same on new loaded page: ’" + selector + "’ - new " + newEls.length + ", old " + oldEls.length
|
||
}
|
||
|
||
forEachEls(newEls, function(newEl, i) {
|
||
var oldEl = oldEls[i]
|
||
if (this.log) {
|
||
this.log("newEl", newEl, "oldEl", oldEl)
|
||
}
|
||
if (switches[selector]) {
|
||
switches[selector].bind(this)(oldEl, newEl, options, switchesOptions[selector])
|
||
}
|
||
else {
|
||
defaultSwitches.outerHTML.bind(this)(oldEl, newEl, options)
|
||
}
|
||
}, this)
|
||
}, this)
|
||
}
|
||
|
||
},{"./foreach-els":7,"./switches":21}],21:[function(_dereq_,module,exports){
|
||
var on = _dereq_("./events/on.js")
|
||
// var off = require("./lib/events/on.js")
|
||
// var trigger = require("./lib/events/trigger.js")
|
||
|
||
|
||
module.exports = {
|
||
outerHTML: function(oldEl, newEl) {
|
||
oldEl.outerHTML = newEl.outerHTML
|
||
this.onSwitch()
|
||
},
|
||
|
||
innerHTML: function(oldEl, newEl) {
|
||
oldEl.innerHTML = newEl.innerHTML
|
||
oldEl.className = newEl.className
|
||
this.onSwitch()
|
||
},
|
||
|
||
sideBySide: function(oldEl, newEl, options, switchOptions) {
|
||
var forEach = Array.prototype.forEach
|
||
var elsToRemove = []
|
||
var elsToAdd = []
|
||
var fragToAppend = document.createDocumentFragment()
|
||
// height transition are shitty on safari
|
||
// so commented for now (until I found something ?)
|
||
// var relevantHeight = 0
|
||
var animationEventNames = "animationend webkitAnimationEnd MSAnimationEnd oanimationend"
|
||
var animatedElsNumber = 0
|
||
var sexyAnimationEnd = function(e) {
|
||
if (e.target != e.currentTarget) {
|
||
// end triggered by an animation on a child
|
||
return
|
||
}
|
||
|
||
animatedElsNumber--
|
||
if (animatedElsNumber <= 0 && elsToRemove) {
|
||
elsToRemove.forEach(function(el) {
|
||
// browsing quickly can make the el
|
||
// already removed by last page update ?
|
||
if (el.parentNode) {
|
||
el.parentNode.removeChild(el)
|
||
}
|
||
})
|
||
|
||
elsToAdd.forEach(function(el) {
|
||
el.className = el.className.replace(el.getAttribute("data-pjax-classes"), "")
|
||
el.removeAttribute("data-pjax-classes")
|
||
// Pjax.off(el, animationEventNames, sexyAnimationEnd, true)
|
||
})
|
||
|
||
elsToAdd = null // free memory
|
||
elsToRemove = null // free memory
|
||
|
||
// assume the height is now useless (avoid bug since there is overflow hidden on the parent)
|
||
// oldEl.style.height = "auto"
|
||
|
||
// this is to trigger some repaint (example: picturefill)
|
||
this.onSwitch()
|
||
// Pjax.trigger(window, "scroll")
|
||
}
|
||
}.bind(this)
|
||
|
||
// Force height to be able to trigger css animation
|
||
// here we get the relevant height
|
||
// oldEl.parentNode.appendChild(newEl)
|
||
// relevantHeight = newEl.getBoundingClientRect().height
|
||
// oldEl.parentNode.removeChild(newEl)
|
||
// oldEl.style.height = oldEl.getBoundingClientRect().height + "px"
|
||
|
||
switchOptions = switchOptions || {}
|
||
|
||
forEach.call(oldEl.childNodes, function(el) {
|
||
elsToRemove.push(el)
|
||
if (el.classList && !el.classList.contains("js-Pjax-remove")) {
|
||
// for fast switch, clean element that just have been added, & not cleaned yet.
|
||
if (el.hasAttribute("data-pjax-classes")) {
|
||
el.className = el.className.replace(el.getAttribute("data-pjax-classes"), "")
|
||
el.removeAttribute("data-pjax-classes")
|
||
}
|
||
el.classList.add("js-Pjax-remove")
|
||
if (switchOptions.callbacks && switchOptions.callbacks.removeElement) {
|
||
switchOptions.callbacks.removeElement(el)
|
||
}
|
||
if (switchOptions.classNames) {
|
||
el.className += " " + switchOptions.classNames.remove + " " + (options.backward ? switchOptions.classNames.backward : switchOptions.classNames.forward)
|
||
}
|
||
animatedElsNumber++
|
||
on(el, animationEventNames, sexyAnimationEnd, true)
|
||
}
|
||
})
|
||
|
||
forEach.call(newEl.childNodes, function(el) {
|
||
if (el.classList) {
|
||
var addClasses = ""
|
||
if (switchOptions.classNames) {
|
||
addClasses = " js-Pjax-add " + switchOptions.classNames.add + " " + (options.backward ? switchOptions.classNames.forward : switchOptions.classNames.backward)
|
||
}
|
||
if (switchOptions.callbacks && switchOptions.callbacks.addElement) {
|
||
switchOptions.callbacks.addElement(el)
|
||
}
|
||
el.className += addClasses
|
||
el.setAttribute("data-pjax-classes", addClasses)
|
||
elsToAdd.push(el)
|
||
fragToAppend.appendChild(el)
|
||
animatedElsNumber++
|
||
on(el, animationEventNames, sexyAnimationEnd, true)
|
||
}
|
||
})
|
||
|
||
// pass all className of the parent
|
||
oldEl.className = newEl.className
|
||
oldEl.appendChild(fragToAppend)
|
||
|
||
// oldEl.style.height = relevantHeight + "px"
|
||
}
|
||
}
|
||
|
||
},{"./events/on.js":4}],22:[function(_dereq_,module,exports){
|
||
module.exports = (function() {
|
||
var counter = 0
|
||
return function() {
|
||
var id = ("pjax" + (new Date().getTime())) + "_" + counter
|
||
counter++
|
||
return id
|
||
}
|
||
})()
|
||
|
||
},{}]},{},[1])
|
||
(1)
|
||
});
|
||
!function(root, factory) {
|
||
"function" == typeof define && define.amd ? // AMD. Register as an anonymous module unless amdModuleId is set
|
||
define([], function() {
|
||
return root.svg4everybody = factory();
|
||
}) : "object" == typeof module && module.exports ? // Node. Does not work with strict CommonJS, but
|
||
// only CommonJS-like environments that support module.exports,
|
||
// like Node.
|
||
module.exports = factory() : root.svg4everybody = factory();
|
||
}(this, function() {
|
||
/*! svg4everybody v2.1.9 | github.com/jonathantneal/svg4everybody */
|
||
function embed(parent, svg, target) {
|
||
// if the target exists
|
||
if (target) {
|
||
// create a document fragment to hold the contents of the target
|
||
var fragment = document.createDocumentFragment(), viewBox = !svg.hasAttribute("viewBox") && target.getAttribute("viewBox");
|
||
// conditionally set the viewBox on the svg
|
||
viewBox && svg.setAttribute("viewBox", viewBox);
|
||
// copy the contents of the clone into the fragment
|
||
for (// clone the target
|
||
var clone = target.cloneNode(!0); clone.childNodes.length; ) {
|
||
fragment.appendChild(clone.firstChild);
|
||
}
|
||
// append the fragment into the svg
|
||
parent.appendChild(fragment);
|
||
}
|
||
}
|
||
function loadreadystatechange(xhr) {
|
||
// listen to changes in the request
|
||
xhr.onreadystatechange = function() {
|
||
// if the request is ready
|
||
if (4 === xhr.readyState) {
|
||
// get the cached html document
|
||
var cachedDocument = xhr._cachedDocument;
|
||
// ensure the cached html document based on the xhr response
|
||
cachedDocument || (cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(""),
|
||
cachedDocument.body.innerHTML = xhr.responseText, xhr._cachedTarget = {}), // clear the xhr embeds list and embed each item
|
||
xhr._embeds.splice(0).map(function(item) {
|
||
// get the cached target
|
||
var target = xhr._cachedTarget[item.id];
|
||
// ensure the cached target
|
||
target || (target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id)),
|
||
// embed the target into the svg
|
||
embed(item.parent, item.svg, target);
|
||
});
|
||
}
|
||
}, // test the ready state change immediately
|
||
xhr.onreadystatechange();
|
||
}
|
||
function svg4everybody(rawopts) {
|
||
function oninterval() {
|
||
// while the index exists in the live <use> collection
|
||
for (// get the cached <use> index
|
||
var index = 0; index < uses.length; ) {
|
||
// get the current <use>
|
||
var use = uses[index], parent = use.parentNode, svg = getSVGAncestor(parent), src = use.getAttribute("xlink:href") || use.getAttribute("href");
|
||
if (!src && opts.attributeName && (src = use.getAttribute(opts.attributeName)),
|
||
svg && src) {
|
||
if (polyfill) {
|
||
if (!opts.validate || opts.validate(src, svg, use)) {
|
||
// remove the <use> element
|
||
parent.removeChild(use);
|
||
// parse the src and get the url and id
|
||
var srcSplit = src.split("#"), url = srcSplit.shift(), id = srcSplit.join("#");
|
||
// if the link is external
|
||
if (url.length) {
|
||
// get the cached xhr request
|
||
var xhr = requests[url];
|
||
// ensure the xhr request exists
|
||
xhr || (xhr = requests[url] = new XMLHttpRequest(), xhr.open("GET", url), xhr.send(),
|
||
xhr._embeds = []), // add the svg and id as an item to the xhr embeds list
|
||
xhr._embeds.push({
|
||
parent: parent,
|
||
svg: svg,
|
||
id: id
|
||
}), // prepare the xhr ready state change event
|
||
loadreadystatechange(xhr);
|
||
} else {
|
||
// embed the local id into the svg
|
||
embed(parent, svg, document.getElementById(id));
|
||
}
|
||
} else {
|
||
// increase the index when the previous value was not "valid"
|
||
++index, ++numberOfSvgUseElementsToBypass;
|
||
}
|
||
}
|
||
} else {
|
||
// increase the index when the previous value was not "valid"
|
||
++index;
|
||
}
|
||
}
|
||
// continue the interval
|
||
(!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) && requestAnimationFrame(oninterval, 67);
|
||
}
|
||
var polyfill, opts = Object(rawopts), newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/, webkitUA = /\bAppleWebKit\/(\d+)\b/, olderEdgeUA = /\bEdge\/12\.(\d+)\b/, edgeUA = /\bEdge\/.(\d+)\b/, inIframe = window.top !== window.self;
|
||
polyfill = "polyfill" in opts ? opts.polyfill : newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe;
|
||
// create xhr requests object
|
||
var requests = {}, requestAnimationFrame = window.requestAnimationFrame || setTimeout, uses = document.getElementsByTagName("use"), numberOfSvgUseElementsToBypass = 0;
|
||
// conditionally start the interval if the polyfill is active
|
||
polyfill && oninterval();
|
||
}
|
||
function getSVGAncestor(node) {
|
||
for (var svg = node; "svg" !== svg.nodeName.toLowerCase() && (svg = svg.parentNode); ) {}
|
||
return svg;
|
||
}
|
||
return svg4everybody;
|
||
}); |