Upgrade jQuery mobile to beta1
[busui.git] / js / jquery.mobile-1.0b1.js
blob:a/js/jquery.mobile-1.0b1.js -> blob:b/js/jquery.mobile-1.0b1.js
  /*!
  * jQuery Mobile v1.0b1
  * http://jquerymobile.com/
  *
  * Copyright 2010, jQuery Project
  * Dual licensed under the MIT or GPL Version 2 licenses.
  * http://jquery.org/license
  */
  /*!
  * jQuery UI Widget @VERSION
  *
  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
  * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Widget
  */
  (function( $, undefined ) {
   
  // jQuery 1.4+
  if ( $.cleanData ) {
  var _cleanData = $.cleanData;
  $.cleanData = function( elems ) {
  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  $( elem ).triggerHandler( "remove" );
  }
  _cleanData( elems );
  };
  } else {
  var _remove = $.fn.remove;
  $.fn.remove = function( selector, keepData ) {
  return this.each(function() {
  if ( !keepData ) {
  if ( !selector || $.filter( selector, [ this ] ).length ) {
  $( "*", this ).add( [ this ] ).each(function() {
  $( this ).triggerHandler( "remove" );
  });
  }
  }
  return _remove.call( $(this), selector, keepData );
  });
  };
  }
   
  $.widget = function( name, base, prototype ) {
  var namespace = name.split( "." )[ 0 ],
  fullName;
  name = name.split( "." )[ 1 ];
  fullName = namespace + "-" + name;
   
  if ( !prototype ) {
  prototype = base;
  base = $.Widget;
  }
   
  // create selector for plugin
  $.expr[ ":" ][ fullName ] = function( elem ) {
  return !!$.data( elem, name );
  };
   
  $[ namespace ] = $[ namespace ] || {};
  $[ namespace ][ name ] = function( options, element ) {
  // allow instantiation without initializing for simple inheritance
  if ( arguments.length ) {
  this._createWidget( options, element );
  }
  };
   
  var basePrototype = new base();
  // we need to make the options hash a property directly on the new instance
  // otherwise we'll modify the options hash on the prototype that we're
  // inheriting from
  // $.each( basePrototype, function( key, val ) {
  // if ( $.isPlainObject(val) ) {
  // basePrototype[ key ] = $.extend( {}, val );
  // }
  // });
  basePrototype.options = $.extend( true, {}, basePrototype.options );
  $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
  namespace: namespace,
  widgetName: name,
  widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
  widgetBaseClass: fullName
  }, prototype );
   
  $.widget.bridge( name, $[ namespace ][ name ] );
  };
   
  $.widget.bridge = function( name, object ) {
  $.fn[ name ] = function( options ) {
  var isMethodCall = typeof options === "string",
  args = Array.prototype.slice.call( arguments, 1 ),
  returnValue = this;
   
  // allow multiple hashes to be passed on init
  options = !isMethodCall && args.length ?
  $.extend.apply( null, [ true, options ].concat(args) ) :
  options;
   
  // prevent calls to internal methods
  if ( isMethodCall && options.charAt( 0 ) === "_" ) {
  return returnValue;
  }
   
  if ( isMethodCall ) {
  this.each(function() {
  var instance = $.data( this, name );
  if ( !instance ) {
  throw "cannot call methods on " + name + " prior to initialization; " +
  "attempted to call method '" + options + "'";
  }
  if ( !$.isFunction( instance[options] ) ) {
  throw "no such method '" + options + "' for " + name + " widget instance";
  }
  var methodValue = instance[ options ].apply( instance, args );
  if ( methodValue !== instance && methodValue !== undefined ) {
  returnValue = methodValue;
  return false;
  }
  });
  } else {
  this.each(function() {
  var instance = $.data( this, name );
  if ( instance ) {
  instance.option( options || {} )._init();
  } else {
  $.data( this, name, new object( options, this ) );
  }
  });
  }
   
  return returnValue;
  };
  };
   
  $.Widget = function( options, element ) {
  // allow instantiation without initializing for simple inheritance
  if ( arguments.length ) {
  this._createWidget( options, element );
  }
  };
   
  $.Widget.prototype = {
  widgetName: "widget",
  widgetEventPrefix: "",
  options: {
  disabled: false
  },
  _createWidget: function( options, element ) {
  // $.widget.bridge stores the plugin instance, but we do it anyway
  // so that it's stored even before the _create function runs
  $.data( element, this.widgetName, this );
  this.element = $( element );
  this.options = $.extend( true, {},
  this.options,
  this._getCreateOptions(),
  options );
   
  var self = this;
  this.element.bind( "remove." + this.widgetName, function() {
  self.destroy();
  });
   
  this._create();
  this._trigger( "create" );
  this._init();
  },
  _getCreateOptions: function() {
  var options = {};
  if ( $.metadata ) {
  options = $.metadata.get( element )[ this.widgetName ];
  }
  return options;
  },
  _create: function() {},
  _init: function() {},
   
  destroy: function() {
  this.element
  .unbind( "." + this.widgetName )
  .removeData( this.widgetName );
  this.widget()
  .unbind( "." + this.widgetName )
  .removeAttr( "aria-disabled" )
  .removeClass(
  this.widgetBaseClass + "-disabled " +
  "ui-state-disabled" );
  },
   
  widget: function() {
  return this.element;
  },
   
  option: function( key, value ) {
  var options = key;
   
  if ( arguments.length === 0 ) {
  // don't return a reference to the internal hash
  return $.extend( {}, this.options );
  }
   
  if (typeof key === "string" ) {
  if ( value === undefined ) {
  return this.options[ key ];
  }
  options = {};
  options[ key ] = value;
  }
   
  this._setOptions( options );
   
  return this;
  },
  _setOptions: function( options ) {
  var self = this;
  $.each( options, function( key, value ) {
  self._setOption( key, value );
  });
   
  return this;
  },
  _setOption: function( key, value ) {
  this.options[ key ] = value;
   
  if ( key === "disabled" ) {
  this.widget()
  [ value ? "addClass" : "removeClass"](
  this.widgetBaseClass + "-disabled" + " " +
  "ui-state-disabled" )
  .attr( "aria-disabled", value );
  }
   
  return this;
  },
   
  enable: function() {
  return this._setOption( "disabled", false );
  },
  disable: function() {
  return this._setOption( "disabled", true );
  },
   
  _trigger: function( type, event, data ) {
  var callback = this.options[ type ];
   
  event = $.Event( event );
  event.type = ( type === this.widgetEventPrefix ?
  type :
  this.widgetEventPrefix + type ).toLowerCase();
  data = data || {};
   
  // copy original event properties over to the new event
  // this would happen if we could call $.event.fix instead of $.Event
  // but we don't have a way to force an event to be fixed multiple times
  if ( event.originalEvent ) {
  for ( var i = $.event.props.length, prop; i; ) {
  prop = $.event.props[ --i ];
  event[ prop ] = event.originalEvent[ prop ];
  }
  }
   
  this.element.trigger( event, data );
   
  return !( $.isFunction(callback) &&
  callback.call( this.element[0], event, data ) === false ||
  event.isDefaultPrevented() );
  }
  };
   
  })( jQuery );
  /*
  * jQuery Mobile Framework : widget factory extentions for mobile
  * Copyright (c) jQuery Project
  * Dual licensed under the MIT or GPL Version 2 licenses.
  * http://jquery.org/license
  */
  (function($, undefined ) {
   
  $.widget( "mobile.widget", {
  _getCreateOptions: function() {
  var elem = this.element,
  options = {};
  $.each( this.options, function( option ) {
  var value = elem.jqmData( option.replace( /[A-Z]/g, function( c ) {
  return "-" + c.toLowerCase();
  } ) );
  if ( value !== undefined ) {
  options[ option ] = value;
  }
  });
  return options;
  }
  });
   
  })( jQuery );
  /*
  * jQuery Mobile Framework : resolution and CSS media query related helpers and behavior
  * Copyright (c) jQuery Project
  * Dual licensed under the MIT or GPL Version 2 licenses.
  * http://jquery.org/license
  */
  (function($, undefined ) {
   
  var $window = $(window),
  $html = $( "html" ),
   
  //media-query-like width breakpoints, which are translated to classes on the html element
  resolutionBreakpoints = [320,480,768,1024];
   
   
  /* $.mobile.media method: pass a CSS media type or query and get a bool return
  note: this feature relies on actual media query support for media queries, though types will work most anywhere
  examples:
  $.mobile.media('screen') //>> tests for screen media type
  $.mobile.media('screen and (min-width: 480px)') //>> tests for screen media type with window width > 480px
  $.mobile.media('@media screen and (-webkit-min-device-pixel-ratio: 2)') //>> tests for webkit 2x pixel ratio (iPhone 4)
  */
  $.mobile.media = (function() {
  // TODO: use window.matchMedia once at least one UA implements it
  var cache = {},
  testDiv = $( "<div id='jquery-mediatest'>" ),
  fakeBody = $( "<body>" ).append( testDiv );
   
  return function( query ) {
  if ( !( query in cache ) ) {
  var styleBlock = document.createElement('style'),
  cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }";
  //must set type for IE!
  styleBlock.type = "text/css";
  if (styleBlock.styleSheet){
  styleBlock.styleSheet.cssText = cssrule;
  }
  else {
  styleBlock.appendChild(document.createTextNode(cssrule));
  }
   
  $html.prepend( fakeBody ).prepend( styleBlock );
  cache[ query ] = testDiv.css( "position" ) === "absolute";
  fakeBody.add( styleBlock ).remove();
  }
  return cache[ query ];
  };
  })();
   
  /*
  private function for adding/removing breakpoint classes to HTML element for faux media-query support
  It does not require media query support, instead using JS to detect screen width > cross-browser support
  This function is called on orientationchange, resize, and mobileinit, and is bound via the 'htmlclass' event namespace
  */
  function detectResolutionBreakpoints(){
  var currWidth = $window.width(),
  minPrefix = "min-width-",
  maxPrefix = "max-width-",
  minBreakpoints = [],
  maxBreakpoints = [],
  unit = "px",
  breakpointClasses;
   
  $html.removeClass( minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " +
  maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit );
   
  $.each(resolutionBreakpoints,function( i, breakPoint ){
  if( currWidth >= breakPoint ){
  minBreakpoints.push( minPrefix + breakPoint + unit );
  }
  if( currWidth <= breakPoint ){
  maxBreakpoints.push( maxPrefix + breakPoint + unit );
  }
  });
   
  if( minBreakpoints.length ){ breakpointClasses = minBreakpoints.join(" "); }
  if( maxBreakpoints.length ){ breakpointClasses += " " + maxBreakpoints.join(" "); }
   
  $html.addClass( breakpointClasses );
  };
   
  /* $.mobile.addResolutionBreakpoints method:
  pass either a number or an array of numbers and they'll be added to the min/max breakpoint classes
  Examples:
  $.mobile.addResolutionBreakpoints( 500 );
  $.mobile.addResolutionBreakpoints( [500, 1200] );
  */
  $.mobile.addResolutionBreakpoints = function( newbps ){
  if( $.type( newbps ) === "array" ){
  resolutionBreakpoints = resolutionBreakpoints.concat( newbps );
  }
  else {
  resolutionBreakpoints.push( newbps );
  }
  resolutionBreakpoints.sort(function(a,b){ return a-b; });
  detectResolutionBreakpoints(