@@ -35,24 +35,14 @@ return $.widget( "mobile.panel", {

options: {
classes: {
panel: "ui-panel",
panelOpen: "ui-panel-open",
panelClosed: "ui-panel-closed",
panelFixed: "ui-panel-fixed",
panelInner: "ui-panel-inner",
modal: "ui-panel-dismiss",
modalOpen: "ui-panel-dismiss-open",
pageContainer: "ui-panel-page-container",
pageWrapper: "ui-panel-wrapper",
pageFixedToolbar: "ui-panel-fixed-toolbar",
pageContentPrefix: "ui-panel-page-content", /* Used for wrapper and fixed toolbars position, display and open classes. */
animate: "ui-panel-animate"
},
animate: true,
theme: null,
position: "left",
dismissible: true,
display: "reveal", //accepts reveal, push, overlay

// Accepts reveal, push, overlay
display: "reveal",
swipeClose: true,
positionFixed: false
},
@@ -69,7 +59,7 @@ return $.widget( "mobile.panel", {
var el = this.element,
parentPage = el.closest( ".ui-page, :jqmData(role='page')" );

// expose some private props to other methods
// Expose some private props to other methods
$.extend( this, {
_closeLink: el.find( ":jqmData(rel='close')" ),
_parentPage: ( parentPage.length > 0 ) ? parentPage : false,
@@ -81,11 +71,12 @@ return $.widget( "mobile.panel", {
if ( this.options.display !== "overlay" ) {
this._getWrapper();
}
this._addPanelClasses();

// if animating, add the class to do so
this._addClass( "ui-panel ui-panel-closed", this._getPanelClasses() );

// If animating, add the class to do so
if ( $.support.cssTransform3d && !!this.options.animate ) {
this.element.addClass( this.options.classes.animate );
this._addClass( "ui-panel-animate" );
}

this._bindUpdateLayout();
@@ -98,32 +89,40 @@ return $.widget( "mobile.panel", {
}

this._bindSwipeEvents();
this._superApply( arguments );
},

_safelyWrap: function( parent, wrapperHtml, children ) {
return children.length ? children.wrapAll( wrapperHtml ).parent() :
$( wrapperHtml ).appendTo( parent );
if ( children.length ) {
children.eq( 0 ).before( wrapperHtml );
wrapperHtml.append( children );
return children.parent();
} else {
return $( wrapperHtml ).appendTo( parent );
}
},

_getPanelInner: function() {
var panelInner = this.element.find( "." + this.options.classes.panelInner );
var panelInner = this.element.find( ".ui-panel-inner" );

if ( panelInner.length === 0 ) {
panelInner = this._safelyWrap( this.element,
"<div class='" + this.options.classes.panelInner + "'></div>",
this.element.children() );
panelInner = $( "<div>" );
this._addClass( panelInner, "ui-panel-inner" );
panelInner = this._safelyWrap( this.element, panelInner, this.element.children() );
}

return panelInner;
},

_createModal: function() {
var self = this,
target = self._parentPage ? self._parentPage.parent() : self.element.parent();
var that = this,
target = that._parentPage ? that._parentPage.parent() : that.element.parent();

that._modal = $( "<div>" );
that._addClass( that._modal, "ui-panel-dismiss" );

self._modal = $( "<div class='" + self.options.classes.modal + "'></div>" )
.on( "mousedown", function() {
self.close();
that._modal.on( "mousedown", function() {
that.close();
} )
.appendTo( target );
},
@@ -136,12 +135,13 @@ return $.widget( "mobile.panel", {

_getWrapper: function() {
var thePage,
wrapper = this._page().find( "." + this.options.classes.pageWrapper );
wrapper = this._page().find( ".ui-panel-wrapper" );

if ( wrapper.length === 0 ) {
thePage = this._page();
wrapper = this._safelyWrap( thePage,
"<div class='" + this.options.classes.pageWrapper + "'></div>",
wrapper = $( "<div>" );
this._addClass( wrapper, "ui-panel-wrapper" );
wrapper = this._safelyWrap( thePage, wrapper,
this._page().children( ".ui-header:not(.ui-header-fixed), " +
".ui-content:not(.ui-popup), .ui-footer:not(.ui-footer-fixed)" ) );
}
@@ -152,32 +152,30 @@ return $.widget( "mobile.panel", {
_getFixedToolbars: function() {
var extFixedToolbars = $( "body" ).children( ".ui-header-fixed, .ui-footer-fixed" ),
intFixedToolbars = this._page().find( ".ui-header-fixed, .ui-footer-fixed" ),
fixedToolbars = extFixedToolbars.add( intFixedToolbars ).addClass( this.options.classes.pageFixedToolbar );
fixedToolbars = extFixedToolbars.add( intFixedToolbars );

this._addClass( fixedToolbars, "ui-panel-fixed-toolbar" );

return fixedToolbars;
},

_getPosDisplayClasses: function( prefix ) {
return prefix + "-position-" + this.options.position + " " + prefix + "-display-" + this.options.display;
return prefix + "-position-" +
this.options.position + " " + prefix +
"-display-" + this.options.display;
},

_getPanelClasses: function() {
var panelClasses = this.options.classes.panel +
" " + this._getPosDisplayClasses( this.options.classes.panel ) +
" " + this.options.classes.panelClosed +
var panelClasses = this._getPosDisplayClasses( "ui-panel" ) +
" " + "ui-body-" + ( this.options.theme ? this.options.theme : "inherit" );

if ( !!this.options.positionFixed ) {
panelClasses += " " + this.options.classes.panelFixed;
panelClasses += " ui-panel-fixed";
}

return panelClasses;
},

_addPanelClasses: function() {
this.element.addClass( this._getPanelClasses() );
},

_handleCloseClick: function( event ) {
if ( !event.isDefaultPrevented() ) {
this.close();
@@ -196,13 +194,13 @@ return $.widget( "mobile.panel", {

_positionPanel: function( scrollToTop ) {
var heightWithMargins, heightWithoutMargins,
self = this,
panelInnerHeight = self._panelInner.outerHeight(),
that = this,
panelInnerHeight = that._panelInner.outerHeight(),
expand = panelInnerHeight > this.window.height();

if ( expand || !self.options.positionFixed ) {
if ( expand || !that.options.positionFixed ) {
if ( expand ) {
self._unfixPanel();
that._unfixPanel();
$.mobile.resetActivePageHeight( panelInnerHeight );
} else if ( !this._parentPage ) {
heightWithMargins = this.element.outerHeight( true );
@@ -218,7 +216,7 @@ return $.widget( "mobile.panel", {
this.window[ 0 ].scrollTo( 0, $.mobile.defaultHomeScroll );
}
} else {
self._fixPanel();
that._fixPanel();
}
},

@@ -232,22 +230,22 @@ return $.widget( "mobile.panel", {

_unfixPanel: function() {
if ( !!this.options.positionFixed && $.support.fixedPosition ) {
this.element.removeClass( this.options.classes.panelFixed );
this._removeClass( "ui-panel-fixed" );
}
},

_fixPanel: function() {
if ( !!this.options.positionFixed && $.support.fixedPosition ) {
this.element.addClass( this.options.classes.panelFixed );
this._addClass( "ui-panel-fixed" );
}
},

_bindUpdateLayout: function() {
var self = this;
var that = this;

self.element.on( "updatelayout", function( /* e */ ) {
if ( self._open ) {
self._positionPanel();
that.element.on( "updatelayout", function( /* e */ ) {
if ( that._open ) {
that._positionPanel();
}
} );
},
@@ -268,9 +266,9 @@ return $.widget( "mobile.panel", {
e.preventDefault();
link = $( e.target );
if ( link.hasClass( "ui-button" ) ) {
link.addClass( "ui-button-active" );
this._addClass( link, null, "ui-button-active" );
this.element.one( "panelopen panelclose", function() {
link.removeClass( "ui-button-active" );
this._removeClass( link, null, "ui-button-active" );
} );
}
this.toggle();
@@ -294,19 +292,21 @@ return $.widget( "mobile.panel", {
},

_bindPageEvents: function() {
var self = this;
var that = this;

this.document

// Close the panel if another panel on the page opens
.on( "panelbeforeopen", function( e ) {
if ( self._open && e.target !== self.element[ 0 ] ) {
self.close();
if ( that._open && e.target !== that.element[ 0 ] ) {
that.close();
}
} )

// On escape, close? might need to have a target check too...
.on( "keyup.panel", function( e ) {
if ( e.keyCode === 27 && self._open ) {
self.close();
if ( e.keyCode === 27 && that._open ) {
that.close();
}
} );
if ( !this._parentPage && this.options.display !== "overlay" ) {
@@ -317,176 +317,180 @@ return $.widget( "mobile.panel", {
}
} );
}

// Clean up open panels after page hide
if ( self._parentPage ) {
if ( that._parentPage ) {
this.document.on( "pagehide", ":jqmData(role='page')", function() {
if ( self._open ) {
self.close( true );
if ( that._open ) {
that.close( true );
}
} );
} else {
this.document.on( "pagebeforehide", function() {
if ( self._open ) {
self.close( true );
if ( that._open ) {
that.close( true );
}
} );
}
},

// state storage of open or closed
// State storage of open or closed
_open: false,
_pageContentOpenClasses: null,
_modalOpenClasses: null,

open: function( immediate ) {
if ( !this._open ) {
var self = this,
o = self.options,
var that = this,
o = that.options,

_openPanel = function() {
self._off( self.document, "panelclose" );
self._page().jqmData( "panel", "open" );
that._off( that.document, "panelclose" );
that._page().jqmData( "panel", "open" );

if ( $.support.cssTransform3d && !!o.animate && o.display !== "overlay" ) {
self._wrapper.addClass( o.classes.animate );
self._fixedToolbars().addClass( o.classes.animate );
that._addClass( that._wrapper, "ui-panel-animate" );
that._addClass( that._fixedToolbars(), "ui-panel-animate" );
}

if ( !immediate && $.support.cssTransform3d && !!o.animate ) {
( self._wrapper || self.element )
( that._wrapper || that.element )
.animationComplete( complete, "transition" );
} else {
setTimeout( complete, 0 );
}

if ( o.theme && o.display !== "overlay" ) {
self._page().parent()
.addClass( o.classes.pageContainer + "-themed " + o.classes.pageContainer + "-" + o.theme );
that._addClass( that._page().parent(),
"ui-panel-page-container-themed ui-panel-page-container-" + o.theme );
}

self.element
.removeClass( o.classes.panelClosed )
.addClass( o.classes.panelOpen );
that._removeClass( "ui-panel-closed" )
._addClass( "ui-panel-open" );

self._positionPanel( true );
that._positionPanel( true );

self._pageContentOpenClasses = self._getPosDisplayClasses( o.classes.pageContentPrefix );
that._pageContentOpenClasses =
that._getPosDisplayClasses( "ui-panel-page-content" );

if ( o.display !== "overlay" ) {
self._page().parent().addClass( o.classes.pageContainer );
self._wrapper.addClass( self._pageContentOpenClasses );
self._fixedToolbars().addClass( self._pageContentOpenClasses );
that._addClass( that._page().parent(), "ui-panel-page-container" );
that._addClass( that._wrapper, that._pageContentOpenClasses );
that._addClass( that._fixedToolbars(), that._pageContentOpenClasses );
}

self._modalOpenClasses = self._getPosDisplayClasses( o.classes.modal ) + " " + o.classes.modalOpen;
if ( self._modal ) {
self._modal
.addClass( self._modalOpenClasses )
.height( Math.max( self._modal.height(), self.document.height() ) );
that._modalOpenClasses =
that._getPosDisplayClasses( "ui-panel-dismiss" ) +
" ui-panel-dismiss-open";

if ( that._modal ) {
that._addClass( that._modal, that._modalOpenClasses );

that._modal.height(
Math.max( that._modal.height(), that.document.height() ) );
}
},
complete = function() {

// Bail if the panel was closed before the opening animation has completed
if ( !self._open ) {
if ( !that._open ) {
return;
}

if ( o.display !== "overlay" ) {
self._wrapper.addClass( o.classes.pageContentPrefix + "-open" );
self._fixedToolbars().addClass( o.classes.pageContentPrefix + "-open" );
that._addClass( that._wrapper, "ui-panel-page-content-open" );
that._addClass( that._fixedToolbars(), "ui-panel-page-content-open" );
}

self._bindFixListener();
that._bindFixListener();

self._trigger( "open" );
that._trigger( "open" );

self._openedPage = self._page();
that._openedPage = that._page();
};

self._trigger( "beforeopen" );
that._trigger( "beforeopen" );

if ( self._page().jqmData( "panel" ) === "open" ) {
self._on( self.document, {
if ( that._page().jqmData( "panel" ) === "open" ) {
that._on( that.document, {
"panelclose": _openPanel
} );
} else {
_openPanel();
}

self._open = true;
that._open = true;
}
},

close: function( immediate ) {
if ( this._open ) {
var self = this,
var that = this,

// Record what the page is the moment the process of closing begins, because it
// may change by the time the process completes
currentPage = self._page(),
currentPage = that._page(),
o = this.options,

_closePanel = function() {

self.element.removeClass( o.classes.panelOpen );
that._removeClass( "ui-panel-open" );

if ( o.display !== "overlay" ) {
self._wrapper.removeClass( self._pageContentOpenClasses );
self._fixedToolbars().removeClass( self._pageContentOpenClasses );
that._removeClass( that._wrapper, that._pageContentOpenClasses );
that._removeClass( that._fixedToolbars(), that._pageContentOpenClasses );
}

if ( !immediate && $.support.cssTransform3d && !!o.animate ) {
( self._wrapper || self.element )
( that._wrapper || that.element )
.animationComplete( complete, "transition" );
} else {
setTimeout( complete, 0 );
}

if ( self._modal ) {
self._modal
.removeClass( self._modalOpenClasses )
.height( "" );
if ( that._modal ) {
that._removeClass( that._modal, that._modalOpenClasses );
that._modal.height( "" );
}
},
complete = function() {
if ( o.theme && o.display !== "overlay" ) {
currentPage.parent().removeClass( o.classes.pageContainer + "-themed " +
o.classes.pageContainer + "-" + o.theme );
that._removeClass( currentPage.parent(),
"ui-panel-page-container-themed ui-panel-page-container-" + o.theme );
}

self.element.addClass( o.classes.panelClosed );
that._addClass( "ui-panel-closed" );

//scroll to the top
self._positionPanel( true );
// Scroll to the top
that._positionPanel( true );

if ( o.display !== "overlay" ) {
currentPage.parent().removeClass( o.classes.pageContainer );
self._wrapper.removeClass( o.classes.pageContentPrefix + "-open" );
self._fixedToolbars().removeClass( o.classes.pageContentPrefix + "-open" );
that._removeClass( currentPage.parent(), "ui-panel-page-container" );
that._removeClass( that._wrapper, "ui-panel-page-content-open" );
that._removeClass( that._fixedToolbars(), "ui-panel-page-content-open" );
}

if ( $.support.cssTransform3d && !!o.animate && o.display !== "overlay" ) {
self._wrapper.removeClass( o.classes.animate );
self._fixedToolbars().removeClass( o.classes.animate );
that._removeClass( that._wrapper, "ui-panel-animate" );
that._removeClass( that._fixedToolbars(), "ui-panel-animate" );
}

self._fixPanel();
self._unbindFixListener();
that._fixPanel();
that._unbindFixListener();
$.mobile.resetActivePageHeight();

currentPage.jqmRemoveData( "panel" );

self._trigger( "close" );
that._trigger( "close" );

self._openedPage = null;
that._openedPage = null;
};

self._trigger( "beforeclose" );
that._trigger( "beforeclose" );

_closePanel();

self._open = false;
that._open = false;
}
},

@@ -497,36 +501,37 @@ return $.widget( "mobile.panel", {
_destroy: function() {
var otherPanels,
o = this.options,
multiplePanels = ( $( "body > :mobile-panel" ).length + $.mobile.activePage.find( ":mobile-panel" ).length ) > 1;
multiplePanels = ( $( "body > :mobile-panel" ).length +
$.mobile.activePage.find( ":mobile-panel" ).length ) > 1;

if ( o.display !== "overlay" ) {

// remove the wrapper if not in use by another panel
otherPanels = $( "body > :mobile-panel" ).add( $.mobile.activePage.find( ":mobile-panel" ) );
// Remove the wrapper if not in use by another panel
otherPanels = $( "body > :mobile-panel" ).add(
$.mobile.activePage.find( ":mobile-panel" ) );

if ( otherPanels.not( ".ui-panel-display-overlay" ).not( this.element ).length === 0 ) {
this._wrapper.children().unwrap();
}

if ( this._open ) {

this._fixedToolbars().removeClass( o.classes.pageContentPrefix + "-open" );
this._removeClass( this._fixedToolbars(), "ui-panel-page-content-open" );

if ( $.support.cssTransform3d && !!o.animate ) {
this._fixedToolbars().removeClass( o.classes.animate );
this._removeClass( this._fixedToolbars(), "ui-panel-animate" );
}

this._page().parent().removeClass( o.classes.pageContainer );
this._removeClass( this._page().parent(), "ui-panel-page-container" );

if ( o.theme ) {
this._page().parent().removeClass( o.classes.pageContainer + "-themed " + o.classes.pageContainer + "-" + o.theme );
this._removeClass( this._page().parent(),
"ui-panel-page-container-themed ui-panel-page-container-" + o.theme );
}
}
}

if ( !multiplePanels ) {

this.document.off( "panelopen panelclose" );

}

if ( this._open ) {
@@ -535,16 +540,16 @@ return $.widget( "mobile.panel", {

this._panelInner.children().unwrap();

this.element
.removeClass( [ this._getPanelClasses(), o.classes.panelOpen, o.classes.animate ].join( " " ) )
.off( "panelbeforeopen" )
.off( "panelhide" )
.off( "keyup.panel" )
.off( "updatelayout" );
this._removeClass( "ui-panel ui-panel-closed ui-panel-open ui-panel-animate",
this._getPanelClasses() );

this.element.off( "panelbeforeopen panelhide keyup.panel updatelayout" );

if ( this._modal ) {
this._modal.remove();
}

this._superApply( arguments );
}
} );

@@ -11,6 +11,8 @@
<script src="../../jquery.setNameSpace.js"></script>
<script src="../../jquery.testHelper.js"></script>
<script src="../../../external/qunit/qunit.js"></script>
<script src="../../../external/qunit-assert-classes/qunit-assert-classes.js"></script>

<script type="text/javascript">
// redirects from push-state-tests.html
$( document ).bind( 'mobileinit', function(){
@@ -41,6 +43,7 @@
</div>
<div data-nstest-role="panel" id="panel-test-events">
<p>Contents of a panel.</p>
<p>Contents of a panel.</p>
</div>
<div data-nstest-role="panel" id="panel-test-open">
<p>Contents of a panel.</p>
@@ -101,7 +104,7 @@ <h1 id="demo-links">Panels</h1>
<a href="#panel-test-id-change">Open Panel</a>
<a href="#panel-test-external">Open Panel</a>
</div>

<div data-nstest-role="panel" id="panel-panelclose-event">
<h1>Panel!</h1>
</div>
@@ -2,12 +2,10 @@
* mobile panel unit tests
*/


( function( QUnit, $ ) {

var count,
defaults = $.mobile.panel.prototype.options,
classes = defaults.classes,
originalWidget = $.mobile.panel.prototype;

function getPageFromPanel( $panel ) {
@@ -19,7 +17,7 @@ function getModalFromPanel( $panel ) {
}

function getWrapperFromPage( $page ) {
return $page.find( "." + defaults.classes.pageWrapper );
return $page.find( ".ui-panel-wrapper" );
}

QUnit.module( "stock panel" );
@@ -29,12 +27,23 @@ QUnit.test( "expected classes on create", function( assert ) {
var $panel = $( "#panel-test-create" ),
$page = getPageFromPanel( $panel );

assert.ok( $panel.hasClass( defaults.classes.panel ), "default class is present" );
assert.ok( $panel.hasClass( "ui-panel-display-" + defaults.display ), "display class is added per the default" );
assert.ok( $panel.hasClass( "ui-panel-position-" + defaults.position ), "position class is added per the default" );
assert.hasClasses( $panel, "ui-panel",
"default class is present" );
assert.hasClasses( $panel, "ui-panel-display-" + defaults.display,
"display class is added per the default" );
assert.hasClasses( $panel, "ui-panel-position-" + defaults.position,
"position class is added per the default" );

if ( $.support.cssTransform3d ) {
assert.hasClasses( $panel, "ui-panel-animate",
"animate class is present by default when supported" );
} else {
assert.lacksClasses( $panel, "ui-panel-animate",
"animate class is not present by default when not supported" );
}

assert.equal( $panel.hasClass( defaults.classes.animate ), $.support.cssTransform3d, "animate class is present by default when supported" );
assert.ok( $panel.hasClass( defaults.classes.panelClosed ), "panel is closed by default" );
assert.hasClasses( $panel, "ui-panel-closed",
"panel is closed by default" );
} );

QUnit.asyncTest( "expected open, close events", function( assert ) {
@@ -43,20 +52,21 @@ QUnit.asyncTest( "expected open, close events", function( assert ) {

var $panel = $( "#panel-test-events" );

$panel.one( "panelbeforeopen panelopen panelbeforeclose panelclose", function( event ) {
assert.ok( true, event.type + " event." );
} ).one( "panelopen", function() {
$panel.panel( "close" );
} ).one( "panelclose", function() {
QUnit.start();
} );
$panel.one( "panelbeforeopen panelopen panelbeforeclose panelclose",
function( event ) {
assert.ok( true, event.type + " event." );
} ).one( "panelopen", function() {
$panel.panel( "close" );
} ).one( "panelclose", function() {
QUnit.start();
} );

$panel.panel( "open" );

} );

QUnit.asyncTest( "classes modified by open", function( assert ) {
assert.expect( 11 );
assert.expect( 10 );
var $panel = $( "#panel-test-open" ),
$page = getPageFromPanel( $panel );

@@ -65,26 +75,34 @@ QUnit.asyncTest( "classes modified by open", function( assert ) {
$modal = getModalFromPanel( $panel ),
$openButton = $page.find( "a[href='\\#panel-test-open']" );

assert.ok( !$openButton.hasClass( "ui-button-active" ), "button doesn't have active class" );
assert.lacksClasses( $openButton, "ui-button-active",
"button doesn't have active class" );

assert.ok( !$panel.hasClass( defaults.classes.panelClosed ), "closed class removed" );
assert.ok( $panel.hasClass( defaults.classes.panelOpen ), "open class added" );
assert.lacksClasses( $panel, "ui-panel-closed",
"closed class removed" );

assert.equal( $wrapper.length, 1, "wrapper exists." );
assert.hasClasses( $panel, "ui-panel-open",
"open class added" );

assert.ok( !$wrapper.hasClass( defaults.classes.contentWrapClosed ), "wrapper not closed class" );
assert.equal( $wrapper.length, 1, "wrapper exists." );

assert.ok( $wrapper.hasClass( defaults.classes.pageContentPrefix + "-open" ), "wrapper open class" );
assert.hasClasses( $wrapper, "ui-panel-page-content" +
"-open", "wrapper open class" );

var prefix = defaults.classes.pageContentPrefix;
assert.ok( $wrapper.hasClass( prefix + "-position-left" ), "wrapper position class" );
assert.ok( $wrapper.hasClass( prefix + "-display-reveal" ), "wrapper display type class" );
var prefix = "ui-panel-page-content";
assert.hasClasses( $wrapper, prefix + "-position-left",
"wrapper position class" );
assert.hasClasses( $wrapper, prefix + "-display-reveal",
"wrapper display type class" );

assert.ok( $modal.hasClass( defaults.classes.modalOpen ), "modal open class" );
assert.hasClasses( $modal, "ui-panel-dismiss-open",
"modal open class" );

prefix = defaults.classes.modal;
assert.ok( $modal.hasClass( prefix + "-position-left" ), "modal position class" );
assert.ok( $modal.hasClass( prefix + "-display-reveal" ), "modal display type class" );
prefix = "ui-panel-dismiss";
assert.hasClasses( $modal, prefix + "-position-left",
"modal position class" );
assert.hasClasses( $modal, prefix + "-display-reveal",
"modal display type class" );

// TODO test positioning when panel height > screen height
// TODO test rebind resize after complete
@@ -99,7 +117,7 @@ QUnit.asyncTest( "classes modified by open", function( assert ) {
} );

QUnit.asyncTest( "classes modified by close", function( assert ) {
assert.expect( 12 );
assert.expect( 7 );

var $panel = $( "#panel-test-close" ),
$page = getPageFromPanel( $panel ),
@@ -110,26 +128,21 @@ QUnit.asyncTest( "classes modified by close", function( assert ) {
$panel.one( "panelopen", function( event ) {
$panel.panel( "close" );
} ).one( "panelclose", function( event ) {
assert.ok( !$openButton.hasClass( "ui-button-active" ), "button doesn't have active class" );
assert.ok( !$panel.hasClass( defaults.classes.panelOpen ), "panel not open class" );
assert.lacksClasses( $openButton, "ui-button-active",
"button doesn't have active class" );
assert.lacksClasses( $panel, "ui-panel-open", "panel not open class" );

assert.ok( !$modal.hasClass( defaults.classes.modalOpen ), "modal without open class" );
var prefix = defaults.classes.modal;
assert.ok( !$modal.hasClass( prefix + "-position-left" ), "modal without position class" );
assert.ok( !$modal.hasClass( prefix + "-display-overlay" ), "modal without display type class" );

assert.ok( !$wrapper.hasClass( defaults.classes.contentWrapOpen ), "wrapper open class" );
assert.ok( !$wrapper.hasClass( defaults.classes.contentWrapOpenComplete ), "wrapper open complete class" );
assert.lacksClasses( $modal, "ui-panel-dismiss-open", "modal without open class" );
var prefix = "ui-panel-dismiss";
assert.lacksClasses( $modal, prefix + "-position-left", "modal without position class" );
assert.lacksClasses( $modal, prefix + "-display-overlay",
"modal without display type class" );

// complete
assert.ok( $panel.hasClass( defaults.classes.panelClosed ), "panel closed class" );

prefix = defaults.classes.contentWrap;
assert.ok( !$wrapper.hasClass( prefix + "-position-left" ), "wrapper position class" );
assert.ok( !$wrapper.hasClass( prefix + "-display-overlay" ), "wrapper display type class" );
assert.hasClasses( $panel, "ui-panel-closed", "panel closed class" );

assert.ok( !$wrapper.hasClass( defaults.classes.pageContentPrefix + "-open" ), "wrapper open class removed" );
assert.ok( !$page.hasClass( defaults.classes.pageBlock ), "page block class not added to page" );
assert.lacksClasses( $wrapper, "ui-panel-page-content" +
"-open", "wrapper open class removed" );

// TODO test positioning when panel height > screen height
// TODO test rebind resize after complete
@@ -165,7 +178,8 @@ QUnit.test( "wrapper exists after create", function( assert ) {
$wrapper = getWrapperFromPage( $page );

assert.ok( $wrapper.length, "wrapper exists" );
assert.ok( !$wrapper.hasClass( defaults.classes.pageContentPrefix + "-open" ), "wrapper does not have open class" );
assert.ok( !$wrapper.hasClass( "ui-panel-page-content" +
"-open" ), "wrapper does not have open class" );

} );

@@ -178,21 +192,16 @@ QUnit.test( "destroy method", function( assert ) {
$wrapper = getWrapperFromPage( $page );

$panel.panel( "destroy" );
// test page without sibling panels

assert.ok( !$wrapper.hasClass( defaults.classes.contentWrapOpen ) );
assert.ok( !$wrapper.hasClass( defaults.classes.contentWrapOpenComplete ) );

assert.ok( !$panel.hasClass( defaults.classes.panel ) );
assert.ok( !$wrapper.hasClass( "ui-panel-position-left" ) );
assert.ok( !$wrapper.hasClass( "ui-panel-display-overlay" ) );
assert.ok( !$panel.hasClass( defaults.classes.panelOpen ) );
assert.ok( !$panel.hasClass( defaults.classes.panelClosed ) );
assert.ok( !$panel.hasClass( "ui-body-c" ) );
assert.ok( !$panel.hasClass( defaults.classes.cssTransform3d ) );
// test page without sibling panels

assert.ok( !$panel.hasClass( [ classes.openComplete, classes.panelUnfixed, classes.panelClosed, classes.panelOpen ].join( " " ) ) );
assert.ok( !$page.hasClass( classes.pageBlock ) );
assert.lacksClasses( $panel, "ui-panel" );
assert.lacksClasses( $wrapper, "ui-panel-position-left" );
assert.lacksClasses( $wrapper, "ui-panel-display-overlay" );
assert.lacksClasses( $panel, "ui-panel-open" );
assert.lacksClasses( $panel, "ui-panel-closed" );
assert.lacksClasses( $panel, "ui-body-c" );
assert.lacksClasses( $panel, "ui-panel-closed ui-panel-open" );

$panel.panel();
} );
@@ -233,7 +242,7 @@ QUnit.module( "dismissable panel", {
setup: function() {
this.originalOriginalEvent = $.Event.prototype.originalEvent;
$.testHelper.mockOriginalEvent( {
touches: [ { 'pageX': 0 }, { 'pageY': 0 } ]
touches: [ { "pageX": 0 }, { "pageY": 0 } ]
} );
},
teardown: function() {
@@ -336,7 +345,8 @@ QUnit.module( "panel with non-default theme" );
QUnit.test( "expected classes on create", function( assert ) {

var $panel = $( "#panel-test-non-default-theme" );
assert.ok( $panel.hasClass( "ui-body-" + $panel.jqmData( 'theme' ) ), "theme class was added" );
assert.hasClasses( $panel, "ui-body-" + $panel.jqmData( "theme" ),
"theme class was added" );

} );

@@ -351,12 +361,14 @@ QUnit.asyncTest( "panel opens, close button hides panel", function( assert ) {

$panel.one( "panelopen", function() {

assert.ok( !$panel.hasClass( defaults.classes.panelClosed ), "wrapper opens" );
assert.lacksClasses( $panel, "ui-panel-closed",
"wrapper opens" );
$closeButton.trigger( "click" );

} ).one( "panelclose", function() {

assert.ok( $panel.hasClass( defaults.classes.panelClosed ), "wrapper has closed class" );
assert.hasClasses( $panel, "ui-panel-closed",
"wrapper has closed class" );
QUnit.start();
} );

@@ -485,7 +497,8 @@ QUnit.asyncTest( "overlay panel should not call getWrapper", function( assert )
pagechange: { src: $( "body" ), event: "pagechange" + eventNs + "4" }
},
function() {
assert.deepEqual( count, 0, "getWrapper not called on pagechange back to initial page" );
assert.deepEqual( count, 0,
"getWrapper not called on pagechange back to initial page" );
QUnit.start();
}
] );
@@ -638,17 +651,17 @@ QUnit.asyncTest( "external panel: test classes during A>B>A transition", functio

$panel.one( "panelopen", function( event ) {

assert.ok( !$panel.hasClass( defaults.classes.panelClosed ), "closed class removed" );
assert.ok( $panel.hasClass( defaults.classes.panelOpen ), "open class added" );
assert.lacksClasses( $panel, "ui-panel-closed", "closed class removed" );
assert.hasClasses( $panel, "ui-panel-open", "open class added" );
assert.ok( $firstPage.data( "nstestPanel" ) === "open", "open flag set on first page" );
assert.equal( $firstPage.find( ".ui-panel-wrapper" ).length, 1, "wrapper exists." );

$link.trigger( "click" );

} ).one( "panelclose", function( event ) {

assert.ok( $panel.hasClass( defaults.classes.panelClosed ), "closed class removed" );
assert.ok( !$panel.hasClass( defaults.classes.panelOpen ), "open class added" );
assert.hasClasses( $panel, "ui-panel-closed", "closed class removed" );
assert.lacksClasses( $panel, "ui-panel-open", "open class added" );
assert.ok( $firstPage.data( "nstestPanel" ) === undefined, "no open flag on first" );

$panel.trigger( "continue" );
@@ -658,8 +671,8 @@ QUnit.asyncTest( "external panel: test classes during A>B>A transition", functio
setTimeout( function() {
$panel.panel( "open" );

assert.ok( !$panel.hasClass( defaults.classes.panelClosed ), "closed class removed" );
assert.ok( $panel.hasClass( defaults.classes.panelOpen ), "open class added" );
assert.lacksClasses( $panel, "ui-panel-closed", "closed class removed" );
assert.hasClasses( $panel, "ui-panel-open", "open class added" );
assert.ok( $secondPage.data( "nstestPanel" ) === "open", "open flag set on 2nd page" );
assert.equal( $secondPage.find( ".ui-panel-wrapper" ).length, 1, "wrapper exists." );

@@ -679,8 +692,8 @@ QUnit.asyncTest( "external panel: test classes during A>B>A transition", functio
$panel.panel( "open" );

assert.ok( $firstPage.data( "nstestPanel" ) === "open", "open flag set on first page" );
assert.ok( !$panel.hasClass( defaults.classes.panelClosed ), "closed class removed" );
assert.ok( $panel.hasClass( defaults.classes.panelOpen ), "open class added" );
assert.lacksClasses( $panel, "ui-panel-closed", "closed class removed" );
assert.hasClasses( $panel, "ui-panel-open", "open class added" );

QUnit.start();
}, 500 );