compass-jquery-plugin 0.3.0.beta.20 → 0.3.0.beta.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -20012,6 +20012,569 @@ $.extend($.ui.selectable, {
20012
20012
  })(jQuery);
20013
20013
 
20014
20014
 
20015
+ /*
20016
+ * jQuery UI selectmenu
20017
+ *
20018
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
20019
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
20020
+ * and GPL (GPL-LICENSE.txt) licenses.
20021
+ *
20022
+ * http://docs.jquery.com/UI
20023
+ */
20024
+
20025
+ (function($) {
20026
+
20027
+ $.widget("ui.selectmenu", {
20028
+ getter: "value",
20029
+ version: "1.8",
20030
+ eventPrefix: "selectmenu",
20031
+ options: {
20032
+ transferClasses: true,
20033
+ style: 'popup',
20034
+ width: null,
20035
+ menuWidth: null,
20036
+ handleWidth: 26,
20037
+ maxHeight: null,
20038
+ icons: null,
20039
+ format: null
20040
+ },
20041
+
20042
+ _create: function() {
20043
+ var self = this, o = this.options;
20044
+
20045
+ // set a default id value
20046
+ var selectmenuId = this.element.attr('id') || 'ui-selectmenu-' + Math.random().toString(16).slice(2, 10);
20047
+
20048
+ //quick array of button and menu id's
20049
+ this.ids = [selectmenuId + '-' + 'button', selectmenuId + '-' + 'menu'];
20050
+
20051
+ //define safe mouseup for future toggling
20052
+ this._safemouseup = true;
20053
+
20054
+ //create menu button wrapper
20055
+ this.newelement = $('<a class="'+ this.widgetBaseClass +' ui-widget ui-state-default ui-corner-all" id="'+this.ids[0]+'" role="button" href="#" aria-haspopup="true" aria-owns="'+this.ids[1]+'"></a>')
20056
+ .insertAfter(this.element);
20057
+
20058
+ //transfer tabindex
20059
+ var tabindex = this.element.attr('tabindex');
20060
+ if(tabindex){ this.newelement.attr('tabindex', tabindex); }
20061
+
20062
+ //save reference to select in data for ease in calling methods
20063
+ this.newelement.data('selectelement', this.element);
20064
+
20065
+ //menu icon
20066
+ this.selectmenuIcon = $('<span class="'+ this.widgetBaseClass +'-icon ui-icon"></span>')
20067
+ .prependTo(this.newelement)
20068
+ .addClass( (o.style == "popup")? 'ui-icon-triangle-2-n-s' : 'ui-icon-triangle-1-s' );
20069
+
20070
+
20071
+ //make associated form label trigger focus
20072
+ $('label[for='+this.element.attr('id')+']')
20073
+ .attr('for', this.ids[0])
20074
+ .bind('click', function(){
20075
+ self.newelement[0].focus();
20076
+ return false;
20077
+ });
20078
+
20079
+ //click toggle for menu visibility
20080
+ this.newelement
20081
+ .bind('mousedown', function(event){
20082
+ self._toggle(event);
20083
+ //make sure a click won't open/close instantly
20084
+ if(o.style == "popup"){
20085
+ self._safemouseup = false;
20086
+ setTimeout(function(){self._safemouseup = true;}, 300);
20087
+ }
20088
+ return false;
20089
+ })
20090
+ .bind('click',function(){
20091
+ return false;
20092
+ })
20093
+ .keydown(function(event){
20094
+ var ret = true;
20095
+ switch (event.keyCode) {
20096
+ case $.ui.keyCode.ENTER:
20097
+ ret = true;
20098
+ break;
20099
+ case $.ui.keyCode.SPACE:
20100
+ ret = false;
20101
+ self._toggle(event);
20102
+ break;
20103
+ case $.ui.keyCode.UP:
20104
+ case $.ui.keyCode.LEFT:
20105
+ ret = false;
20106
+ self._moveSelection(-1);
20107
+ break;
20108
+ case $.ui.keyCode.DOWN:
20109
+ case $.ui.keyCode.RIGHT:
20110
+ ret = false;
20111
+ self._moveSelection(1);
20112
+ break;
20113
+ case $.ui.keyCode.TAB:
20114
+ ret = true;
20115
+ break;
20116
+ default:
20117
+ ret = false;
20118
+ self._typeAhead(event.keyCode, 'mouseup');
20119
+ break;
20120
+ }
20121
+ return ret;
20122
+ })
20123
+ .bind('mouseover focus', function(){
20124
+ $(this).addClass(self.widgetBaseClass+'-focus ui-state-hover');
20125
+ })
20126
+ .bind('mouseout blur', function(){
20127
+ $(this).removeClass(self.widgetBaseClass+'-focus ui-state-hover');
20128
+ });
20129
+
20130
+ //document click closes menu
20131
+ $(document).mousedown(function(event){
20132
+ self.close(event);
20133
+ });
20134
+
20135
+ //change event on original selectmenu
20136
+ this.element
20137
+ .click(function(){ this._refreshValue(); })
20138
+ // newelement can be null under unclear circumstances in IE8
20139
+ .focus(function () { if (this.newelement) { this.newelement[0].focus(); } });
20140
+
20141
+ //create menu portion, append to body
20142
+ var cornerClass = (o.style == "dropdown")? " ui-corner-bottom" : " ui-corner-all";
20143
+ this.list = $('<ul class="' + self.widgetBaseClass + '-menu ui-widget ui-widget-content'+cornerClass+'" aria-hidden="true" role="listbox" aria-labelledby="'+this.ids[0]+'" id="'+this.ids[1]+'"></ul>').appendTo('body');
20144
+
20145
+ //serialize selectmenu element options
20146
+ var selectOptionData = [];
20147
+ this.element
20148
+ .find('option')
20149
+ .each(function(){
20150
+ selectOptionData.push({
20151
+ value: $(this).attr('value'),
20152
+ text: self._formatText(jQuery(this).text()),
20153
+ selected: $(this).attr('selected'),
20154
+ classes: $(this).attr('class'),
20155
+ parentOptGroup: $(this).parent('optgroup').attr('label')
20156
+ });
20157
+ });
20158
+
20159
+ //active state class is only used in popup style
20160
+ var activeClass = (self.options.style == "popup") ? " ui-state-active" : "";
20161
+
20162
+ //write li's
20163
+ for (var i = 0; i < selectOptionData.length; i++) {
20164
+ var thisLi = $('<li role="presentation"><a href="#" tabindex="-1" role="option" aria-selected="false">'+ selectOptionData[i].text +'</a></li>')
20165
+ .data('index',i)
20166
+ .addClass(selectOptionData[i].classes)
20167
+ .data('optionClasses', selectOptionData[i].classes|| '')
20168
+ .mouseup(function(event){
20169
+ if(self._safemouseup){
20170
+ var changed = $(this).data('index') != self._selectedIndex();
20171
+ self.value($(this).data('index'));
20172
+ self.select(event);
20173
+ if(changed){ self.change(event); }
20174
+ self.close(event,true);
20175
+ }
20176
+ return false;
20177
+ })
20178
+ .click(function(){
20179
+ return false;
20180
+ })
20181
+ .bind('mouseover focus', function(){
20182
+ self._selectedOptionLi().addClass(activeClass);
20183
+ self._focusedOptionLi().removeClass(self.widgetBaseClass+'-item-focus ui-state-hover');
20184
+ $(this).removeClass('ui-state-active').addClass(self.widgetBaseClass + '-item-focus ui-state-hover');
20185
+ })
20186
+ .bind('mouseout blur', function(){
20187
+ if($(this).is( self._selectedOptionLi() )){ $(this).addClass(activeClass); }
20188
+ $(this).removeClass(self.widgetBaseClass + '-item-focus ui-state-hover');
20189
+ });
20190
+
20191
+ //optgroup or not...
20192
+ if(selectOptionData[i].parentOptGroup){
20193
+ // whitespace in the optgroupname must be replaced, otherwise the li of existing optgroups are never found
20194
+ var optGroupName = self.widgetBaseClass + '-group-' + selectOptionData[i].parentOptGroup.replace(/[^a-zA-Z0-9]/g, "");
20195
+ if(this.list.find('li.' + optGroupName).size()){
20196
+ this.list.find('li.' + optGroupName + ':last ul').append(thisLi);
20197
+ }
20198
+ else{
20199
+ $('<li role="presentation" class="'+self.widgetBaseClass+'-group '+optGroupName+'"><span class="'+self.widgetBaseClass+'-group-label">'+selectOptionData[i].parentOptGroup+'</span><ul></ul></li>')
20200
+ .appendTo(this.list)
20201
+ .find('ul')
20202
+ .append(thisLi);
20203
+ }
20204
+ }
20205
+ else{
20206
+ thisLi.appendTo(this.list);
20207
+ }
20208
+
20209
+ //this allows for using the scrollbar in an overflowed list
20210
+ this.list.bind('mousedown mouseup', function(){return false;});
20211
+
20212
+ //append icon if option is specified
20213
+ if(o.icons){
20214
+ for(var j in o.icons){
20215
+ if(thisLi.is(o.icons[j].find)){
20216
+ thisLi
20217
+ .data('optionClasses', selectOptionData[i].classes + ' ' + self.widgetBaseClass + '-hasIcon')
20218
+ .addClass(self.widgetBaseClass + '-hasIcon');
20219
+ var iconClass = o.icons[j].icon || "";
20220
+
20221
+ thisLi
20222
+ .find('a:eq(0)')
20223
+ .prepend('<span class="'+self.widgetBaseClass+'-item-icon ui-icon '+iconClass + '"></span>');
20224
+ }
20225
+ }
20226
+ }
20227
+ }
20228
+
20229
+ //add corners to top and bottom menu items
20230
+ this.list.find('li:last').addClass("ui-corner-bottom");
20231
+ if(o.style == 'popup'){ this.list.find('li:first').addClass("ui-corner-top"); }
20232
+
20233
+ //transfer classes to selectmenu and list
20234
+ if(o.transferClasses){
20235
+ var transferClasses = this.element.attr('class') || '';
20236
+ this.newelement.add(this.list).addClass(transferClasses);
20237
+ }
20238
+
20239
+ //original selectmenu width
20240
+ var selectWidth = this.element.width();
20241
+
20242
+ //set menu button width
20243
+ this.newelement.width( (o.width) ? o.width : selectWidth);
20244
+
20245
+ //set menu width to either menuWidth option value, width option value, or select width
20246
+ if(o.style == 'dropdown'){ this.list.width( (o.menuWidth) ? o.menuWidth : ((o.width) ? o.width : selectWidth)); }
20247
+ else { this.list.width( (o.menuWidth) ? o.menuWidth : ((o.width) ? o.width - o.handleWidth : selectWidth - o.handleWidth)); }
20248
+
20249
+ //set max height from option
20250
+ if(o.maxHeight && o.maxHeight < this.list.height()){ this.list.height(o.maxHeight); }
20251
+
20252
+ //save reference to actionable li's (not group label li's)
20253
+ this._optionLis = this.list.find('li:not(.'+ self.widgetBaseClass +'-group)');
20254
+
20255
+ //transfer menu click to menu button
20256
+ this.list
20257
+ .keydown(function(event){
20258
+ var ret = true;
20259
+ switch (event.keyCode) {
20260
+ // this needs to be fixed as _moveFocus doesnt work correctly
20261
+ /*
20262
+ case $.ui.keyCode.UP:
20263
+ case $.ui.keyCode.LEFT:
20264
+ ret = false;
20265
+ self._moveFocus(-1);
20266
+ break;
20267
+ case $.ui.keyCode.DOWN:
20268
+ case $.ui.keyCode.RIGHT:
20269
+ ret = false;
20270
+ self._moveFocus(1);
20271
+ break;
20272
+ */
20273
+ case $.ui.keyCode.HOME:
20274
+ ret = false;
20275
+ self._moveFocus(':first');
20276
+ break;
20277
+ case $.ui.keyCode.PAGE_UP:
20278
+ ret = false;
20279
+ self._scrollPage('up');
20280
+ break;
20281
+ case $.ui.keyCode.PAGE_DOWN:
20282
+ ret = false;
20283
+ self._scrollPage('down');
20284
+ break;
20285
+ case $.ui.keyCode.END:
20286
+ ret = false;
20287
+ self._moveFocus(':last');
20288
+ break;
20289
+ case $.ui.keyCode.ENTER:
20290
+ case $.ui.keyCode.SPACE:
20291
+ ret = false;
20292
+ self.close(event,true);
20293
+ $(event.target).parents('li:eq(0)').trigger('mouseup');
20294
+ break;
20295
+ case $.ui.keyCode.TAB:
20296
+ ret = true;
20297
+ self.close(event,true);
20298
+ break;
20299
+ case $.ui.keyCode.ESCAPE:
20300
+ ret = false;
20301
+ self.close(event,true);
20302
+ break;
20303
+ default:
20304
+ ret = false;
20305
+ self._typeAhead(event.keyCode,'focus');
20306
+ break;
20307
+ }
20308
+ return ret;
20309
+ });
20310
+
20311
+ //selectmenu style
20312
+ if(o.style == 'dropdown'){
20313
+ this.newelement
20314
+ .addClass(self.widgetBaseClass+"-dropdown");
20315
+ this.list
20316
+ .addClass(self.widgetBaseClass+"-menu-dropdown");
20317
+ }
20318
+ else {
20319
+ this.newelement
20320
+ .addClass(self.widgetBaseClass+"-popup");
20321
+ this.list
20322
+ .addClass(self.widgetBaseClass+"-menu-popup");
20323
+ }
20324
+
20325
+ //append status span to button
20326
+ this.newelement.prepend('<span class="'+self.widgetBaseClass+'-status">'+ selectOptionData[this._selectedIndex()].text +'</span>');
20327
+
20328
+ //hide original selectmenu element
20329
+ this.element.hide();
20330
+
20331
+ //transfer disabled state
20332
+ if(this.element.attr('disabled') == true){ this.disable(); }
20333
+
20334
+ //update value
20335
+ this.value(this._selectedIndex());
20336
+
20337
+ // needed when window is resized
20338
+ $(window).resize(function(){
20339
+ self._refreshPosition();
20340
+ });
20341
+ },
20342
+ destroy: function() {
20343
+ this.element.removeData(this.widgetName)
20344
+ .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
20345
+ .removeAttr('aria-disabled')
20346
+ .unbind("click");
20347
+
20348
+ //unbind click on label, reset its for attr
20349
+ $('label[for='+this.newelement.attr('id')+']')
20350
+ .attr('for',this.element.attr('id'))
20351
+ .unbind('click');
20352
+ this.newelement.remove();
20353
+ this.list.remove();
20354
+ this.element.show();
20355
+
20356
+ // call widget destroy function
20357
+ $.Widget.prototype.destroy.apply(this, arguments);
20358
+ },
20359
+ _typeAhead: function(code, eventType){
20360
+ var self = this;
20361
+ //define self._prevChar if needed
20362
+ if(!self._prevChar){ self._prevChar = ['',0]; }
20363
+ var C = String.fromCharCode(code);
20364
+ c = C.toLowerCase();
20365
+ var focusFound = false;
20366
+ function focusOpt(elem, ind){
20367
+ focusFound = true;
20368
+ $(elem).trigger(eventType);
20369
+ self._prevChar[1] = ind;
20370
+ }
20371
+ this.list.find('li a').each(function(i){
20372
+ if(!focusFound){
20373
+ var thisText = $(this).text();
20374
+ if( thisText.indexOf(C) == 0 || thisText.indexOf(c) == 0){
20375
+ if(self._prevChar[0] == C){
20376
+ if(self._prevChar[1] < i){ focusOpt(this,i); }
20377
+ }
20378
+ else{ focusOpt(this,i); }
20379
+ }
20380
+ }
20381
+ });
20382
+ this._prevChar[0] = C;
20383
+ },
20384
+ _uiHash: function(){
20385
+ var index = this.value();
20386
+ return {
20387
+ index: index,
20388
+ option: $("option", this.element).get(index),
20389
+ value: this.element[0].value
20390
+ };
20391
+ },
20392
+ open: function(event){
20393
+ var self = this;
20394
+ var disabledStatus = this.newelement.attr("aria-disabled");
20395
+ if(disabledStatus != 'true'){
20396
+ this._refreshPosition();
20397
+ this._closeOthers(event);
20398
+ this.newelement
20399
+ .addClass('ui-state-active');
20400
+
20401
+ this.list
20402
+ .appendTo('body')
20403
+ .addClass(self.widgetBaseClass + '-open')
20404
+ .attr('aria-hidden', false)
20405
+ .find('li:not(.'+ self.widgetBaseClass +'-group):eq('+ this._selectedIndex() +') a')[0].focus();
20406
+ if(this.options.style == "dropdown"){ this.newelement.removeClass('ui-corner-all').addClass('ui-corner-top'); }
20407
+ this._refreshPosition();
20408
+ this._trigger("open", event, this._uiHash());
20409
+ }
20410
+ },
20411
+ close: function(event, retainFocus){
20412
+ if(this.newelement.is('.ui-state-active')){
20413
+ this.newelement
20414
+ .removeClass('ui-state-active');
20415
+ this.list
20416
+ .attr('aria-hidden', true)
20417
+ .removeClass(this.widgetBaseClass+'-open');
20418
+ if(this.options.style == "dropdown"){ this.newelement.removeClass('ui-corner-top').addClass('ui-corner-all'); }
20419
+ if(retainFocus){this.newelement[0].focus();}
20420
+ this._trigger("close", event, this._uiHash());
20421
+ }
20422
+ },
20423
+ change: function(event) {
20424
+ this.element.trigger('change');
20425
+ this._trigger("change", event, this._uiHash());
20426
+ },
20427
+ select: function(event) {
20428
+ this._trigger("select", event, this._uiHash());
20429
+ },
20430
+ _closeOthers: function(event){
20431
+ $('.'+ this.widgetBaseClass +'.ui-state-active').not(this.newelement).each(function(){
20432
+ $(this).data('selectelement').selectmenu('close',event);
20433
+ });
20434
+ $('.'+ this.widgetBaseClass +'.ui-state-hover').trigger('mouseout');
20435
+ },
20436
+ _toggle: function(event,retainFocus){
20437
+ if(this.list.is('.'+ this.widgetBaseClass +'-open')){ this.close(event,retainFocus); }
20438
+ else { this.open(event); }
20439
+ },
20440
+ _formatText: function(text){
20441
+ return this.options.format ? this.options.format(text) : text;
20442
+ },
20443
+ _selectedIndex: function(){
20444
+ return this.element[0].selectedIndex;
20445
+ },
20446
+ _selectedOptionLi: function(){
20447
+ return this._optionLis.eq(this._selectedIndex());
20448
+ },
20449
+ _focusedOptionLi: function(){
20450
+ return this.list.find('.'+ this.widgetBaseClass +'-item-focus');
20451
+ },
20452
+ _moveSelection: function(amt){
20453
+ var currIndex = parseInt(this._selectedOptionLi().data('index'), 10);
20454
+ var newIndex = currIndex + amt;
20455
+ return this._optionLis.eq(newIndex).trigger('mouseup');
20456
+ },
20457
+ _moveFocus: function(amt){
20458
+ if(!isNaN(amt)){
20459
+ var currIndex = parseInt(this._focusedOptionLi().data('index'), 10);
20460
+ var newIndex = currIndex + amt;
20461
+ }
20462
+ else { var newIndex = parseInt(this._optionLis.filter(amt).data('index'), 10); }
20463
+
20464
+ if(newIndex < 0){ newIndex = 0; }
20465
+ if(newIndex > this._optionLis.size()-1){
20466
+ newIndex = this._optionLis.size()-1;
20467
+ }
20468
+ var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
20469
+
20470
+ this._focusedOptionLi().find('a:eq(0)').attr('id','');
20471
+ this._optionLis.eq(newIndex).find('a:eq(0)').attr('id',activeID)[0].focus();
20472
+ this.list.attr('aria-activedescendant', activeID);
20473
+ },
20474
+ _scrollPage: function(direction){
20475
+ var numPerPage = Math.floor(this.list.outerHeight() / this.list.find('li:first').outerHeight());
20476
+ numPerPage = (direction == 'up') ? -numPerPage : numPerPage;
20477
+ this._moveFocus(numPerPage);
20478
+ },
20479
+ _setOption: function(key, value) {
20480
+ this.options[key] = value;
20481
+ if (key == 'disabled') {
20482
+ this.close();
20483
+ this.element
20484
+ .add(this.newelement)
20485
+ .add(this.list)
20486
+ [value ? 'addClass' : 'removeClass'](
20487
+ this.widgetBaseClass + '-disabled' + ' ' +
20488
+ this.namespace + '-state-disabled')
20489
+ .attr("aria-disabled", value);
20490
+ }
20491
+ },
20492
+ value: function(newValue) {
20493
+ if (arguments.length) {
20494
+ this.element[0].selectedIndex = newValue;
20495
+ this._refreshValue();
20496
+ this._refreshPosition();
20497
+ }
20498
+ return this.element[0].selectedIndex;
20499
+ },
20500
+ _refreshValue: function() {
20501
+ var activeClass = (this.options.style == "popup") ? " ui-state-active" : "";
20502
+ var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
20503
+ //deselect previous
20504
+ this.list
20505
+ .find('.'+ this.widgetBaseClass +'-item-selected')
20506
+ .removeClass(this.widgetBaseClass + "-item-selected" + activeClass)
20507
+ .find('a')
20508
+ .attr('aria-selected', 'false')
20509
+ .attr('id', '');
20510
+ //select new
20511
+ this._selectedOptionLi()
20512
+ .addClass(this.widgetBaseClass + "-item-selected"+activeClass)
20513
+ .find('a')
20514
+ .attr('aria-selected', 'true')
20515
+ .attr('id', activeID);
20516
+
20517
+ //toggle any class brought in from option
20518
+ var currentOptionClasses = this.newelement.data('optionClasses') ? this.newelement.data('optionClasses') : "";
20519
+ var newOptionClasses = this._selectedOptionLi().data('optionClasses') ? this._selectedOptionLi().data('optionClasses') : "";
20520
+ this.newelement
20521
+ .removeClass(currentOptionClasses)
20522
+ .data('optionClasses', newOptionClasses)
20523
+ .addClass( newOptionClasses )
20524
+ .find('.'+this.widgetBaseClass+'-status')
20525
+ .html(
20526
+ this._selectedOptionLi()
20527
+ .find('a:eq(0)')
20528
+ .html()
20529
+ );
20530
+
20531
+ this.list.attr('aria-activedescendant', activeID);
20532
+ },
20533
+ _refreshPosition: function(){
20534
+ var self = this, o = this.options;
20535
+
20536
+ // get some vars
20537
+ var pageScroll = self._pageScroll();
20538
+ var menuTop = this.newelement.offset().top;
20539
+ var viewportHeight = $(window).height();
20540
+ var listHeight = $(this.list[0]).outerHeight();
20541
+
20542
+ // check if there's enough room to expand to the bottom
20543
+ if ((menuTop + listHeight) > (viewportHeight + pageScroll)) {
20544
+ menuTop -= listHeight;
20545
+ } else {
20546
+ if (this.newelement.is('.'+this.widgetBaseClass+'-popup')) {
20547
+ var scrolledAmt = this.list[0].scrollTop;
20548
+ this.list.find('li:lt('+this._selectedIndex()+')').each(function() {
20549
+ scrolledAmt -= $(this).outerHeight();
20550
+ });
20551
+ menuTop+=scrolledAmt;
20552
+ } else {
20553
+ menuTop += this.newelement.height();
20554
+ }
20555
+ }
20556
+ // set values
20557
+ this.list.css({
20558
+ top: menuTop,
20559
+ left: this.newelement.offset().left
20560
+ });
20561
+ },
20562
+ _pageScroll: function() {
20563
+ var yScroll;
20564
+ if (self.pageYOffset) {
20565
+ yScroll = self.pageYOffset;
20566
+ // Explorer 6 Strict
20567
+ } else if (document.documentElement && document.documentElement.scrollTop) {
20568
+ yScroll = document.documentElement.scrollTop;
20569
+ // all other Explorers
20570
+ } else if (document.body) {
20571
+ yScroll = document.body.scrollTop;
20572
+ }
20573
+ return yScroll;
20574
+ }
20575
+ });
20576
+ })(jQuery);
20577
+
20015
20578
  /*
20016
20579
  * jQuery UI Slider 1.8.5
20017
20580
  *