mirror of
https://github.com/moparisthebest/app-UI
synced 2024-08-13 16:54:00 -04:00
1ab501ca87
this is pre-alpha quality code, but getting better by the day
298 lines
8.7 KiB
JavaScript
298 lines
8.7 KiB
JavaScript
|
|
|
|
var ViewNavigator = function( target ) {
|
|
|
|
this.supportsBackKey = true; //phonegap on android only
|
|
this.animating = false;
|
|
this.animationX = 150;
|
|
this.animationDuration = 350;
|
|
this.history = [];
|
|
this.scroller = null;
|
|
this.headerPadding = 0;
|
|
|
|
this.uniqueId = this.guid();
|
|
|
|
var regexp = new RegExp("Windows Phone OS 7");
|
|
this.winPhone = (navigator.userAgent.search(regexp) >= 0);
|
|
|
|
this.rootElement = $('<div class="viewNavigator_root"></div>');
|
|
this.header = $('<div class="viewNavigator_header"></div>');
|
|
this.content = $('<div class="viewNavigator_content" id="contentRoot"></div>');
|
|
this.rootElement.append( this.header );
|
|
this.rootElement.append( this.content );
|
|
|
|
this.parent = $( target );
|
|
|
|
var self = this;
|
|
$(window).resize( function(event){ self.resizeContent() } );
|
|
$(this.parent).resize( function(event){ self.resizeContent() } );
|
|
this.parent.append( this.rootElement );
|
|
|
|
if ( window.viewNavigators == null || window.viewNavigators == undefined ) {
|
|
window.viewNavigators = {};
|
|
}
|
|
window.viewNavigators[ this.uniqueId ] = this;
|
|
|
|
if ( typeof PhoneGap != 'undefined' ) {
|
|
//backKeyViewNavigators is only used in PhoneGap on Android
|
|
if ( window.backKeyViewNavigators == null || window.backKeyViewNavigators == undefined ) {
|
|
window.backKeyViewNavigators = [];
|
|
}
|
|
if ( this.supportsBackKey ) {
|
|
window.backKeyViewNavigators.push( this );
|
|
}
|
|
}
|
|
}
|
|
|
|
ViewNavigator.prototype.replaceView = function( viewDescriptor ) {
|
|
if (this.animating)
|
|
return;
|
|
viewDescriptor.animation = "pushEffect"
|
|
|
|
//this is a hack to mimic behavior of pushView, then pop off the "current" from the history
|
|
this.history.push( viewDescriptor );
|
|
this.updateView( viewDescriptor );
|
|
this.history.pop();
|
|
this.history.pop();
|
|
this.history.push( viewDescriptor );
|
|
}
|
|
|
|
ViewNavigator.prototype.pushView = function( viewDescriptor ) {
|
|
if (this.animating)
|
|
return;
|
|
viewDescriptor.animation = "pushEffect"
|
|
this.history.push( viewDescriptor );
|
|
this.updateView( viewDescriptor );
|
|
}
|
|
|
|
ViewNavigator.prototype.popView = function() {
|
|
|
|
if (this.animating || this.history.length <= 1 )
|
|
return;
|
|
|
|
var currentViewDescriptor = this.history[ this.history.length-1];
|
|
if ( currentViewDescriptor.backCallback ) {
|
|
currentViewDescriptor.backCallback();
|
|
}
|
|
|
|
this.history.pop();
|
|
var viewDescriptor = this.history[ this.history.length-1 ];
|
|
viewDescriptor.animation = "popEffect"
|
|
this.updateView( viewDescriptor );
|
|
}
|
|
|
|
ViewNavigator.prototype.setHeaderPadding = function( amount ) {
|
|
this.headerPadding = amount;
|
|
if ( this.headerBacklink ) {
|
|
this.headerBacklink.css("left", amount);
|
|
}
|
|
}
|
|
|
|
ViewNavigator.prototype.updateView = function( viewDescriptor ) {
|
|
|
|
this.animating = true;
|
|
this.contentPendingRemove = this.contentViewHolder;
|
|
this.headerContentPendingRemove = this.headerContent;
|
|
|
|
this.headerContent = $('<div class="viewNavigator_headerContent"></div>');
|
|
|
|
this.headerTitle = $("<div class='viewNavigator_header_title'>" + viewDescriptor.title + "</div>");
|
|
this.headerContent.append( this.headerTitle );
|
|
|
|
var linkGuid = this.guid();
|
|
if ( viewDescriptor.backLabel ) {
|
|
this.headerBacklink = $('<li class="viewNavigator_header_backlink backLinkButton" id="link' + linkGuid + '" onclick="window.viewNavigators[\'' + this.uniqueId + '\'].popView()">'+ viewDescriptor.backLabel + '</li>');
|
|
this.headerContent.append( this.headerBacklink );
|
|
|
|
//this is for proper handling in splitviewnavigator
|
|
this.setHeaderPadding( this.headerPadding );
|
|
}
|
|
|
|
var id = this.guid();
|
|
this.contentViewHolder = $('<div class="viewNavigator_contentHolder" id="' + id + '"></div>');
|
|
this.contentViewHolder.append( viewDescriptor.view );
|
|
this.resizeContent();
|
|
|
|
|
|
$(this.contentPendingRemove).click(function(){ return false; });
|
|
|
|
if ( viewDescriptor.animation == "popEffect" ) {
|
|
|
|
this.contentViewHolder.css( "left", -this.contentViewHolder.width() );
|
|
this.contentViewHolder.css( "opacity", 1 );
|
|
this.content.prepend( this.contentViewHolder );
|
|
|
|
this.headerContent.css( "left", -this.animationX );
|
|
this.headerContent.css( "opacity", 0 );
|
|
this.header.append( this.headerContent );
|
|
|
|
|
|
this.contentPendingRemove.animate({
|
|
left:this.contentViewHolder.width(),
|
|
opacity:1,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration, this.animationCompleteHandler(this.contentPendingRemove, this.headerContentPendingRemove, this.headerContent, this.contentViewHolder ));
|
|
|
|
//remove this to change back
|
|
this.contentViewHolder.animate({
|
|
left:0,
|
|
opacity:1,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration);
|
|
|
|
this.headerContentPendingRemove.animate({
|
|
left:this.animationX,
|
|
opacity:0,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration );
|
|
|
|
this.headerContent.animate({
|
|
left:0,
|
|
opacity:1,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration );
|
|
}
|
|
else if ( this.history.length > 1 ) {
|
|
|
|
this.contentViewHolder.css( "left", this.contentViewHolder.width() );
|
|
this.contentViewHolder.css( "opacity", 1 );
|
|
|
|
this.content.append( this.contentViewHolder );
|
|
|
|
this.headerContent.css( "left", this.animationX );
|
|
this.headerContent.css( "opacity", 0 );
|
|
this.header.append( this.headerContent );
|
|
|
|
this.contentViewHolder.animate({
|
|
left:0,
|
|
opacity:1,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration, this.animationCompleteHandler(this.contentPendingRemove, this.headerContentPendingRemove, this.headerContent, this.contentViewHolder ));
|
|
|
|
this.contentPendingRemove.animate({
|
|
left:-this.contentViewHolder.width(),
|
|
opacity:1,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration);
|
|
|
|
this.headerContent.animate({
|
|
left:0,
|
|
opacity:1,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration );
|
|
|
|
this.headerContentPendingRemove.animate({
|
|
left:-this.animationX,
|
|
opacity:0,
|
|
avoidTransforms:false,
|
|
useTranslate3d: true
|
|
}, this.animationDuration );
|
|
}
|
|
else {
|
|
this.contentViewHolder.css( "left", 0 );
|
|
this.contentViewHolder.css( "opacity", 1 );
|
|
this.content.append( this.contentViewHolder );
|
|
|
|
this.headerContent.css( "left", 0 );
|
|
this.headerContent.css( "opacity", 1 );
|
|
this.header.append( this.headerContent );
|
|
this.animating = false;
|
|
this.resetScroller();
|
|
}
|
|
|
|
if ( viewDescriptor.backLabel ) {
|
|
new NoClickDelay( this.headerBacklink.get()[0] );
|
|
}
|
|
}
|
|
|
|
|
|
ViewNavigator.prototype.resetScroller = function() {
|
|
|
|
var id = this.contentViewHolder.attr( "id" );
|
|
|
|
if ( !this.winPhone ) {
|
|
if ( this.scroller != null ) {
|
|
this.scroller.destroy();
|
|
}
|
|
if ( id ) {
|
|
var self = this;
|
|
setTimeout( function() { self.scroller = new iScroll( id ); }, 10 );
|
|
//this.scroller = new iScroll( id );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ViewNavigator.prototype.refreshScroller = function() {
|
|
|
|
if ( !this.winPhone ) {
|
|
if ( this.scroller != null ) {
|
|
this.scroller.refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
ViewNavigator.prototype.animationCompleteHandler = function(removalTarget, headerRemovalTarget, headerView, contentView) {
|
|
var self = this;
|
|
return function() {
|
|
self.animating = false;
|
|
self.resetScroller();
|
|
if ( removalTarget ) {
|
|
removalTarget.unbind( "click" );
|
|
removalTarget.remove();
|
|
}
|
|
if ( headerRemovalTarget ) {
|
|
headerRemovalTarget.unbind( "click" );
|
|
headerRemovalTarget.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
ViewNavigator.prototype.resizeContent = function(event) {
|
|
|
|
var targetWidth = this.parent.width();
|
|
if ( this.headerContent )
|
|
this.headerContent.width( targetWidth );
|
|
if ( this.contentViewHolder )
|
|
this.contentViewHolder.width( targetWidth );
|
|
}
|
|
|
|
|
|
//GUID logic from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
|
|
|
|
ViewNavigator.prototype.S4 = function() {
|
|
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
|
}
|
|
|
|
ViewNavigator.prototype.guid = function() {
|
|
return (this.S4() + this.S4() + "-" + this.S4() + "-4" + this.S4().substr(0,3) + "-" + this.S4() + "-" + this.S4() + this.S4() + this.S4()).toLowerCase();
|
|
}
|
|
|
|
|
|
|
|
/* PHONEGAP INTEGRATION */
|
|
|
|
//android+phonegap specific back button support - will only work if phonegap is used on android (www.phonegap.com)
|
|
if ( typeof PhoneGap != 'undefined' ) {
|
|
document.addEventListener("deviceready", onDeviceReady, false);
|
|
}
|
|
|
|
function onDeviceReady() {
|
|
document.addEventListener("backbutton", onBackKey, false);
|
|
}
|
|
|
|
function onBackKey( event ) {
|
|
event.preventDefault();
|
|
window.viewNavigator.popView();
|
|
for ( var x=0; x<window.backKeyViewNavigators.length; x++ ) {
|
|
window.backKeyViewNavigators[x].popView();
|
|
}
|
|
}
|