summaryrefslogtreecommitdiffstats
path: root/web/_static/jsuites/jsuites.mobile.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/_static/jsuites/jsuites.mobile.js')
-rw-r--r--web/_static/jsuites/jsuites.mobile.js1016
1 files changed, 1016 insertions, 0 deletions
diff --git a/web/_static/jsuites/jsuites.mobile.js b/web/_static/jsuites/jsuites.mobile.js
new file mode 100644
index 0000000..e152da1
--- /dev/null
+++ b/web/_static/jsuites/jsuites.mobile.js
@@ -0,0 +1,1016 @@
+jSuites.app = (function(el, options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ path: 'views',
+ onbeforechangepage: null,
+ onchangepage: null,
+ onbeforecreatepage: null,
+ oncreatepage: null,
+ onerrorpage: null,
+ onloadpage: null,
+ toolbar: null,
+ route: null,
+ ident: null,
+ detachHiddenPages: false
+ }
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // App
+ el.classList.add('japp');
+
+ // Toolbar
+ var toolbar = document.createElement('div');
+
+ obj.setToolbar = function(o) {
+ if (o) {
+ obj.options.toolbar = o;
+ }
+ // Force application
+ obj.options.toolbar.app = obj;
+ // Set toolbar
+ obj.toolbar = jSuites.toolbar(toolbar, obj.options.toolbar);
+ // Add to the DOM
+ el.appendChild(toolbar);
+ }
+
+ obj.hideToolbar = function() {
+ if (toolbar.style.display == '') {
+ toolbar.style.display = 'none';
+ }
+ }
+
+ obj.showToolbar = function() {
+ if (toolbar.style.display == 'none') {
+ toolbar.style.display = '';
+ }
+ }
+
+ /**
+ * Page identification
+ */
+ var ident = function(route) {
+ route = route.split('?')[0];
+
+ if (typeof(obj.options.ident) == 'function') {
+ var ret = obj.options.ident(route);
+ if (typeof(ret) !== 'undefined') {
+ return ret;
+ }
+ }
+
+ return route;
+ }
+
+ /*
+ * Parse javascript from an element
+ */
+ var parseScript = function(element) {
+ // Get javascript
+ var script = element.getElementsByTagName('script');
+ // Run possible inline scripts
+ for (var i = 0; i < script.length; i++) {
+ // Get type
+ var type = script[i].getAttribute('type');
+ if (! type || type == 'text/javascript' || type == 'text/loader') {
+ eval(script[i].text);
+ }
+ }
+ }
+
+ /**
+ * Pages
+ */
+ obj.pages = function() {
+ /**
+ * Create or access a page
+ */
+ var component = function(route, o, callback, element) {
+ var options = {};
+
+ if (o) {
+ if (typeof(o) == 'object') {
+ var options = o;
+ } else {
+ if (! callback && typeof(o) == 'function') {
+ callback = o;
+ }
+ }
+ }
+
+ if (typeof(obj.options.route) == 'function') {
+ route = obj.options.route(route, options);
+ }
+
+ if (route === false) {
+ console.error('JSUITES: Permission denied');
+ } else {
+ // Query string does not make part in the route
+ options.ident = ident(route);
+ // Current Route
+ options.route = route;
+
+ // If exists just open
+ var page = component.container[options.ident];
+ if (page) {
+ page.options.closed = 0;
+ component.show(page, options, callback);
+ } else {
+ // Closed
+ options.closed = options.closed ? 1 : 0;
+
+ // New page url
+ if (! options.url) {
+ options.url = obj.options.path + options.ident + '.html';
+ }
+
+ // Create new page
+ page = component.create(options, callback, element);
+
+ // Container
+ component.container[options.ident] = page;
+ }
+ }
+ }
+
+ /**
+ * Create a new page
+ */
+ component.create = function(o, callback, fromElement) {
+ // Create page
+ if (fromElement) {
+ var page = fromElement;
+ } else {
+ var page = document.createElement('div');
+ }
+
+ page.classList.add('page');
+
+ // Keep options
+ page.options = o ? o : {};
+
+ // Create page overwrite
+ var ret = null;
+ if (typeof(obj.options.onbeforecreatepage) == 'function') {
+ ret = obj.options.onbeforecreatepage(obj, page);
+ if (ret === false) {
+ return false;
+ }
+ }
+
+ var success = function(result) {
+ // Remove to avoid id conflicts
+ if (component.current && obj.options.detachHiddenPages == true) {
+ while (component.element.children[0]) {
+ component.element.children[0].parentNode.removeChild(component.element.children[0]);
+ }
+ }
+
+ if (! component.current) {
+ component.element.appendChild(page);
+ } else {
+ component.element.insertBefore(page, component.current.nextSibling);
+ }
+
+ // Open page
+ if (result) {
+ page.innerHTML = result;
+ }
+
+ // Get javascript
+ try {
+ parseScript(page);
+ } catch (e) {
+ console.log(e);
+ }
+
+ // Create page overwrite
+ if (typeof(obj.options.oncreatepage) == 'function') {
+ obj.options.oncreatepage(obj, page, result);
+ }
+
+ // Push to refresh controls
+ if (typeof(page.options.onpush) == 'function') {
+ jSuites.refresh(page, page.options.onpush);
+ }
+
+ // Navbar
+ if (page.querySelector('.navbar')) {
+ page.classList.add('with-navbar');
+ }
+
+ // Global onload callback
+ if (typeof(obj.options.onloadpage) == 'function') {
+ obj.options.onloadpage(obj, page);
+ }
+
+ // Specific online callback
+ if (typeof(o.onload) == 'function') {
+ o.onload(page);
+ }
+
+ // Always hidden when created
+ page.style.display = 'none';
+
+ // Show page
+ if (! page.options.closed) {
+ component.show(page, o, callback);
+ }
+ }
+
+ // URL
+ if (o.url.indexOf('?') == -1) {
+ var url = o.url + '?';
+ } else {
+ var url = o.url + '&';
+ }
+
+ if (fromElement) {
+ success();
+ } else {
+ jSuites.ajax({
+ url: url + 'ts=' + new Date().getTime(),
+ method: 'GET',
+ dataType: 'html',
+ queue: true,
+ success: success,
+ error: function(a,b) {
+ if (typeof(obj.options.onerrorpage) == 'function') {
+ obj.options.onerrorpage(obj, page, a, b);
+ }
+
+ component.destroy(page);
+ }
+ });
+ }
+
+ return page;
+ }
+
+ component.show = function(page, o, callback) {
+ if (o) {
+ if (o.onenter) {
+ page.options.onenter = o.onenter;
+ }
+ if (o.onleave) {
+ page.options.onleave = o.onleave;
+ }
+ if (o.route) {
+ page.options.route = o.route;
+ }
+ }
+
+ // Add history
+ if (! o || ! o.ignoreHistory) {
+ // Route
+ if (o && o.route) {
+ var route = o.route;
+ } else {
+ var route = page.options.route;
+ }
+ // Add history
+ window.history.pushState({ route: route }, page.options.title, route);
+ }
+
+ var pageIsReady = function() {
+ if (component.current) {
+ component.current.style.display = 'none';
+
+ if (component.current && obj.options.detachHiddenPages == true) {
+ if (component.current.parentNode) {
+ component.current.parentNode.removeChild(component.current);
+ }
+ }
+ }
+
+ // New page
+ if (typeof(obj.options.onchangepage) == 'function') {
+ obj.options.onchangepage(obj, page, component.current, o);
+ }
+
+ // Enter event
+ if (typeof(page.options.onenter) == 'function') {
+ page.options.onenter(obj, page, component.current);
+ }
+
+ // Callback
+ if (typeof(callback) == 'function') {
+ callback(obj, page);
+ }
+
+ // Current page
+ component.current = page;
+ }
+
+ // Append page in case was detached
+ if (! page.parentNode) {
+ component.element.appendChild(page);
+ }
+
+ if (component.current) {
+ // Show page
+ page.style.display = '';
+
+ if (component.current != page) {
+ var a = Array.prototype.indexOf.call(component.element.children, component.current);
+ var b = Array.prototype.indexOf.call(component.element.children, page);
+
+ // Before leave the page
+ if (typeof(obj.options.onbeforechangepage) == 'function') {
+ var ret = obj.options.onbeforechangepage(obj, component.current, page, o);
+ if (ret === false) {
+ return false;
+ }
+ }
+
+ // Leave event
+ if (typeof(page.options.onleave) == 'function') {
+ page.options.onleave(obj, component.current);
+ }
+
+ // Animation only on mobile
+ var rect = component.element.getBoundingClientRect();
+
+ // Move to the top
+ window.scrollTo({ top: 0 });
+
+ // Page is ready
+ if (rect.width < 800 && obj.options.detachHiddenPages == false) {
+ jSuites.animation.slideLeft(component.element, (a < b ? 0 : 1), function() {
+ if (component.current != page) {
+ pageIsReady();
+ }
+ });
+ } else {
+ if (component.current != page) {
+ pageIsReady();
+ }
+ }
+ } else {
+ component.current = null;
+
+ pageIsReady();
+ }
+ } else {
+ // Show
+ page.style.display = '';
+
+ // Page is ready
+ pageIsReady();
+ }
+
+ // Select toolbar item
+ if (page.options.toolbarItem) {
+ obj.toolbar.selectItem(page.options.toolbarItem);
+ }
+ }
+
+ /**
+ * Get a page by route
+ */
+ component.get = function(route) {
+ var key = ident(route);
+ if (component.container[key]) {
+ return component.container[key];
+ }
+ }
+
+ /**
+ * Reset the page container
+ */
+ component.reset = function() {
+ // Container
+ component.element.innerHTML = '';
+ // Current
+ component.current = null;
+ }
+
+ /**
+ * Reset the page container
+ */
+ component.destroy = function(page) {
+ if (page) {
+ if (page.parentNode) {
+ page.remove();
+ }
+ delete component.container[page.options.ident];
+ } else {
+ // Reset container
+ component.reset();
+ // Destroy references
+ component.container = {};
+ }
+ }
+
+ /**
+ * Page container controller
+ */
+ component.container = {};
+
+ component.init = function() {
+ /**
+ * Pages DOM container
+ */
+ var pagesContainer = el.querySelector('.pages');
+ if (pagesContainer) {
+ component.element = pagesContainer;
+ } else {
+ component.element = document.createElement('div');
+ component.element.className = 'pages';
+ }
+
+ // Prefetched content
+ var current = null;
+ if (el.innerHTML) {
+ // Create with the prefetched content
+ current = document.createElement('div');
+ while (el.childNodes[0]) {
+ current.appendChild(el.childNodes[0]);
+ }
+ }
+
+ // Append page container to the application
+ el.appendChild(component.element);
+
+ // Go to the current page
+ if (current) {
+ component(window.location.pathname, null, null, current);
+ }
+ }
+
+ return component;
+ }();
+
+ // Start page object
+ obj.pages.init();
+
+ /**
+ * Panel methods
+ */
+ obj.panel = function() {
+ var panel = null;
+
+ var component = function(route, o) {
+ if (! panel) {
+ // Create element
+ panel = document.createElement('div');
+ panel.classList.add('panel');
+ panel.classList.add('panel-left');
+ panel.style.display = 'none';
+
+ // Bind to the app
+ el.appendChild(panel);
+ }
+
+ // Remote content
+ if (route) {
+ // URL
+ if (! o) {
+ o = {};
+ }
+ if (! o.url) {
+ o.url = obj.options.path + route + '.html';
+ }
+ // Route
+ o.route = route;
+ // Panel
+ panel.options = o;
+
+ // Request remote data
+ jSuites.ajax({
+ url: o.url,
+ method: 'GET',
+ dataType: 'html',
+ success: function(result) {
+ // Create page overwrite
+ var ret = null;
+ if (typeof(obj.options.oncreatepage) == 'function') {
+ ret = obj.options.oncreatepage(obj, panel, result);
+ }
+
+ // Ignore create page actions
+ if (ret !== false) {
+ // Open page
+ panel.innerHTML = result;
+ // Get javascript
+ parseScript(page);
+ }
+ }
+ });
+ } else {
+ component.show();
+ }
+ }
+
+ component.show = function() {
+ // Show panel
+ if (panel && panel.style.display == 'none') {
+ panel.style.display = '';
+ // Add animation
+ if (panel.classList.contains('panel-left')) {
+ jSuites.animation.slideLeft(panel, 1);
+ } else {
+ jSuites.animation.slideRight(panel, 1);
+ }
+ }
+ }
+
+ component.hide = function() {
+ if (panel && panel.style.display == '') {
+ // Animation
+ if (panel.classList.contains('panel-left')) {
+ jSuites.animation.slideLeft(panel, 0, function() {
+ panel.style.display = 'none';
+ });
+ } else {
+ jSuites.animation.slideRight(panel, 0, function() {
+ panel.animation.style.display = 'none';
+ });
+ }
+ }
+ }
+
+ component.get = function() {
+ return panel;
+ }
+
+ component.destroy = function() {
+ el.removeChild(panel);
+ panel = null;
+ }
+
+ return component;
+ }();
+
+ // Actionsheet
+ obj.actionsheet = jSuites.actionsheet(el, obj);
+
+ var controlSwipeLeft = function(e) {
+ var element = jSuites.findElement(e.target, 'option');
+
+ if (element && element.querySelector('.option-actions')) {
+ element.scrollTo({
+ left: 100,
+ behavior: 'smooth'
+ });
+ } else {
+ obj.panel.hide();
+ }
+ }
+
+ var controlSwipeRight = function(e) {
+ var element = jSuites.findElement(e.target, 'option');
+ if (element && element.querySelector('.option-actions')) {
+ element.scrollTo({
+ left: 0,
+ behavior: 'smooth'
+ });
+ } else {
+ obj.panel.show();
+ }
+ }
+
+ var action = null;
+
+ var clicked = function(e) {
+ // Grouped options
+ if (e.target.classList.contains('option-title')) {
+ if (e.target.classList.contains('selected')) {
+ e.target.classList.remove('selected');
+ } else {
+ e.target.classList.add('selected');
+ }
+ }
+
+ // Grouped buttons
+ if (e.target.parentNode && e.target.parentNode.classList && e.target.parentNode.classList.contains('jbuttons-group')) {
+ for (var j = 0; j < e.target.parentNode.children.length; j++) {
+ e.target.parentNode.children[j].classList.remove('selected');
+ }
+ e.target.classList.add('selected');
+ }
+
+ // App links
+ var tmp = jSuites.findElement(e.target, function(el) {
+ return el.tagName == 'A' && el.getAttribute('href') ? el : false;
+ });
+
+ if (tmp) {
+ var h = tmp.getAttribute('href');
+ if (h.substr(0,2) == '//' || h.substr(0,4) == 'http' || tmp.classList.contains('link') || h.indexOf('#') >= 0) {
+ action = null;
+ } else {
+ var p = jSuites.getPosition(e);
+ action = {
+ h: h,
+ element: tmp,
+ target: e.target,
+ x: p[0],
+ y: p[1],
+ };
+
+ // Cancel click operation in 400ms
+ setTimeout(function() {
+ action = null;
+ }, 400);
+ }
+ }
+ }
+
+ var actionDown = function(e) {
+ e = e || window.event;
+ if (e.buttons) {
+ var mouseButton = e.buttons;
+ } else if (e.button) {
+ var mouseButton = e.button;
+ } else {
+ var mouseButton = e.which;
+ }
+
+ if (mouseButton < 2) {
+ clicked(e);
+ }
+ }
+
+ var actionUp = function(e) {
+ obj.actionsheet.close();
+ // Action
+ if (action) {
+ var p = jSuites.getPosition(e);
+ // If mouse move cancel the click action
+ if (Math.abs(action.x - p[0]) < 5 && Math.abs(action.y - p[1]) < 5) {
+ // Go to the page
+ obj.pages(action.h);
+ }
+ // Prevent default
+ e.preventDefault();
+ action = null;
+ }
+ }
+
+ el.addEventListener('swipeleft', controlSwipeLeft);
+ el.addEventListener('swiperight', controlSwipeRight);
+
+ if ('ontouchstart' in document.documentElement === true) {
+ document.addEventListener('touchstart', actionDown);
+ document.addEventListener('touchend', actionUp);
+ } else {
+ document.addEventListener('mousedown', actionDown);
+ document.addEventListener('click', actionUp);
+ }
+
+ window.onpopstate = function(e) {
+ if (e.state && e.state.route) {
+ if (obj.pages.get(e.state.route)) {
+ obj.pages(e.state.route, { ignoreHistory: true });
+ } else {
+ window.location.href = e.state.route;
+ }
+ } else {
+ window.location.reload();
+ }
+ }
+
+ if (obj.options.toolbar) {
+ obj.setToolbar();
+ }
+
+ el.app = obj;
+
+ return obj;
+});
+
+jSuites.actionsheet = (function(el, component) {
+ var obj = function(options) {
+ // Reset container
+ actionContent.innerHTML = '';
+
+ // Create new elements
+ for (var i = 0; i < options.length; i++) {
+ var actionGroup = document.createElement('div');
+ actionGroup.className = 'jactionsheet-group';
+
+ for (var j = 0; j < options[i].length; j++) {
+ var v = options[i][j];
+ var actionItem = document.createElement('div');
+ var actionInput = document.createElement('input');
+ actionInput.type = 'button';
+ actionInput.value = v.title;
+ if (v.className) {
+ actionInput.className = v.className;
+ }
+ if (v.onclick) {
+ actionInput.event = v.onclick;
+ actionInput.onclick = function() {
+ this.event(component, this);
+ }
+ }
+ if (v.action == 'cancel') {
+ actionInput.style.color = 'red';
+ }
+ actionItem.appendChild(actionInput);
+ actionGroup.appendChild(actionItem);
+ }
+
+ actionContent.appendChild(actionGroup);
+ }
+
+ // Show
+ actionsheet.style.display = '';
+
+ // Animation
+ jSuites.animation.slideBottom(actionContent, true);
+ }
+
+ obj.close = function() {
+ if (actionsheet.style.display != 'none') {
+ // Remove any existing actionsheet
+ jSuites.animation.slideBottom(actionContent, false, function() {
+ actionsheet.style.display = 'none';
+ });
+ }
+ }
+
+ obj.get = function() {
+ return actionsheet;
+ }
+
+ // Init action sheet
+ var actionsheet = document.createElement('div');
+ actionsheet.className = 'jactionsheet';
+ actionsheet.style.display = 'none';
+
+ var actionContent = document.createElement('div');
+ actionContent.className = 'jactionsheet-content';
+ actionsheet.appendChild(actionContent);
+
+ // Append actionsheet container to the application
+ el.appendChild(actionsheet);
+
+ el.actionsheet = obj;
+
+ return obj;
+});
+
+jSuites.dialog = (function() {
+ var obj = {};
+ obj.options = {};
+
+ var dialog = null;
+ var dialogTitle = null;
+ var dialogHeader = null;
+ var dialogMessage = null;
+ var dialogFooter = null;
+ var dialogContainer = null;
+ var dialogConfirm = null;
+ var dialogConfirmButton = null;
+ var dialogCancel = null;
+ var dialogCancelButton = null;
+
+ obj.open = function(options) {
+ if (! jSuites.dialog.hasEvents) {
+ obj.init();
+
+ jSuites.dialog.hasEvents = true;
+ }
+ obj.options = options;
+
+ if (obj.options.title) {
+ dialogTitle.innerHTML = obj.options.title;
+ }
+
+ if (obj.options.message) {
+ dialogMessage.innerHTML = obj.options.message;
+ }
+
+ if (! obj.options.confirmLabel) {
+ obj.options.confirmLabel = 'OK';
+ }
+ dialogConfirmButton.value = obj.options.confirmLabel;
+
+ if (! obj.options.cancelLabel) {
+ obj.options.cancelLabel = 'Cancel';
+ }
+ dialogCancelButton.value = obj.options.cancelLabel;
+
+ if (obj.options.type == 'confirm') {
+ dialogCancelButton.parentNode.style.display = '';
+ } else {
+ dialogCancelButton.parentNode.style.display = 'none';
+ }
+
+ // Append element to the app
+ dialog.style.opacity = 100;
+
+ // Append to the page
+ if (jSuites.el) {
+ jSuites.el.appendChild(dialog);
+ } else {
+ document.body.appendChild(dialog);
+ }
+
+ // Focus
+ dialog.focus();
+
+ // Show
+ setTimeout(function() {
+ dialogContainer.style.opacity = 100;
+ }, 0);
+ }
+
+ obj.close = function() {
+ dialog.style.opacity = 0;
+ dialogContainer.style.opacity = 0;
+ setTimeout(function() {
+ dialog.remove();
+ }, 100);
+ }
+
+ obj.init = function() {
+ dialog = document.createElement('div');
+ dialog.setAttribute('tabindex', '901');
+ dialog.className = 'jdialog';
+ dialog.id = 'dialog';
+
+ dialogHeader = document.createElement('div');
+ dialogHeader.className = 'jdialog-header';
+
+ dialogTitle = document.createElement('div');
+ dialogTitle.className = 'jdialog-title';
+ dialogHeader.appendChild(dialogTitle);
+
+ dialogMessage = document.createElement('div');
+ dialogMessage.className = 'jdialog-message';
+ dialogHeader.appendChild(dialogMessage);
+
+ dialogFooter = document.createElement('div');
+ dialogFooter.className = 'jdialog-footer';
+
+ dialogContainer = document.createElement('div');
+ dialogContainer.className = 'jdialog-container';
+ dialogContainer.appendChild(dialogHeader);
+ dialogContainer.appendChild(dialogFooter);
+
+ // Confirm
+ dialogConfirm = document.createElement('div');
+ dialogConfirmButton = document.createElement('input');
+ dialogConfirmButton.value = obj.options.confirmLabel;
+ dialogConfirmButton.type = 'button';
+ dialogConfirmButton.onclick = function() {
+ if (typeof(obj.options.onconfirm) == 'function') {
+ obj.options.onconfirm();
+ }
+ obj.close();
+ };
+ dialogConfirm.appendChild(dialogConfirmButton);
+ dialogFooter.appendChild(dialogConfirm);
+
+ // Cancel
+ dialogCancel = document.createElement('div');
+ dialogCancelButton = document.createElement('input');
+ dialogCancelButton.value = obj.options.cancelLabel;
+ dialogCancelButton.type = 'button';
+ dialogCancelButton.onclick = function() {
+ if (typeof(obj.options.oncancel) == 'function') {
+ obj.options.oncancel();
+ }
+ obj.close();
+ }
+ dialogCancel.appendChild(dialogCancelButton);
+ dialogFooter.appendChild(dialogCancel);
+
+ // Dialog
+ dialog.appendChild(dialogContainer);
+
+ document.addEventListener('keydown', function(e) {
+ if (e.which == 13) {
+ if (typeof(obj.options.onconfirm) == 'function') {
+ jSuites.dialog.options.onconfirm();
+ }
+ obj.close();
+ } else if (e.which == 27) {
+ obj.close();
+ }
+ });
+ }
+
+ return obj;
+})();
+
+jSuites.confirm = (function(message, onconfirm) {
+ if (jSuites.getWindowWidth() < 800) {
+ jSuites.dialog.open({
+ type: 'confirm',
+ message: message,
+ title: 'Confirmation',
+ onconfirm: onconfirm,
+ });
+ } else {
+ if (confirm(message)) {
+ onconfirm();
+ }
+ }
+});
+
+
+jSuites.refresh = (function(el, options) {
+ // Controls
+ var touchPosition = null;
+ var pushToRefresh = null;
+
+ // Page touch move
+ var pageTouchMove = function(e, page) {
+ if (typeof(page.options.onpush) == 'function') {
+ if (page.scrollTop < 5) {
+ if (! touchPosition) {
+ touchPosition = {};
+ touchPosition.x = e.touches[0].clientX;
+ touchPosition.y = e.touches[0].clientY;
+ }
+
+ var height = e.touches[0].clientY - touchPosition.y;
+ if (height > 70) {
+ if (! pushToRefresh.classList.contains('ready')) {
+ pushToRefresh.classList.add('ready');
+ }
+ } else {
+ if (pushToRefresh.classList.contains('ready')) {
+ pushToRefresh.classList.remove('ready');
+ }
+ pushToRefresh.style.height = height + 'px';
+
+ if (height > 20) {
+ if (! pushToRefresh.classList.contains('holding')) {
+ pushToRefresh.classList.add('holding');
+ page.insertBefore(pushToRefresh, page.firstChild);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Page touch end
+ var pageTouchEnd = function(e, page) {
+ if (typeof(page.options.onpush) == 'function') {
+ // Remove holding
+ pushToRefresh.classList.remove('holding');
+ // Refresh or not refresh
+ if (! pushToRefresh.classList.contains('ready')) {
+ // Reset and not refresh
+ pushToRefresh.style.height = '';
+ obj.hide();
+ } else {
+ pushToRefresh.classList.remove('ready');
+ // Loading indication
+ setTimeout(function() {
+ obj.hide();
+ }, 1000);
+
+ // Refresh
+ if (typeof(page.options.onpush) == 'function') {
+ page.options.onpush(page);
+ }
+ }
+ }
+ }
+
+ var obj = function(element, callback) {
+ if (! pushToRefresh) {
+ pushToRefresh = document.createElement('div');
+ pushToRefresh.className = 'jrefresh';
+ }
+
+ element.addEventListener('touchmove', function(e) {
+ pageTouchMove(e, element);
+ });
+ element.addEventListener('touchend', function(e) {
+ pageTouchEnd(e, element);
+ });
+ if (! element.options) {
+ element.options = {};
+ }
+ if (typeof(callback) == 'function') {
+ element.options.onpush = callback;
+ }
+ }
+
+ obj.hide = function() {
+ if (pushToRefresh.parentNode) {
+ pushToRefresh.parentNode.removeChild(pushToRefresh);
+ }
+ touchPosition = null;
+ }
+
+ return obj;
+})();