git.fiddlerwoaroof.com
jquery.accordion.js
286e4ed1
 (function($) {
     $.widget("ui.accordion1", {
         options: {
             helpDialog: $('<div class="help"></div>'),
             active: 0,
             animated: 'slide',
             clearStyle: false,
             manyOpen: true,
             event: "click",
             fillSpace: false,
             header: "> li > :first-child,> :not(li):even",
             icons: {
                 header: "ui-icon-triangle-1-e",
                 headerSelected: "ui-icon-triangle-1-s"
             },
             navigation: false,
             navigationFilter: function() {
                 return this.href.toLowerCase() == location.href.toLowerCase();
             }
 
         },
 
         _create: function() {
 
             var o = this.options, self = this;
             this.running = 0;
 
             this._initHelp(o.helpDialog);
             this.element.addClass("ui-accordion ui-widget ui-helper-reset");
 
             // in lack of child-selectors in CSS we need to mark top-LIs in a UL-accordion for some IE-fix
             this.element.children("li").addClass("ui-accordion-li-fix");
 
             this.headers = this.element.find(o.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all")
                 .bind("mouseenter.accordion", function(){ $(this).addClass('ui-state-hover'); })
                 .bind("mouseleave.accordion", function(){ $(this).removeClass('ui-state-hover'); })
                 .bind("focus.accordion", function(){ $(this).addClass('ui-state-focus'); })
                 .bind("blur.accordion", function(){ $(this).removeClass('ui-state-focus'); });
 
             this.headers
                 .next()
                 .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
 
             if ( o.navigation ) {
                 var current = this.element.find("a").filter(o.navigationFilter);
                 if ( current.length ) {
                     var header = current.closest(".ui-accordion-header");
                     if ( header.length ) {
                         // anchor within header
                         this.active = header;
                     } else {
                         // anchor within content
                         this.active = current.closest(".ui-accordion-content").prev();
                     }
                 }
             }
 
             this.active = $(this.headers.get(0));
 
             //Append icon elements
             //this._createIcons();
 
             //this.resize();
 
             //ARIA
             this.element.attr('role','tablist');
 
             this.headers
                 .attr('role','tab')
                 .bind('keydown', function(event) { return self._keydown(event); })
                 .next()
                 .attr('role','tabpanel');
 
             this.headers
                 .attr('aria-expanded','false')
                 .attr("tabIndex", "0")
                 .next()
                 .hide();
 
 
             // only need links in taborder for Safari
             if (!$.browser.safari)
                 this.headers.find('a').attr('tabIndex','-1');
 
             if (o.event) {
                 this.headers.bind((o.event) + ".accordion", function(event) {
                     self._clickHandler.call(self, event, this);
                     event.preventDefault();
                 });
                 this.active.trigger(o.event)
             }
 
             this.active.focus();
         },
 
         _initHelp: function(target) {
             var self = this;
             $(target).prepend(
                 '<table style="margin: auto auto">\n' +
                     '   <thead><tr><th>Key</th><th>Action</th></tr></thead>\n' +
                     '   <tbody><tr><td>Movement:</td><td>Arrow keys, vi keys or wasd</tr>\n' +
                     '         <tr><td><pre>\n' +
                     '           w\n' +
                     '         a s d\n' +
                     '         </pre></td><td><pre>\n' +
                     '           k\n' +
                     '         h j l\n' +
                     '         </pre></td>\n' +
                     '   </tr><tr class="s">\n' +
                     '         <td>Shift+up or down:</td><td>Keep current pane open and switch to appropriate pane</td>\n' +
                     '      </tr><tr>\n' +
                     '         <td>Right, Enter:</td><td>Open current item</td>\n' +
                     '      </tr><tr class="s">\n' +
                     '         <td>Left, Enter:</td><td>Close current item</td>\n' +
                     '      </tr><tr class="s">\n' +
                     '         <td>Space:</td><td>Scroll down if current element not fully visible, otherwise go to next</td>\n' +
                     '      </tr><tr>\n' +
                     "         <td>'?':</td><td>Help</td>\n" +
                     '      </tr>\n' +
                     '   </tbody>\n' +
                     '</table>\n'
             ).dialog({autoOpen: false, modal: true, title: 'Help (\'q\' or Escape to exit)', minWidth: 402, width: 402});
 
             $('body').bind('keydown', function(event) {
                 if (event.shiftKey && event.which == 191) { // 191 == '?'
                     self.help();
                 } else if (event.which == 81 && self.options.helpDialog.dialog('isOpen')) { // 81 == 'q'
                     self.help();
                 };
             });
             if (this.options.helpTrigger)  {
                 $(this.options.helpTrigger).click( function() { self.help(); });
             }
 
 
 
         },
 
         _keydown: function(event) {
 
             var o = this.options, keyCode = $.ui.keyCode;
 
             if (o.disabled || event.altKey || event.ctrlKey)
                 return;
 
             var length = this.headers.length;
             var currentIndex = this.headers.index(event.target);
             var toFocus = false;
             var is_space = false;
             var result = false;
 
             switch(event.keyCode) {
             case keyCode.SPACE:
                 is_space = true;
                 toFocus = this.headers[(currentIndex + 1) % length];
                 break;
             case 74: // j
             case 83: // s
             case keyCode.DOWN:
                 toFocus = this.headers[(currentIndex + 1) % length];
                 break;
             case keyCode.UP:
             case 75: // k
             case 87: // w
                 toFocus = this.headers[(currentIndex - 1 + length) % length];
                 break;
             case keyCode.RIGHT:
             case 76: // l
             case 68: // l
                 this.show(event.target);
                 break;
             case keyCode.LEFT:
             case 72: // h
             case 65: // h
                 this.hide(event.target);
                 break;
             case keyCode.ENTER:
                 $(event.target).stop();
                 this.toggle(event.target);
                 event.preventDefault();
             }
 
             if (toFocus) {
                 //console.log(this.active.next().offset().top + this.active.next().outerHeight());
                 //console.log($(window).height()+$(window).scrollTop());
                 console.log((this.active.next().offset().top + this.active.next().outerHeight()) > ($(window).height() + $(window).scrollTop()));
                 console.log(toFocus);
                 var windowBottom = $(window).height() + $(window).scrollTop()
                 if (is_space && ((this.active.next().offset().top + this.active.next().outerHeight()) > windowBottom)) {
                     result = true;
                     toFocus = this.active;
                 } else {
                     result = false;
                     if (!event.shiftKey) this.hide(this.active);
                 };
                 console.log(toFocus);
                 console.log(toFocus == this.active);
 
                 if (toFocus != this.active) {
                     this.active = $(toFocus);
                     toFocus.focus();
                     this.show(this.active);
                 }
 
             } else { result = true; }
 
             return result;
 
         },
 
         show: function(target) {
             var target = $(target);
             target.stop();
             target.removeClass("ui-state-default").addClass("ui-state-active").removeClass("ui-corner-all").addClass("ui-corner-top");
             target.next().show();
         },
         hide: function(target) {
             var target = $(target);
             target.stop();
             target.addClass("ui-state-default").removeClass("ui-state-active").addClass("ui-corner-all").removeClass("ui-corner-top");
             target.next().hide();
         },
         toggle: function(target) {
             var target = $(target);
             target.stop();
             target.toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");
             target.next().toggle();
         },
 
         _clickHandler: function(event, target) {
             console.log(target);
             this.active = $(target);
             this.active.stop()
             this.active.toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");
             this.active.next().toggle();
             this.active.focus();
 
         },
 
 		destroy: function() {
 		},
 
 		_setOption: function(option, value) {
 			$.Widget.prototype._setOption.apply( this, arguments );
 		},
 
         help: function(target) {
             if (!this.options.helpDialog.dialog('isOpen'))
                 this.options.helpDialog.dialog('open');
             else
                 this.options.helpDialog.dialog('close');
         }
 
 	});
 })(jQuery);