Code cleanup (#120)
* Lots of code cleanup * Cleanup parse-options tests - Rename objects for clarity and inline unneeded objects - Remove unneeded tests - Use Object.keys().length instead of a custom function - Use typeof === "object" instead of a custom function that checks the prototype tree as well, since we don't expect anything but an object literal. * Remove old switchFallback code * Remove polyfill for Function.prototype.bind * Inline small functions * Add more documentation and tests for options.currentUrlFullReload Closes #17 * Update package.json
This commit was merged in pull request #120.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
module.exports = function(obj) {
|
||||
if (null === obj || "object" != typeof obj) {
|
||||
if (null === obj || "object" !== typeof obj) {
|
||||
return obj
|
||||
}
|
||||
var copy = obj.constructor()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module.exports = function(el) {
|
||||
var code = (el.text || el.textContent || el.innerHTML || "")
|
||||
var src = (el.src || "");
|
||||
var src = (el.src || "")
|
||||
var parent = el.parentNode || document.querySelector("head") || document.documentElement
|
||||
var script = document.createElement("script")
|
||||
|
||||
@@ -13,12 +13,12 @@ module.exports = function(el) {
|
||||
|
||||
script.type = "text/javascript"
|
||||
|
||||
if (src != "") {
|
||||
script.src = src;
|
||||
script.async = false; // force synchronous loading of peripheral js
|
||||
if (src !== "") {
|
||||
script.src = src
|
||||
script.async = false // force synchronous loading of peripheral JS
|
||||
}
|
||||
|
||||
if (code != "") {
|
||||
if (code !== "") {
|
||||
try {
|
||||
script.appendChild(document.createTextNode(code))
|
||||
}
|
||||
@@ -29,11 +29,11 @@ module.exports = function(el) {
|
||||
}
|
||||
|
||||
// execute
|
||||
parent.appendChild(script);
|
||||
parent.appendChild(script)
|
||||
// avoid pollution only in head or body tags
|
||||
if (["head","body"].indexOf(parent.tagName.toLowerCase()) > 0) {
|
||||
if (["head", "body"].indexOf(parent.tagName.toLowerCase()) > 0) {
|
||||
parent.removeChild(script)
|
||||
}
|
||||
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ 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
|
||||
var event
|
||||
event = document.createEvent("HTMLEvents")
|
||||
event.initEvent(e, true, true)
|
||||
event.eventName = e
|
||||
@@ -17,8 +17,8 @@ module.exports = function(els, events, opts) {
|
||||
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
|
||||
// THANK YOU IE (9/10/11)
|
||||
// dispatchEvent doesn't work if the element is not in the DOM
|
||||
domFix = true
|
||||
document.body.appendChild(el)
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@ var evalScript = require("./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)
|
||||
|
||||
if (el.tagName.toLowerCase() === "script") {
|
||||
evalScript(el);
|
||||
evalScript(el)
|
||||
}
|
||||
|
||||
forEachEls(el.querySelectorAll("script"), function(script) {
|
||||
@@ -14,7 +12,7 @@ module.exports = function(el) {
|
||||
if (script.parentNode) {
|
||||
script.parentNode.removeChild(script)
|
||||
}
|
||||
evalScript(script);
|
||||
evalScript(script)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@ 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
|
||||
// assume simple DOM element
|
||||
return fn.call(context, els)
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
require("../polyfills/Function.prototype.bind")
|
||||
|
||||
var on = require("../events/on")
|
||||
var clone = require("../clone")
|
||||
|
||||
@@ -8,27 +6,27 @@ var attrClick = "data-pjax-click-state"
|
||||
var formAction = function(el, event) {
|
||||
// Since loadUrl modifies options and we may add our own modifications below,
|
||||
// clone it so the changes don't persist
|
||||
var options = clone(this.options);
|
||||
var options = clone(this.options)
|
||||
|
||||
// Initialize requestOptions
|
||||
options.requestOptions = {
|
||||
requestUrl: el.getAttribute("action") || window.location.href,
|
||||
requestMethod: el.getAttribute("method") || "GET",
|
||||
requestMethod: el.getAttribute("method") || "GET"
|
||||
}
|
||||
|
||||
// create a testable virtual link of the form action
|
||||
var virtLinkElement = document.createElement("a");
|
||||
virtLinkElement.setAttribute("href", options.requestOptions.requestUrl);
|
||||
var virtLinkElement = document.createElement("a")
|
||||
virtLinkElement.setAttribute("href", options.requestOptions.requestUrl)
|
||||
|
||||
// Ignore external links.
|
||||
if (virtLinkElement.protocol !== window.location.protocol || virtLinkElement.host !== window.location.host) {
|
||||
el.setAttribute(attrClick, "external");
|
||||
el.setAttribute(attrClick, "external")
|
||||
return
|
||||
}
|
||||
|
||||
// Ignore click if we are on an anchor on the same page
|
||||
if (virtLinkElement.pathname === window.location.pathname && virtLinkElement.hash.length > 0) {
|
||||
el.setAttribute(attrClick, "anchor-present");
|
||||
el.setAttribute(attrClick, "anchor-present")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,41 +38,39 @@ var formAction = function(el, event) {
|
||||
|
||||
// if declared as a full reload, just normally submit the form
|
||||
if (options.currentUrlFullReload) {
|
||||
el.setAttribute(attrClick, "reload");
|
||||
return;
|
||||
el.setAttribute(attrClick, "reload")
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
var paramObject = [];
|
||||
var paramObject = []
|
||||
for (var elementKey in el.elements) {
|
||||
var element = el.elements[elementKey];
|
||||
var element = el.elements[elementKey]
|
||||
// jscs:disable disallowImplicitTypeConversion
|
||||
if (!!element.name && element.attributes !== undefined && element.tagName.toLowerCase() !== "button") {
|
||||
// jscs:enable disallowImplicitTypeConversion
|
||||
if ((element.attributes.type !== "checkbox" && element.attributes.type !== "radio") || element.checked) {
|
||||
paramObject.push({name: encodeURIComponent(element.name), value: encodeURIComponent(element.value)});
|
||||
paramObject.push({name: encodeURIComponent(element.name), value: encodeURIComponent(element.value)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creating a getString
|
||||
var paramsString = (paramObject.map(function(value) {return value.name + "=" + value.value;})).join("&");
|
||||
var paramsString = (paramObject.map(function(value) {return value.name + "=" + value.value})).join("&")
|
||||
|
||||
options.requestOptions.requestPayload = paramObject;
|
||||
options.requestOptions.requestPayloadString = paramsString;
|
||||
options.requestOptions.requestPayload = paramObject
|
||||
options.requestOptions.requestPayloadString = paramsString
|
||||
|
||||
el.setAttribute(attrClick, "submit");
|
||||
el.setAttribute(attrClick, "submit")
|
||||
|
||||
|
||||
options.triggerElement = el;
|
||||
this.loadUrl(virtLinkElement.href, options);
|
||||
};
|
||||
options.triggerElement = el
|
||||
this.loadUrl(virtLinkElement.href, options)
|
||||
}
|
||||
|
||||
var isDefaultPrevented = function(event) {
|
||||
return event.defaultPrevented || event.returnValue === false;
|
||||
};
|
||||
|
||||
return event.defaultPrevented || event.returnValue === false
|
||||
}
|
||||
|
||||
module.exports = function(el) {
|
||||
var that = this
|
||||
@@ -92,8 +88,7 @@ module.exports = function(el) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (event.keyCode == 13) {
|
||||
if (event.keyCode === 13) {
|
||||
formAction.call(that, el, event)
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
require("../polyfills/Function.prototype.bind")
|
||||
|
||||
var on = require("../events/on")
|
||||
var clone = require("../clone")
|
||||
|
||||
@@ -9,10 +7,10 @@ var attrKey = "data-pjax-keyup-state"
|
||||
var linkAction = function(el, event) {
|
||||
// Since loadUrl modifies options and we may add our own modifications below,
|
||||
// clone it so the changes don't persist
|
||||
var options = clone(this.options);
|
||||
var options = clone(this.options)
|
||||
|
||||
// Initialize requestOptions since loadUrl expects it to be an object
|
||||
options.requestOptions = {};
|
||||
options.requestOptions = {}
|
||||
|
||||
// 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) {
|
||||
@@ -66,7 +64,7 @@ var linkAction = function(el, event) {
|
||||
}
|
||||
|
||||
var isDefaultPrevented = function(event) {
|
||||
return event.defaultPrevented || event.returnValue === false;
|
||||
return event.defaultPrevented || event.returnValue === false
|
||||
}
|
||||
|
||||
module.exports = function(el) {
|
||||
@@ -91,7 +89,7 @@ module.exports = function(el) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.keyCode == 13) {
|
||||
if (event.keyCode === 13) {
|
||||
linkAction.call(that, el, event)
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = function(el) {
|
||||
return el.querySelectorAll(this.options.elements)
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
module.exports = function() {
|
||||
if (this.options.debug && console) {
|
||||
if (typeof console.log === "function") {
|
||||
console.log.apply(console, arguments);
|
||||
console.log.apply(console, arguments)
|
||||
}
|
||||
// ie is weird
|
||||
// IE is weird
|
||||
else if (console.log) {
|
||||
console.log(arguments);
|
||||
console.log(arguments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
var forEachEls = require("../foreach-els")
|
||||
|
||||
var parseElement = require("./parse-element")
|
||||
|
||||
module.exports = function(el) {
|
||||
forEachEls(this.getElements(el), parseElement, this)
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
var defaultSwitches = require("../switches")
|
||||
|
||||
module.exports = function(options) {
|
||||
options = options || {}
|
||||
options.elements = options.elements || "a[href], form[action]"
|
||||
options.selectors = options.selectors || ["title", ".js-Pjax"]
|
||||
options.switches = options.switches || {}
|
||||
@@ -18,16 +19,16 @@ module.exports = function(options) {
|
||||
ga("send", "pageview", {page: location.pathname, title: document.title})
|
||||
}
|
||||
}
|
||||
options.scrollTo = (typeof options.scrollTo === "undefined") ? 0 : options.scrollTo;
|
||||
options.scrollTo = (typeof options.scrollTo === "undefined") ? 0 : options.scrollTo
|
||||
options.scrollRestoration = (typeof options.scrollRestoration !== "undefined") ? options.scrollRestoration : true
|
||||
options.cacheBust = (typeof options.cacheBust === "undefined") ? true : options.cacheBust
|
||||
options.debug = options.debug || false
|
||||
options.timeout = options.timeout || 0
|
||||
options.currentUrlFullReload = (typeof options.currentUrlFullReload === "undefined") ? false : options.currentUrlFullReload
|
||||
|
||||
// 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
|
||||
// We can’t replace body.outerHTML or head.outerHTML.
|
||||
// It creates a bug where a new body or head are created in the DOM.
|
||||
// If you set head.outerHTML, a new body tag is appended, so the DOM has 2 body nodes, and vice versa
|
||||
if (!options.switches.head) {
|
||||
options.switches.head = defaultSwitches.switchElementsAlt
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = function(el) {
|
||||
this.parseDOM(el || document)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = function() {
|
||||
window.location.reload()
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = function(location, options, callback) {
|
||||
options = options || {};
|
||||
var requestMethod = options.requestMethod || "GET";
|
||||
var requestPayload = options.requestPayloadString || null;
|
||||
options = options || {}
|
||||
var requestMethod = options.requestMethod || "GET"
|
||||
var requestPayload = options.requestPayloadString || null
|
||||
var request = new XMLHttpRequest()
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
@@ -35,9 +35,9 @@ module.exports = function(location, options, callback) {
|
||||
request.setRequestHeader("X-PJAX", "true")
|
||||
|
||||
// Add the request payload if available
|
||||
if (options.requestPayloadString != undefined && options.requestPayloadString != "") {
|
||||
if (options.requestPayloadString !== undefined && options.requestPayloadString !== "") {
|
||||
// Send the proper header information along with the request
|
||||
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
|
||||
request.send(requestPayload)
|
||||
|
||||
@@ -3,7 +3,7 @@ var forEachEls = require("./foreach-els")
|
||||
var defaultSwitches = require("./switches")
|
||||
|
||||
module.exports = function(switches, switchesOptions, selectors, fromEl, toEl, options) {
|
||||
var switchesQueue = [];
|
||||
var switchesQueue = []
|
||||
|
||||
selectors.forEach(function(selector) {
|
||||
var newEls = fromEl.querySelectorAll(selector)
|
||||
@@ -12,12 +12,6 @@ module.exports = function(switches, switchesOptions, selectors, fromEl, toEl, op
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
var on = require("./events/on.js")
|
||||
// var off = require("./lib/events/on.js")
|
||||
// var trigger = require("./lib/events/trigger.js")
|
||||
|
||||
|
||||
module.exports = {
|
||||
outerHTML: function(oldEl, newEl) {
|
||||
@@ -20,7 +17,7 @@ module.exports = {
|
||||
|
||||
// Copy attributes from the new element to the old one
|
||||
if (newEl.hasAttributes()) {
|
||||
var attrs = newEl.attributes;
|
||||
var attrs = newEl.attributes
|
||||
for (var i = 0; i < attrs.length; i++) {
|
||||
oldEl.attributes.setNamedItem(attrs[i].cloneNode())
|
||||
}
|
||||
@@ -34,13 +31,10 @@ module.exports = {
|
||||
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) {
|
||||
if (e.target !== e.currentTarget) {
|
||||
// end triggered by an animation on a child
|
||||
return
|
||||
}
|
||||
@@ -58,28 +52,16 @@ module.exports = {
|
||||
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) {
|
||||
@@ -123,7 +105,5 @@ module.exports = {
|
||||
// pass all className of the parent
|
||||
oldEl.className = newEl.className
|
||||
oldEl.appendChild(fragToAppend)
|
||||
|
||||
// oldEl.style.height = relevantHeight + "px"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user