1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Applies button styling to links
3 //>>label: Buttons: Link-based
5 //>>css: ../css/themes/default/jquery.mobile.theme.css, ../css/structure/jquery.mobile.button.css
7 define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.vmouse" ], function( $ ) {
8 //>>excludeEnd("jqmBuildExclude");
9 ( function( $, undefined ) {
11 $.fn.buttonMarkup = function( options ) {
12 var $workingSet = this;
14 // Enforce options to be of type string
15 options = ( options && ( $.type( options ) == "object" ) )? options : {};
16 for ( var i = 0; i < $workingSet.length; i++ ) {
17 var el = $workingSet.eq( i ),
19 o = $.extend( {}, $.fn.buttonMarkup.defaults, {
20 icon: options.icon !== undefined ? options.icon : el.jqmData( "icon" ),
21 iconpos: options.iconpos !== undefined ? options.iconpos : el.jqmData( "iconpos" ),
22 theme: options.theme !== undefined ? options.theme : el.jqmData( "theme" ) || $.mobile.getInheritedTheme( el, "c" ),
23 inline: options.inline !== undefined ? options.inline : el.jqmData( "inline" ),
24 shadow: options.shadow !== undefined ? options.shadow : el.jqmData( "shadow" ),
25 corners: options.corners !== undefined ? options.corners : el.jqmData( "corners" ),
26 iconshadow: options.iconshadow !== undefined ? options.iconshadow : el.jqmData( "iconshadow" ),
27 mini: options.mini !== undefined ? options.mini : el.jqmData( "mini" )
31 innerClass = "ui-btn-inner",
32 textClass = "ui-btn-text",
33 buttonClass, iconClass,
34 // Button inner markup
40 $.each(o, function(key, value) {
41 e.setAttribute( "data-" + $.mobile.ns + key, value );
42 el.jqmData(key, value);
45 // Check if this element is already enhanced
46 buttonElements = $.data(((e.tagName === "INPUT" || e.tagName === "BUTTON") ? e.parentNode : e), "buttonElements");
49 e = buttonElements.outer;
51 buttonInner = buttonElements.inner;
52 buttonText = buttonElements.text;
53 // We will recreate this icon below
54 $(buttonElements.icon).remove();
55 buttonElements.icon = null;
58 buttonInner = document.createElement( o.wrapperEls );
59 buttonText = document.createElement( o.wrapperEls );
61 buttonIcon = o.icon ? document.createElement( "span" ) : null;
63 if ( attachEvents && !buttonElements) {
67 // if not, try to find closest theme container
69 o.theme = $.mobile.getInheritedTheme( el, "c" );
72 buttonClass = "ui-btn ui-btn-up-" + o.theme;
73 buttonClass += o.inline ? " ui-btn-inline" : "";
74 buttonClass += o.shadow ? " ui-shadow" : "";
75 buttonClass += o.corners ? " ui-btn-corner-all" : "";
77 if ( o.mini !== undefined ) {
78 // Used to control styling in headers/footers, where buttons default to `mini` style.
79 buttonClass += o.mini ? " ui-mini" : " ui-fullsize";
82 if ( o.inline !== undefined ) {
83 // Used to control styling in headers/footers, where buttons default to `mini` style.
84 buttonClass += o.inline === false ? " ui-btn-block" : " ui-btn-inline";
89 o.icon = "ui-icon-" + o.icon;
90 o.iconpos = o.iconpos || "left";
92 iconClass = "ui-icon " + o.icon;
95 iconClass += " ui-icon-shadow";
100 buttonClass += " ui-btn-icon-" + o.iconpos;
102 if ( o.iconpos == "notext" && !el.attr( "title" ) ) {
103 el.attr( "title", el.getEncodedText() );
107 innerClass += o.corners ? " ui-btn-corner-all" : "";
109 if ( o.iconpos && o.iconpos === "notext" && !el.attr( "title" ) ) {
110 el.attr( "title", el.getEncodedText() );
113 if ( buttonElements ) {
114 el.removeClass( buttonElements.bcls || "" );
116 el.removeClass( "ui-link" ).addClass( buttonClass );
118 buttonInner.className = innerClass;
120 buttonText.className = textClass;
121 if ( !buttonElements ) {
122 buttonInner.appendChild( buttonText );
125 buttonIcon.className = iconClass;
126 if ( !(buttonElements && buttonElements.icon) ) {
127 buttonIcon.appendChild( document.createTextNode("\u00a0") );
128 buttonInner.appendChild( buttonIcon );
132 while ( e.firstChild && !buttonElements) {
133 buttonText.appendChild( e.firstChild );
136 if ( !buttonElements ) {
137 e.appendChild( buttonInner );
140 // Assign a structure containing the elements of this button to the elements of this button. This
141 // will allow us to recognize this as an already-enhanced button in future calls to buttonMarkup().
150 $.data(e, 'buttonElements', buttonElements);
151 $.data(buttonInner, 'buttonElements', buttonElements);
152 $.data(buttonText, 'buttonElements', buttonElements);
154 $.data(buttonIcon, 'buttonElements', buttonElements);
161 $.fn.buttonMarkup.defaults = {
168 function closestEnabledButton( element ) {
172 // Note that we check for typeof className below because the element we
173 // handed could be in an SVG DOM where className on SVG elements is defined to
174 // be of a different type (SVGAnimatedString). We only operate on HTML DOM
175 // elements, so we look for plain "string".
176 cname = ( typeof element.className === 'string' ) && (element.className + ' ');
177 if ( cname && cname.indexOf("ui-btn ") > -1 && cname.indexOf("ui-disabled ") < 0 ) {
181 element = element.parentNode;
187 var attachEvents = function() {
188 var hoverDelay = $.mobile.buttonMarkup.hoverDelay, hov, foc;
190 $( document ).bind( {
191 "vmousedown vmousecancel vmouseup vmouseover vmouseout focus blur scrollstart": function( event ) {
193 $btn = $( closestEnabledButton( event.target ) ),
197 theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
199 if ( evt === "vmousedown" ) {
200 if ( $.support.touch ) {
201 hov = setTimeout(function() {
202 $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme );
205 $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme );
207 } else if ( evt === "vmousecancel" || evt === "vmouseup" ) {
208 $btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
209 } else if ( evt === "vmouseover" || evt === "focus" ) {
210 if ( $.support.touch ) {
211 foc = setTimeout(function() {
212 $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme );
215 $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme );
217 } else if ( evt === "vmouseout" || evt === "blur" || evt === "scrollstart" ) {
218 $btn.removeClass( "ui-btn-hover-" + theme + " ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
228 "focusin focus": function( event ){
229 $( closestEnabledButton( event.target ) ).addClass( $.mobile.focusClass );
231 "focusout blur": function( event ){
232 $( closestEnabledButton( event.target ) ).removeClass( $.mobile.focusClass );
239 //links in bars, or those with data-role become buttons
240 //auto self-init widgets
241 $( document ).bind( "pagecreate create", function( e ){
243 $( ":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a, .ui-bar > :jqmData(role='controlgroup') > a", e.target )
244 .not( ".ui-btn, :jqmData(role='none'), :jqmData(role='nojs')" )
250 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
252 //>>excludeEnd("jqmBuildExclude");