Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions lib/attr-persistence.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var $ = require('jquery');
var camelCase = require('camelcase');

/**
* Helps persist class names or css rules across calls to morphdom.
Expand All @@ -24,25 +24,28 @@ function persistAttr(fromEl, toEl, type) {
if (type !== 'class' && type !== 'css') {
throw new Error('unsupported type ' + type);
}
var $from = $(fromEl);
var attr = 'data-persist-' + type;
var toPersist = $from.attr(attr);
var toPersist = fromEl.getAttribute(attr);
if (!toPersist) {
return toEl;
}
toPersist = toPersist.split(',');
var $to = $(toEl);
for (var i = 0; i < toPersist.length; i++) {
var curClass = toPersist[i];
switch (type) {
case 'class':
$to.toggleClass(toPersist[i], $from.hasClass(curClass));
if (fromEl.classList.contains(curClass)) {
toEl.classList.add(toPersist[i]);
} else {
toEl.classList.remove(toPersist[i]);
}
break;
case 'css':
// Avoid persisting styles that are computed and not strictly
// defined on the style attribute
if ($from.get(0).style[$.camelCase(curClass)]) {
$to.css(curClass, $from.css(curClass));
var style = camelCase(curClass);
if (fromEl.style[style]) {
toEl.style[style] = fromEl.style[style];
}
break;
default:
Expand Down
73 changes: 41 additions & 32 deletions lib/css-transition-group.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';

var $ = require('jquery');

var TRANSITION_ATTR = 'data-transition-name';
var TRANSITION_ENTER_ATTR = 'data-transition-enter';
var TRANSITION_LEAVE_ATTR = 'data-transition-leave';
Expand Down Expand Up @@ -38,92 +36,88 @@ module.exports.plugin = function () {
* value of the specified attribute does not parse as an integer.
* @memberOf cssTransitionGroup
* @param {String} attr name of attribute from which to fetch an integer.
* @param {jQuery} $node jQuery collection containing the node in question.
* @param {Element} node jQuery collection containing the node in question.
* @return {Number} number representing the value of the attr for the
* $node
*/
function getTransitionTimeout(attr, $node, defaultDuration) {
function getTransitionTimeout(attr, node, defaultDuration) {
if (typeof defaultDuration === 'undefined') {
defaultDuration = NaN;
}
var transitionTimeout = $node.attr(attr);
var transitionTimeout = node.getAttribute(attr);
transitionTimeout = transitionTimeout ? parseInt(transitionTimeout, 10) : defaultDuration;
if (isNaN(transitionTimeout)) {
var e = Error(attr + ' must be an integer');
e.forNode = $node.get(0);
e.forNode = node;
throw e;
}
return transitionTimeout;
}

function onBeforeNodeAdded(node) {
var $node = $(node);
var transitionName = $node.attr(TRANSITION_ATTR);
var transitionName = node.getAttribute && node.getAttribute(TRANSITION_ATTR);
if (!transitionName) {
return node;
}
var transitionIsEnabled = $node.attr(TRANSITION_ENTER_ATTR);
var transitionIsEnabled = node.getAttribute(TRANSITION_ENTER_ATTR);
if (transitionIsEnabled === 'false') {
return;
}
var transitionEnterTimeout = getTransitionTimeout(
TRANSITION_ENTER_DELAY_ATTR, $node, 65
TRANSITION_ENTER_DELAY_ATTR, node, 65
);
var transitionDuration = getTransitionTimeout(
TRANSITION_ENTER_DURATION_ATTR, $node
TRANSITION_ENTER_DURATION_ATTR, node
);

$node.addClass(transitionName + ENTER_SUFFIX);
node.classList.add(transitionName + ENTER_SUFFIX);
function applyEnterTransition() {
$node.addClass(transitionName + ENTER_SUFFIX + ACTIVE_SUFFIX);
node.classList.add(transitionName + ENTER_SUFFIX + ACTIVE_SUFFIX);
setTimeout(function () {
$node.removeClass(transitionName + ENTER_SUFFIX);
$node.removeClass(transitionName + ENTER_SUFFIX + ACTIVE_SUFFIX);
$node.trigger(transitionName + ENTER_SUFFIX + COMPLETE_SUFFIX);
node.classList.remove(transitionName + ENTER_SUFFIX);
node.classList.remove(transitionName + ENTER_SUFFIX + ACTIVE_SUFFIX);
dispatchEvent(node, transitionName + ENTER_SUFFIX + COMPLETE_SUFFIX);
}, transitionDuration);
}
setTimeout(applyEnterTransition, transitionEnterTimeout);
return node;
}

function onBeforeNodeDiscarded(node) {
var $node = $(node);
var transitionName = $node.attr(TRANSITION_ATTR);
var transitionName = node.getAttribute && node.getAttribute(TRANSITION_ATTR);
if (!transitionName) {
return true;
}
var transitionIsEnabled = $node.attr(TRANSITION_LEAVE_ATTR);
var transitionIsEnabled = node.getAttribute(TRANSITION_LEAVE_ATTR);
if (transitionIsEnabled === 'false') {
return true;
}
var transitionLeaveTimeout = getTransitionTimeout(
TRANSITION_LEAVE_DELAY_ATTR, $node, 65
TRANSITION_LEAVE_DELAY_ATTR, node, 65
);
var transitionDuration = getTransitionTimeout(
TRANSITION_LEAVE_DURATION_ATTR, $node
TRANSITION_LEAVE_DURATION_ATTR, node
);

node._totalDuration = transitionLeaveTimeout + transitionDuration;
node._leaveStart = new Date().getTime();
$node.addClass(transitionName + LEAVE_SUFFIX);
node.classList.add(transitionName + LEAVE_SUFFIX);
clearTimeout(node._leaveTimeout);
node._leaveTimeout = setTimeout(applyLeaveTransition, transitionLeaveTimeout);
function applyLeaveTransition() {
$node.addClass(transitionName + LEAVE_SUFFIX + ACTIVE_SUFFIX);
node.classList.add(transitionName + LEAVE_SUFFIX + ACTIVE_SUFFIX);
node._leaveTimeout = setTimeout(handleLeaveTransitionComplete, transitionDuration);
}
function handleLeaveTransitionComplete() {
node._leaveTimeout = null;
$node.trigger(transitionName + LEAVE_SUFFIX + COMPLETE_SUFFIX);
$node.remove();
dispatchEvent(node, transitionName + LEAVE_SUFFIX + COMPLETE_SUFFIX);
node.parentNode.removeChild(node);
}
return false;
}

function onBeforeElUpdated(fromEl, toEl) {
var $from = $(fromEl);
var $to = $(toEl);
var transitionName = $from.attr(TRANSITION_ATTR);
var transitionName = fromEl.getAttribute && fromEl.getAttribute(TRANSITION_ATTR);
if (!transitionName) {
return toEl;
}
Expand All @@ -133,11 +127,11 @@ function onBeforeElUpdated(fromEl, toEl) {
// is now intended to be in the dom. Cancel and reverse the exit transition.
if (fromEl._leaveTimeout) {
fromEl._leaveTimeout = clearTimeout(fromEl._leaveTimeout);
$from.addClass(transitionName + LEAVE_SUFFIX);
$from.removeClass(transitionName + LEAVE_SUFFIX + ACTIVE_SUFFIX);
fromEl.classList.add(transitionName + LEAVE_SUFFIX);
fromEl.classList.remove(transitionName + LEAVE_SUFFIX + ACTIVE_SUFFIX);
var remaining = fromEl._totalDuration - (new Date().getTime() - fromEl._leaveStart);
fromEl._leaveTimeout = setTimeout(function () {
$from.removeClass(transitionName + LEAVE_SUFFIX);
fromEl.classList.remove(transitionName + LEAVE_SUFFIX);
}, remaining);
}
var transitionClassesToPersist = [
Expand All @@ -148,7 +142,22 @@ function onBeforeElUpdated(fromEl, toEl) {
];
for (var i = 0; i < transitionClassesToPersist.length; i++) {
var name = transitionClassesToPersist[i];
$to.toggleClass(name, $from.hasClass(name));
if (fromEl.classList.contains(name)) {
toEl.classList.add(name);
} else {
toEl.classList.remove(name);
}
}
return toEl;
}

function dispatchEvent(node, event) {
var evt;
try {
evt = new Event(event, {bubbles: true});
} catch (e) {
evt = document.createEvent('Event');
evt.initEvent(event, true, true);
}
node.dispatchEvent(evt);
}
20 changes: 18 additions & 2 deletions lib/input-persistence.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
'use strict';

var $ = require('jquery');
var Element = window.Element;

// @source: MDN
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function (s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}

/**
* There exists a possible race condition where the following conditions are
Expand Down Expand Up @@ -35,7 +51,7 @@ var $ = require('jquery');
module.exports.plugin = function () {
return {
onBeforeElUpdated: function (el) {
return !$(el).is('input[type=text]:focus,input[type=number]:focus');
return !el.matches('input[type=text]:focus,input[type=number]:focus');
}
};
};
59 changes: 31 additions & 28 deletions lib/transition-element-movement.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Motivation for transitioning positional changes inspired by
// https://medium.com/developers-writing/animating-the-unanimatable-1346a5aab3cd

var $ = require('jquery');

var TRANSITION_ATTR = 'data-transition-motion';
var TRANSITION_MOTION_DURATION_ATTR = 'data-transition-motion-duration';
var TRANSITION_MOTION_CLASS_ATTR = 'data-transition-motion-class';
Expand All @@ -19,9 +17,7 @@ var DEFAULT_TRANSITION_MOTION_CLASS = 'transition-motion';
module.exports.plugin = function () {
return {
onBeforeElUpdated: function onBeforeElUpdated(fromEl, toEl) {
var $from = $(fromEl);
var $to = $(toEl);
var transitionName = $from.attr(TRANSITION_ATTR);
var transitionName = fromEl.getAttribute(TRANSITION_ATTR);
if (!transitionName) {
return toEl;
}
Expand All @@ -36,16 +32,14 @@ module.exports.plugin = function () {
// If we've already done this once, $from.css('transform') will have
// a value. If that is the case, we copy it from $from to $to and
// return
if ($from.css('transform') !== 'none') {
$to.css({
transform: $from.css('transform')
});
if (getTransform(fromEl)) {
setTransform(toEl, getTransform(fromEl));
return toEl;
}
var activateMotionTransitionClass = $from.attr(TRANSITION_MOTION_CLASS_ATTR) ||
var activateMotionTransitionClass = fromEl.getAttribute(TRANSITION_MOTION_CLASS_ATTR) ||
DEFAULT_TRANSITION_MOTION_CLASS;

var motionDuration = $from.attr(TRANSITION_MOTION_DURATION_ATTR);
var motionDuration = fromEl.getAttribute(TRANSITION_MOTION_DURATION_ATTR);
motionDuration = parseInt(motionDuration, 10);
if (isNaN(motionDuration)) {
throw new Error(
Expand Down Expand Up @@ -74,29 +68,38 @@ module.exports.plugin = function () {
// the dom. Thus, at this point of the code execution, the state
// of `fromEl === (the state of toEl)` when the
// `onBeforeElUpdated` method returned.
$from.css({
height: previousPosition.height,
width: previousPosition.width,
transform: 'translate(' + deltaX + 'px ,' +
deltaY + 'px)'
});
fromEl.style.height = previousPosition.height + 'px';
fromEl.style.width = previousPosition.width + 'px';
setTransform(fromEl, 'translate(' + deltaX + 'px ,' + deltaY + 'px)');
window.requestAnimationFrame(function () {
$from.addClass(activateMotionTransitionClass);
$from.css({
transform: '',
height: newPosition.height,
width: newPosition.width
});
fromEl.classList.add(activateMotionTransitionClass);
setTransform(fromEl, '');
fromEl.style.height = newPosition.height + 'px';
fromEl.style.width = newPosition.width + 'px';
setTimeout(function () {
$from.removeClass(activateMotionTransitionClass);
$from.css({
height: '',
width: ''
});
fromEl.classList.remove(activateMotionTransitionClass);
fromEl.style.height = '';
fromEl.style.width = '';
}, motionDuration);
});
});
return toEl;
}
};
};

function setTransform(element, transform) {
element.style.webkitTransform = transform;
element.style.MozTransform = transform;
element.style.msTransform = transform;
element.style.OTransform = transform;
element.style.transform = transform;
}

function getTransform(element) {
return element.style.webkitTransform ||
element.style.MozTransform ||
element.style.msTransform ||
element.style.OTransform ||
element.style.transform || '';
}
Loading