Files
pjax/lib/switches.js
2017-12-19 15:56:48 -05:00

130 lines
4.5 KiB
JavaScript

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) {
oldEl.outerHTML = newEl.outerHTML
this.onSwitch()
},
innerHTML: function(oldEl, newEl) {
oldEl.innerHTML = newEl.innerHTML
oldEl.className = newEl.className
this.onSwitch()
},
switchElementsAlt: function(oldEl, newEl) {
oldEl.innerHTML = newEl.innerHTML
// Copy attributes from the new element to the old one
if (newEl.hasAttributes()) {
const attrs = newEl.attributes;
for (var i = 0; i < attrs.length; i++) {
oldEl.attributes.setNamedItem(attrs[i])
}
}
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"
}
}