mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 06:57:02 +08:00
Cleaning House (JS)
This commit is contained in:
@ -1,208 +0,0 @@
|
|||||||
/**
|
|
||||||
* The LeftRightMenuViewController makes it easy to have an interface
|
|
||||||
* with two hidden menus: one on the left, and one on the right.
|
|
||||||
*
|
|
||||||
* The main content supports dragging to show either panel, or the panel can be
|
|
||||||
* show/hidden through buttons elsewhere in the app.
|
|
||||||
*
|
|
||||||
* Either panel can be disabled based on the context in the app.
|
|
||||||
*/
|
|
||||||
(function(window, document, ion) {
|
|
||||||
ion.controllers = ion.controllers || {};
|
|
||||||
|
|
||||||
ion.controllers.LeftRightMenuViewController = function(options) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
this.animateClass = options.animateClass;
|
|
||||||
this.left = options.left;
|
|
||||||
this.leftWidth = options.leftWidth;
|
|
||||||
this.right = options.right;
|
|
||||||
this.rightWidth = options.rightWidth;
|
|
||||||
this.center = options.center;
|
|
||||||
this.isLeftEnabled = options.isLeftEnabled == undefined ? true : options.isLeftEnabled;
|
|
||||||
this.isRightEnabled = options.isRightEnabled == undefined ? true : options.isRightEnabled;
|
|
||||||
|
|
||||||
this._rightShowing = false;
|
|
||||||
this._leftShowing = false;
|
|
||||||
|
|
||||||
|
|
||||||
// Bind release and drag listeners
|
|
||||||
window.ion.onGesture('release', function(e) {
|
|
||||||
_this._endDrag(e);
|
|
||||||
}, this.center);
|
|
||||||
|
|
||||||
window.ion.onGesture('drag', function(e) {
|
|
||||||
_this._handleDrag(e);
|
|
||||||
}, this.center);
|
|
||||||
};
|
|
||||||
|
|
||||||
ion.controllers.LeftRightMenuViewController.prototype = {
|
|
||||||
setIsLeftEnabled: function(isLeftEnabled) {
|
|
||||||
this.isLeftEnabled = isLeftEnabled;
|
|
||||||
},
|
|
||||||
setIsRightEnabled: function(isRightEnabled) {
|
|
||||||
this.isRightEnabled = isRightEnabled;
|
|
||||||
},
|
|
||||||
toggleLeft: function() {
|
|
||||||
var openAmount = this.getOpenAmount();
|
|
||||||
if(openAmount > 0) {
|
|
||||||
this.openPercentage(0);
|
|
||||||
} else {
|
|
||||||
this.openPercentage(100);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleRight: function() {
|
|
||||||
var openAmount = this.getOpenAmount();
|
|
||||||
if(openAmount < 0) {
|
|
||||||
this.openPercentage(0);
|
|
||||||
} else {
|
|
||||||
this.openPercentage(-100);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getOpenAmount: function() {
|
|
||||||
var r = /translate3d\((-?\d+)px/;
|
|
||||||
var d = r.exec(this.center.style.webkitTransform);
|
|
||||||
|
|
||||||
if(d && d.length > 0) {
|
|
||||||
return parseInt(d[1]);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
getOpenRatio: function() {
|
|
||||||
var amount = this.getOpenAmount();
|
|
||||||
if(amount >= 0) {
|
|
||||||
return amount / this.leftWidth;
|
|
||||||
}
|
|
||||||
return amount / this.rightWidth;
|
|
||||||
},
|
|
||||||
openPercentage: function(percentage) {
|
|
||||||
var p = percentage / 100;
|
|
||||||
var maxLeft = this.leftWidth;
|
|
||||||
var maxRight = this.rightWidth;
|
|
||||||
if(percentage >= 0) {
|
|
||||||
this.openAmount(maxLeft * p);
|
|
||||||
} else {
|
|
||||||
this.openAmount(maxRight * p);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openAmount: function(amount) {
|
|
||||||
var maxLeft = this.leftWidth;
|
|
||||||
var maxRight = this.rightWidth;
|
|
||||||
|
|
||||||
// Check if we can move to that side, depending if the left/right panel is enabled
|
|
||||||
if((!this.isLeftEnabled && amount > 0) || (!this.isRightEnabled && amount < 0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((this._leftShowing && amount > maxLeft) || (this._rightShowing && amount < -maxRight)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.center.style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
|
||||||
|
|
||||||
if(amount >= 0) {
|
|
||||||
this._leftShowing = true;
|
|
||||||
this._rightShowing = false;
|
|
||||||
|
|
||||||
if(this.isRightEnabled) {
|
|
||||||
this.right.style.zIndex = -1;
|
|
||||||
}
|
|
||||||
if(this.isLeftEnabled) {
|
|
||||||
this.left.style.zIndex = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._rightShowing = true;
|
|
||||||
this._leftShowing = false;
|
|
||||||
if(this.isRightEnabled) {
|
|
||||||
this.right.style.zIndex = 0;
|
|
||||||
}
|
|
||||||
if(this.isLeftEnabled) {
|
|
||||||
this.left.style.zIndex = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
snapToRest: function(e) {
|
|
||||||
// We want to animate at the end of this
|
|
||||||
this.center.classList.add(this.animateClass);
|
|
||||||
this._isDragging = false;
|
|
||||||
|
|
||||||
// Check how much the panel is open after the drag, and
|
|
||||||
// what the drag velocity is
|
|
||||||
var ratio = this.getOpenRatio();
|
|
||||||
|
|
||||||
if(ratio == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var velocityThreshold = 0.3;
|
|
||||||
var velocityX = e.gesture.velocityX
|
|
||||||
var direction = e.gesture.direction;
|
|
||||||
|
|
||||||
// Less than half, going left
|
|
||||||
//if(ratio > 0 && ratio < 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
|
||||||
//this.openPercentage(0);
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Going right, less than half, too slow (snap back)
|
|
||||||
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
|
||||||
this.openPercentage(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Going left, more than half, too slow (snap back)
|
|
||||||
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
|
||||||
this.openPercentage(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Going left, less than half, too slow (snap back)
|
|
||||||
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
|
||||||
this.openPercentage(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Going right, more than half, too slow (snap back)
|
|
||||||
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
|
||||||
this.openPercentage(-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Going right, more than half, or quickly (snap open)
|
|
||||||
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
|
|
||||||
this.openPercentage(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Going left, more than half, or quickly (span open)
|
|
||||||
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
|
|
||||||
this.openPercentage(-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Snap back for safety
|
|
||||||
else {
|
|
||||||
this.openPercentage(0);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_endDrag: function(e) {
|
|
||||||
this.snapToRest(e);
|
|
||||||
},
|
|
||||||
_initDrag: function(e) {
|
|
||||||
this.center.classList.remove(this.animateClass);
|
|
||||||
this._isDragging = true;
|
|
||||||
this._startX = 0;
|
|
||||||
this._offsetX = 0;
|
|
||||||
this._lastX = 0;
|
|
||||||
},
|
|
||||||
_handleDrag: function(e) {
|
|
||||||
if(!this._isDragging) {
|
|
||||||
this._initDrag(e);
|
|
||||||
|
|
||||||
this._startX = e.gesture.touches[0].pageX;
|
|
||||||
this._lastX = this._startX;
|
|
||||||
|
|
||||||
this._offsetX = this.getOpenAmount();
|
|
||||||
}
|
|
||||||
//console.log('Dragging page', this._startX, this._lastX, this._offsetX, e);
|
|
||||||
var newX = this._offsetX + (this._lastX - this._startX);
|
|
||||||
|
|
||||||
this.openAmount(newX);
|
|
||||||
|
|
||||||
this._lastX = e.gesture.touches[0].pageX;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
(function(window, document, ion) {
|
|
||||||
ion.controllers = ion.controllers || {};
|
|
||||||
|
|
||||||
ion.controllers.TabController = function(options) {
|
|
||||||
this.viewControllers = [];
|
|
||||||
this.selectedViewController = null;
|
|
||||||
|
|
||||||
var tabChildren = options.tab.querySelectorAll('.tab-item');
|
|
||||||
console.log("Building from", tabChildren.length, "tab items");
|
|
||||||
for(var i = 0; i < tabChildren.length; i++) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ion.controllers.TabController.prototype = {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
(function(window, document, ion) {
|
|
||||||
ion.Button = function() {}
|
|
||||||
|
|
||||||
// Process an the touchstart event and if this is a button,
|
|
||||||
// add the .active class so Android will show depressed
|
|
||||||
// button states.
|
|
||||||
ion.Button.prototype._onTouchStart = function(event) {
|
|
||||||
console.log('Touch start!', event);
|
|
||||||
if(event.target && event.target.classList.contains('button')) {
|
|
||||||
event.target.classList.add('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Remove any active state on touch end/cancel/etc.
|
|
||||||
ion.Button.prototype._onTouchEnd = function(event) {
|
|
||||||
console.log('Touch end!', event);
|
|
||||||
if(event.target && event.target.classList.contains('button')) {
|
|
||||||
event.target.classList.remove('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Process the click? Set flag to not process other click events
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('touchstart', ion.Button.prototype._onTouchStart);
|
|
||||||
document.addEventListener('touchend', ion.Button.prototype._onTouchEnd);
|
|
||||||
document.addEventListener('touchcancel', ion.Button.prototype._onTouchEnd);
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
(function(window, document, ion) {
|
|
||||||
ion.List = function() {}
|
|
||||||
|
|
||||||
ion.List.prototype._TAB_ITEM_CLASS = 'tab-item';
|
|
||||||
|
|
||||||
ion.List.prototype._onTouchStart = function(event) {
|
|
||||||
console.log('Touch start!', event);
|
|
||||||
if(event.target && event.target.parentNode.classList.contains(this._TAB_ITEM_CLASS)) {
|
|
||||||
event.target.classList.add('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ion.List.prototype._onTouchEnd = function(event) {
|
|
||||||
console.log('Touch end!', event);
|
|
||||||
if(event.target && event.target.parentNode.classList.contains(this._TAB_ITEM_CLASS)) {
|
|
||||||
event.target.classList.remove('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('mousedown', ion.List.prototype._onTouchStart);
|
|
||||||
document.addEventListener('touchstart', ion.List.prototype._onTouchStart);
|
|
||||||
document.addEventListener('touchend', ion.List.prototype._onTouchEnd);
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
(function(window, document, ion) {
|
|
||||||
|
|
||||||
var
|
|
||||||
x,
|
|
||||||
isPanelOpen,
|
|
||||||
|
|
||||||
PANEL_ACTIVE = "ion-panel-active",
|
|
||||||
PANEL_ACTIVE_LEFT = "ion-panel-active-left",
|
|
||||||
PANEL_ACTIVE_RIGHT = "ion-panel-active-right",
|
|
||||||
|
|
||||||
PANEL_OPEN_LEFT = "ion-panel-left",
|
|
||||||
PANEL_OPEN_RIGHT = "ion-panel-right";
|
|
||||||
|
|
||||||
ion.Panel = {
|
|
||||||
|
|
||||||
toggle: function(panelId, options) {
|
|
||||||
if(isPanelOpen) {
|
|
||||||
this.close();
|
|
||||||
} else {
|
|
||||||
this.open(panelId, options);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
open: function(panelId, options) {
|
|
||||||
// see if there is an element with this id
|
|
||||||
var panel = document.getElementById(panelId);
|
|
||||||
if(panel) {
|
|
||||||
// this element is a panel, open it!
|
|
||||||
|
|
||||||
// remember that a panel is currently open
|
|
||||||
isPanelOpen = true;
|
|
||||||
|
|
||||||
// find all the panels that are or were once active
|
|
||||||
var panelsActive = document.getElementsByClassName(PANEL_ACTIVE);
|
|
||||||
|
|
||||||
// remove the panel-active css classes from each of the previously active panels
|
|
||||||
for(x=0; x<panelsActive.length; x++) {
|
|
||||||
panelsActive[x].classList.remove(PANEL_ACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// activate the panel we want open by adding the panel-active css classes
|
|
||||||
panel.classList.add(PANEL_ACTIVE);
|
|
||||||
|
|
||||||
// add to <body> that there is a panel open
|
|
||||||
if(options && options.direction === "right") {
|
|
||||||
panel.classList.add(PANEL_ACTIVE_RIGHT);
|
|
||||||
document.body.classList.add(PANEL_OPEN_RIGHT);
|
|
||||||
} else {
|
|
||||||
// left is the default
|
|
||||||
panel.classList.add(PANEL_ACTIVE_LEFT);
|
|
||||||
document.body.classList.add(PANEL_OPEN_LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
close: function() {
|
|
||||||
if(isPanelOpen) {
|
|
||||||
// there is a panel already open, so close it
|
|
||||||
isPanelOpen = false;
|
|
||||||
|
|
||||||
// remove from <body> so that no panels should be open
|
|
||||||
var className = document.body.className;
|
|
||||||
className = className.replace(PANEL_OPEN_LEFT, "").replace(PANEL_OPEN_RIGHT, "").trim();
|
|
||||||
document.body.className = className;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener("popstate", ion.Panel.close, false);
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
(function(window, document, ion) {
|
|
||||||
ion.Tabs = function() {}
|
|
||||||
|
|
||||||
ion.Tabs.prototype._TAB_ITEM_CLASS = 'tab-item';
|
|
||||||
|
|
||||||
ion.Tabs.prototype._onTouchStart = function(event) {
|
|
||||||
console.log('Touch start!', event);
|
|
||||||
if(event.target && event.target.parentNode.classList.contains(this._TAB_ITEM_CLASS)) {
|
|
||||||
event.target.classList.add('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ion.Tabs.prototype._onTouchEnd = function(event) {
|
|
||||||
console.log('Touch end!', event);
|
|
||||||
if(event.target && event.target.parentNode.classList.contains(this._TAB_ITEM_CLASS)) {
|
|
||||||
event.target.classList.remove('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('mousedown', ion.Tabs.prototype._onTouchStart);
|
|
||||||
document.addEventListener('touchstart', ion.Tabs.prototype._onTouchStart);
|
|
||||||
document.addEventListener('touchend', ion.Tabs.prototype._onTouchEnd);
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
(function(window, document, ion) {
|
|
||||||
|
|
||||||
// Loop through each element in the DOM and collect up all
|
|
||||||
// the templates it has. A template either has data to supply
|
|
||||||
// to others, or it needs data from another template
|
|
||||||
function initTemplates() {
|
|
||||||
var
|
|
||||||
x,
|
|
||||||
el,
|
|
||||||
tmp,
|
|
||||||
emptyTemplates = [],
|
|
||||||
container,
|
|
||||||
templateElements;
|
|
||||||
|
|
||||||
// collect up all the templates currently in the DOM
|
|
||||||
templateElements = document.body.querySelectorAll("[data-template]");
|
|
||||||
for(x=0; x<templateElements.length; x++) {
|
|
||||||
el = templateElements[x];
|
|
||||||
|
|
||||||
if(el.dataset.template && !el.tSet) {
|
|
||||||
// this element is either supplying template
|
|
||||||
// data or it needs to be filled with template data
|
|
||||||
|
|
||||||
if(el.innerHTML == "") {
|
|
||||||
// this element is requesting to have its innerHTML
|
|
||||||
// built from a template already set
|
|
||||||
emptyTemplates.push(el);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// this element contains innerHTML which should be used
|
|
||||||
// as a template for other elements. Save this template
|
|
||||||
// data for future use.
|
|
||||||
|
|
||||||
// Save only in sessionStorage, which maintains a storage area that's
|
|
||||||
// available for the duration of the page session. A page session
|
|
||||||
// lasts for as long as the browser is open and survives over page
|
|
||||||
// reloads and restores. Opening a page in a new tab or window will
|
|
||||||
// cause a new session to be initiated.
|
|
||||||
sessionStorage.setItem("t:" + el.dataset.template, el.outerHTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember that this is set so we don't bother doing all this
|
|
||||||
// code again for the same element in the future
|
|
||||||
el.tSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go through each empty template and build it up with existing template data
|
|
||||||
for(x=0; x<emptyTemplates.length; x++) {
|
|
||||||
el = emptyTemplates[x];
|
|
||||||
tmp = sessionStorage.getItem("t:" + el.dataset.template);
|
|
||||||
if(tmp) {
|
|
||||||
// we've got template data, plug it into this element's innerHTML
|
|
||||||
container = document.createElement("div");
|
|
||||||
container.innerHTML = tmp;
|
|
||||||
|
|
||||||
el.parentNode.replaceChild(container.children[0].cloneNode(true), el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ion.on("ready", initTemplates);
|
|
||||||
ion.on("pagecreate", initTemplates);
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
(function(window, document, ion) {
|
|
||||||
|
|
||||||
function initTransitions(e) {
|
|
||||||
var data = e.detail.data;
|
|
||||||
|
|
||||||
// build a new main element to hold the new html
|
|
||||||
var newMainElement = document.createElement("main");
|
|
||||||
newMainElement.innerHTML = data.main;
|
|
||||||
|
|
||||||
// get the old main element, which will be the first one
|
|
||||||
var oldMainElement = document.querySelector("main");
|
|
||||||
|
|
||||||
// decide how to do the page transition
|
|
||||||
if(data.transition === "slide-from-left") {
|
|
||||||
slideStart(newMainElement, oldMainElement, "left");
|
|
||||||
} else {
|
|
||||||
// No animation. Nothing fancy here
|
|
||||||
noTransition(newMainElement, oldMainElement, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function noTransition(newMainElement, oldMainElement, data) {
|
|
||||||
// entirely replace the old element, no transition
|
|
||||||
oldMainElement.parentNode.replaceChild(newMainElement, oldMainElement);
|
|
||||||
ion.trigger("pagecreate", {
|
|
||||||
url: data.url,
|
|
||||||
title: data.title
|
|
||||||
});
|
|
||||||
ion.trigger("pageview");
|
|
||||||
}
|
|
||||||
|
|
||||||
function slideStart(newMainElement, oldMainElement, fromDirection) {
|
|
||||||
// copy what the main element currently looks like into a document fragment
|
|
||||||
// make all the changes to the document fragment, then replace the
|
|
||||||
// old main with the two new ones. Both the old and new main will be
|
|
||||||
// in the DOM, but their CSS classes will do the transitioning for us
|
|
||||||
}
|
|
||||||
|
|
||||||
ion.on("pageloaded", initTransitions);
|
|
||||||
|
|
||||||
})(this, document, ion = this.ion || {});
|
|
||||||
Reference in New Issue
Block a user