Upgrade to jquery.mobile-1.0rc1
[busui.git] / js / jquery.mobile-1.0rc1.js
blob:a/js/jquery.mobile-1.0rc1.js -> blob:b/js/jquery.mobile-1.0rc1.js
  /*!
  * jQuery Mobile v1.0rc1
  * 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", {
  // decorate the parent _createWidget to trigger `widgetinit` for users
  // who wish to do post post `widgetcreate` alterations/additions
  //
  // TODO create a pull request for jquery ui to trigger this event
  // in the original _createWidget
  _createWidget: function() {
  $.Widget.prototype._createWidget.apply( this, arguments );
  this._trigger( 'init' );
  },
   
  _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 : a workaround for window.matchMedia
  * 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" );
   
  /* $.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 ];
  };
  })();
   
  })(jQuery);/*
  * jQuery Mobile Framework : support tests
  * Copyright (c) jQuery Project
  * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
  */
   
  (function( $, undefined ) {
   
  var fakeBody = $( "<body>" ).prependTo( "html" ),
  fbCSS = fakeBody[ 0 ].style,
  vendors = [ "Webkit", "Moz", "O" ],
  webos = "palmGetResource" in window, //only used to rule out scrollTop
  bb = window.blackberry; //only used to rule out box shadow, as it's filled opaque on BB
   
  // thx Modernizr
  function propExists( prop ) {
  var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ),
  props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " );
   
  for ( var v in props ){
  if ( fbCSS[ props[ v ] ] !== undefined ) {
  return true;
  }
  }
  }
   
  // Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting )
  function baseTagTest() {
  var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/",
  base = $( "head base" ),
  fauxEle = null,
  href = "",
  link, rebase;
   
  if ( !base.length ) {
  base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( &quo