Build mobile apps with simple HTML, CSS, and JS components. http://goratchet.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

422 lines
10 KiB

// modal
!(function () {
'use strict';
var findModals = function (target) {
var i;
var modals = document.querySelectorAll('a');
for (; target && target !== document; target = target.parentNode) {
for (i = modals.length; i--;) {
if (modals[i] === target) {
return target;
}
}
}
};
var getModal = function (event) {
var modalToggle = findModals(event.target);
if (modalToggle && modalToggle.hash && -1 === modalToggle.hash.indexOf('/')) {
return document.querySelector(modalToggle.hash);
}
};
window.addEventListener('touchend', function (event) {
var modal = getModal(event);
if (modal) {
if (modal && modal.classList.contains('modal')) {
modal.classList.toggle('active');
}
event.preventDefault(); // prevents rewriting url (apps can still use hash values in url)
}
});
}());
// popover
!(function () {
'use strict';
var popover;
var findPopovers = function (target) {
var i;
var popovers = document.querySelectorAll('a');
for (; target && target !== document; target = target.parentNode) {
for (i = popovers.length; i--;) {
if (popovers[i] === target) {
return target;
}
}
}
};
var onPopoverHidden = function () {
popover.style.display = 'none';
popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
};
// HACK to hide programatically
var hide = function(e){
e.preventDefault()
e.stopPropagation()
popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
popover.classList.remove('visible');
popover.parentNode.removeChild(backdrop);
};
var backdrop = (function () {
var element = document.createElement('div');
element.classList.add('backdrop');
element.addEventListener('click', hide, false);
return element;
}());
var getPopover = function (e) {
var anchor = findPopovers(e.target);
if (!anchor || !anchor.hash || (anchor.hash.indexOf('/') > 0)) {
return;
}
try {
popover = document.querySelector(anchor.hash);
} catch (error) {
popover = null;
}
if (popover === null) {
return;
}
if (!popover || !popover.classList.contains('popover')) {
return;
}
return popover;
};
var showHidePopover = function (e) {
var popover = getPopover(e);
if (popover) {
// if clicked fast enough, function hide may not call at all
popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
e.preventDefault()
e.stopPropagation()
}else{
// HACK, click anyway to close existing popover
popover = document.querySelector('.popover.visible');
if (popover) hide(e);
return;
}
popover.style.display = 'block';
popover.offsetHeight;
popover.classList.add('visible');
popover.parentNode.appendChild(backdrop);
};
window.addEventListener('click', showHidePopover);
}());
// segmented-controllers
!(function () {
'use strict';
var getTarget = function (target) {
var i;
var segmentedControls = document.querySelectorAll('.segmented-control .control-item');
for (; target && target !== document; target = target.parentNode) {
for (i = segmentedControls.length; i--;) {
if (segmentedControls[i] === target) {
return target;
}
}
}
};
window.addEventListener('touchend', function (e) {
var activeTab;
var activeBodies;
var targetBody;
var targetTab = getTarget(e.target);
var className = 'active';
var classSelector = '.' + className;
if (!targetTab) {
return;
}
activeTab = targetTab.parentNode.querySelector(classSelector);
if (activeTab) {
activeTab.classList.remove(className);
}
targetTab.classList.add(className);
if (!targetTab.hash) {
return;
}
targetBody = document.querySelector(targetTab.hash);
if (!targetBody) {
return;
}
activeBodies = targetBody.parentNode.querySelectorAll(classSelector);
for (var i = 0; i < activeBodies.length; i++) {
activeBodies[i].classList.remove(className);
}
targetBody.classList.add(className);
});
window.addEventListener('click', function (e) { if (getTarget(e.target)) {e.preventDefault();} });
}());
// slider
!(function () {
'use strict';
var pageX;
var pageY;
var slider;
var deltaX;
var deltaY;
var offsetX;
var lastSlide;
var startTime;
var resistance;
var sliderWidth;
var slideNumber;
var isScrolling;
var scrollableArea;
var getSlider = function (target) {
var i;
var sliders = document.querySelectorAll('.slider > .slide-group');
for (; target && target !== document; target = target.parentNode) {
for (i = sliders.length; i--;) {
if (sliders[i] === target) {
return target;
}
}
}
};
var getScroll = function () {
if ('webkitTransform' in slider.style) {
var translate3d = slider.style.webkitTransform.match(/translate3d\(([^,]*)/);
var ret = translate3d ? translate3d[1] : 0;
return parseInt(ret, 10);
}
};
var setSlideNumber = function (offset) {
var round = offset ? (deltaX < 0 ? 'ceil' : 'floor') : 'round';
slideNumber = Math[round](getScroll() / (scrollableArea / slider.children.length));
slideNumber += offset;
slideNumber = Math.min(slideNumber, 0);
slideNumber = Math.max(-(slider.children.length - 1), slideNumber);
};
var onTouchStart = function (e) {
slider = getSlider(e.target);
if (!slider) {
return;
}
var firstItem = slider.querySelector('.slide');
scrollableArea = firstItem.offsetWidth * slider.children.length;
isScrolling = undefined;
sliderWidth = slider.offsetWidth;
resistance = 1;
lastSlide = -(slider.children.length - 1);
startTime = +new Date();
pageX = e.touches[0].pageX;
pageY = e.touches[0].pageY;
deltaX = 0;
deltaY = 0;
setSlideNumber(0);
slider.style['-webkit-transition-duration'] = 0;
};
var onTouchMove = function (e) {
if (e.touches.length > 1 || !slider) {
return; // Exit if a pinch || no slider
}
deltaX = e.touches[0].pageX - pageX;
deltaY = e.touches[0].pageY - pageY;
pageX = e.touches[0].pageX;
pageY = e.touches[0].pageY;
if (typeof isScrolling === 'undefined') {
isScrolling = Math.abs(deltaY) > Math.abs(deltaX);
}
if (isScrolling) {
return;
}
offsetX = (deltaX / resistance) + getScroll();
e.preventDefault();
resistance = slideNumber === 0 && deltaX > 0 ? (pageX / sliderWidth) + 1.25 :
slideNumber === lastSlide && deltaX < 0 ? (Math.abs(pageX) / sliderWidth) + 1.25 : 1;
slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
};
var onTouchEnd = function (e) {
if (!slider || isScrolling) {
return;
}
setSlideNumber(
(+new Date()) - startTime < 1000 && Math.abs(deltaX) > 15 ? (deltaX < 0 ? -1 : 1) : 0
);
offsetX = slideNumber * sliderWidth;
slider.style['-webkit-transition-duration'] = '.2s';
slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
e = new CustomEvent('slide', {
detail: { slideNumber: Math.abs(slideNumber) },
bubbles: true,
cancelable: true
});
slider.parentNode.dispatchEvent(e);
};
window.addEventListener('touchstart', onTouchStart);
window.addEventListener('touchmove', onTouchMove);
window.addEventListener('touchend', onTouchEnd);
}());
// toggle
!(function () {
'use strict';
var start = {};
var touchMove = false;
var distanceX = false;
var toggle = false;
var findToggle = function (target) {
var i;
var toggles = document.querySelectorAll('.toggle');
for (; target && target !== document; target = target.parentNode) {
for (i = toggles.length; i--;) {
if (toggles[i] === target) {
return target;
}
}
}
};
window.addEventListener('touchstart', function (e) {
e = e.originalEvent || e;
toggle = findToggle(e.target);
if (!toggle) {
return;
}
var handle = toggle.querySelector('.toggle-handle');
var toggleWidth = toggle.clientWidth;
var handleWidth = handle.clientWidth;
var offset = toggle.classList.contains('active') ? (toggleWidth - handleWidth) : 0;
start = { pageX : e.touches[0].pageX - offset, pageY : e.touches[0].pageY };
touchMove = false;
});
window.addEventListener('touchmove', function (e) {
e = e.originalEvent || e;
if (e.touches.length > 1) {
return; // Exit if a pinch
}
if (!toggle) {
return;
}
var handle = toggle.querySelector('.toggle-handle');
var current = e.touches[0];
var toggleWidth = toggle.clientWidth;
var handleWidth = handle.clientWidth;
var offset = toggleWidth - handleWidth;
touchMove = true;
distanceX = current.pageX - start.pageX;
if (Math.abs(distanceX) < Math.abs(current.pageY - start.pageY)) {
return;
}
e.preventDefault();
if (distanceX < 0) {
return (handle.style.webkitTransform = 'translate3d(0,0,0)');
}
if (distanceX > offset) {
return (handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)');
}
handle.style.webkitTransform = 'translate3d(' + distanceX + 'px,0,0)';
toggle.classList[(distanceX > (toggleWidth / 2 - handleWidth / 2)) ? 'add' : 'remove']('active');
});
window.addEventListener('touchend', function (e) {
if (!toggle) {
return;
}
var handle = toggle.querySelector('.toggle-handle');
var toggleWidth = toggle.clientWidth;
var handleWidth = handle.clientWidth;
var offset = (toggleWidth - handleWidth);
var slideOn = (!touchMove && !toggle.classList.contains('active')) || (touchMove && (distanceX > (toggleWidth / 2 - handleWidth / 2)));
if (slideOn) {
handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)';
} else {
handle.style.webkitTransform = 'translate3d(0,0,0)';
}
toggle.classList[slideOn ? 'add' : 'remove']('active');
e = new CustomEvent('toggle', {
detail: { isActive: slideOn },
bubbles: true,
cancelable: true
});
toggle.dispatchEvent(e);
touchMove = false;
toggle = false;
});
}());