2 (function( $, window ) {
3 var win = $.mobile.$window,
4 event_name = "orientationchange",
8 initial_orientation_is_landscape,
9 initial_orientation_is_default,
10 portrait_map = { "0": true, "180": true };
12 // It seems that some device/browser vendors use window.orientation values 0 and 180 to
13 // denote the "default" orientation. For iOS devices, and most other smart-phones tested,
14 // the default orientation is always "portrait", but in some Android and RIM based tablets,
15 // the default orientation is "landscape". The following code attempts to use the window
16 // dimensions to figure out what the current orientation is, and then makes adjustments
17 // to the to the portrait_map if necessary, so that we can properly decode the
18 // window.orientation value whenever get_orientation() is called.
20 // Note that we used to use a media query to figure out what the orientation the browser
23 // initial_orientation_is_landscape = $.mobile.media("all and (orientation: landscape)");
25 // but there was an iPhone/iPod Touch bug beginning with iOS 4.2, up through iOS 5.1,
26 // where the browser *ALWAYS* applied the landscape media query. This bug does not
29 if ( $.support.orientation ) {
31 // Check the window width and height to figure out what the current orientation
32 // of the device is at this moment. Note that we've initialized the portrait map
33 // values to 0 and 180, *AND* we purposely check for landscape so that if we guess
34 // wrong, , we default to the assumption that portrait is the default orientation.
35 // We use a threshold check below because on some platforms like iOS, the iPhone
36 // form-factor can report a larger width than height if the user turns on the
37 // developer console. The actual threshold value is somewhat arbitrary, we just
38 // need to make sure it is large enough to exclude the developer console case.
40 var ww = window.innerWidth || $.mobile.$window.width(),
41 wh = window.innerHeight || $.mobile.$window.height(),
42 landscape_threshold = 50;
44 initial_orientation_is_landscape = ww > wh && ( ww - wh ) > landscape_threshold;
47 // Now check to see if the current window.orientation is 0 or 180.
48 initial_orientation_is_default = portrait_map[ window.orientation ];
50 // If the initial orientation is landscape, but window.orientation reports 0 or 180, *OR*
51 // if the initial orientation is portrait, but window.orientation reports 90 or -90, we
52 // need to flip our portrait_map values because landscape is the default orientation for
53 // this device/browser.
54 if ( ( initial_orientation_is_landscape && initial_orientation_is_default ) || ( !initial_orientation_is_landscape && !initial_orientation_is_default ) ) {
55 portrait_map = { "-90": true, "90": true };
59 $.event.special.orientationchange = $.extend( {}, $.event.special.orientationchange, {
61 // If the event is supported natively, return false so that jQuery
62 // will bind to the event using DOM methods.
63 if ( $.support.orientation &&
64 $.event.special.orientationchange.disabled === false ) {
68 // Get the current orientation to avoid initial double-triggering.
69 last_orientation = get_orientation();
71 // Because the orientationchange event doesn't exist, simulate the
72 // event by testing window dimensions on resize.
73 win.bind( "throttledresize", handler );
75 teardown: function() {
76 // If the event is not supported natively, return false so that
77 // jQuery will unbind the event using DOM methods.
78 if ( $.support.orientation && !$.event.special.orientationchange.disabled ) {
82 // Because the orientationchange event doesn't exist, unbind the
83 // resize event handler.
84 win.unbind( "throttledresize", handler );
86 add: function( handleObj ) {
87 // Save a reference to the bound event handler.
88 var old_handler = handleObj.handler;
91 handleObj.handler = function( event ) {
92 // Modify event object, adding the .orientation property.
93 event.orientation = get_orientation();
95 // Call the originally-bound event handler and return its result.
96 return old_handler.apply( this, arguments );
101 // If the event is not supported natively, this handler will be bound to
102 // the window resize event to simulate the orientationchange event.
104 // Get the current orientation.
105 var orientation = get_orientation();
107 if ( orientation !== last_orientation ) {
108 // The orientation has changed, so trigger the orientationchange event.
109 last_orientation = orientation;
110 win.trigger( event_name );
114 // Get the current page orientation. This method is exposed publicly, should it
115 // be needed, as jQuery.event.special.orientationchange.orientation()
116 $.event.special.orientationchange.orientation = get_orientation = function() {
117 var isPortrait = true, elem = document.documentElement;
119 // prefer window orientation to the calculation based on screensize as
120 // the actual screen resize takes place before or after the orientation change event
121 // has been fired depending on implementation (eg android 2.3 is before, iphone after).
122 // More testing is required to determine if a more reliable method of determining the new screensize
123 // is possible when orientationchange is fired. (eg, use media queries + element + opacity)
124 if ( $.support.orientation ) {
125 // if the window orientation registers as 0 or 180 degrees report
126 // portrait, otherwise landscape
127 isPortrait = portrait_map[ window.orientation ];
129 isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1;
132 return isPortrait ? "portrait" : "landscape";
135 $.fn[ event_name ] = function( fn ) {
136 return fn ? this.bind( event_name, fn ) : this.trigger( event_name );
141 $.attrFn[ event_name ] = true;