Skip to content
Snippets Groups Projects
Commit 9ba12248 authored by gitlabhq's avatar gitlabhq
Browse files

init commit

parent 93efff94
No related branches found
No related tags found
No related merge requests found
Showing
with 2859 additions and 0 deletions
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/*
* jQuery UI selectmenu dev version
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI
* https://github.com/fnagel/jquery-ui/wiki/Selectmenu
*/
(function($) {
$.widget("ui.selectmenu", {
getter: "value",
version: "1.8",
eventPrefix: "selectmenu",
options: {
transferClasses: true,
typeAhead: "sequential",
style: 'dropdown',
positionOptions: {
my: "left top",
at: "left bottom",
offset: null
},
width: null,
menuWidth: null,
handleWidth: 26,
maxHeight: null,
icons: null,
format: null,
bgImage: function() {},
wrapperElement: "<div />"
},
_create: function() {
var self = this, o = this.options;
// set a default id value, generate a new random one if not set by developer
var selectmenuId = this.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 );
// quick array of button and menu id's
this.ids = [ selectmenuId + '-button', selectmenuId + '-menu' ];
// define safe mouseup for future toggling
this._safemouseup = true;
// create menu button wrapper
this.newelement = $( '<a />', {
'class': this.widgetBaseClass + ' ui-widget ui-state-default ui-corner-all',
'id' : this.ids[ 0 ],
'role': 'button',
'href': '#nogo',
'tabindex': this.element.attr( 'disabled' ) ? 1 : 0,
'aria-haspopup': true,
'aria-owns': this.ids[ 1 ]
});
this.newelementWrap = $( o.wrapperElement )
.append( this.newelement )
.insertAfter( this.element );
// transfer tabindex
var tabindex = this.element.attr( 'tabindex' );
if ( tabindex ) {
this.newelement.attr( 'tabindex', tabindex );
}
// save reference to select in data for ease in calling methods
this.newelement.data( 'selectelement', this.element );
// menu icon
this.selectmenuIcon = $( '<span class="' + this.widgetBaseClass + '-icon ui-icon"></span>' )
.prependTo( this.newelement );
// append status span to button
this.newelement.prepend( '<span class="' + self.widgetBaseClass + '-status" />' );
// make associated form label trigger focus
$( 'label[for="' + selectmenuId + '"]' )
.attr( 'for', this.ids[0] )
.bind( 'click.selectmenu', function() {
self.newelement[0].focus();
return false;
});
// click toggle for menu visibility
this.newelement
.bind('mousedown.selectmenu', function(event) {
self._toggle(event, true);
// make sure a click won't open/close instantly
if (o.style == "popup") {
self._safemouseup = false;
setTimeout(function() { self._safemouseup = true; }, 300);
}
return false;
})
.bind('click.selectmenu', function() {
return false;
})
.bind("keydown.selectmenu", function(event) {
var ret = false;
switch (event.keyCode) {
case $.ui.keyCode.ENTER:
ret = true;
break;
case $.ui.keyCode.SPACE:
self._toggle(event);
break;
case $.ui.keyCode.UP:
if (event.altKey) {
self.open(event);
} else {
self._moveSelection(-1);
}
break;
case $.ui.keyCode.DOWN:
if (event.altKey) {
self.open(event);
} else {
self._moveSelection(1);
}
break;
case $.ui.keyCode.LEFT:
self._moveSelection(-1);
break;
case $.ui.keyCode.RIGHT:
self._moveSelection(1);
break;
case $.ui.keyCode.TAB:
ret = true;
break;
default:
ret = true;
}
return ret;
})
.bind('keypress.selectmenu', function(event) {
self._typeAhead(event.which, 'mouseup');
return true;
})
.bind('mouseover.selectmenu focus.selectmenu', function() {
if (!o.disabled) {
$(this).addClass(self.widgetBaseClass + '-focus ui-state-hover');
}
})
.bind('mouseout.selectmenu blur.selectmenu', function() {
if (!o.disabled) {
$(this).removeClass(self.widgetBaseClass + '-focus ui-state-hover');
}
});
// document click closes menu
$(document).bind("mousedown.selectmenu", function(event) {
self.close(event);
});
// change event on original selectmenu
this.element
.bind("click.selectmenu", function() {
self._refreshValue();
})
// FIXME: newelement can be null under unclear circumstances in IE8
// TODO not sure if this is still a problem (fnagel 20.03.11)
.bind("focus.selectmenu", function() {
if (self.newelement) {
self.newelement[0].focus();
}
});
// set width when not set via options
if (!o.width) {
o.width = this.element.outerWidth();
}
// set menu button width
this.newelement.width(o.width);
// hide original selectmenu element
this.element.hide();
// create menu portion, append to body
this.list = $( '<ul />', {
'class': 'ui-widget ui-widget-content',
'aria-hidden': true,
'role': 'listbox',
'aria-labelledby': this.ids[0],
'id': this.ids[1]
});
this.listWrap = $( o.wrapperElement )
.addClass( self.widgetBaseClass + '-menu' )
.append( this.list )
.appendTo( 'body' );
// transfer menu click to menu button
this.list
.bind("keydown.selectmenu", function(event) {
var ret = false;
switch (event.keyCode) {
case $.ui.keyCode.UP:
if (event.altKey) {
self.close(event, true);
} else {
self._moveFocus(-1);
}
break;
case $.ui.keyCode.DOWN:
if (event.altKey) {
self.close(event, true);
} else {
self._moveFocus(1);
}
break;
case $.ui.keyCode.LEFT:
self._moveFocus(-1);
break;
case $.ui.keyCode.RIGHT:
self._moveFocus(1);
break;
case $.ui.keyCode.HOME:
self._moveFocus(':first');
break;
case $.ui.keyCode.PAGE_UP:
self._scrollPage('up');
break;
case $.ui.keyCode.PAGE_DOWN:
self._scrollPage('down');
break;
case $.ui.keyCode.END:
self._moveFocus(':last');
break;
case $.ui.keyCode.ENTER:
case $.ui.keyCode.SPACE:
self.close(event, true);
$(event.target).parents('li:eq(0)').trigger('mouseup');
break;
case $.ui.keyCode.TAB:
ret = true;
self.close(event, true);
$(event.target).parents('li:eq(0)').trigger('mouseup');
break;
case $.ui.keyCode.ESCAPE:
self.close(event, true);
break;
default:
ret = true;
}
return ret;
})
.bind('keypress.selectmenu', function(event) {
self._typeAhead(event.which, 'focus');
return true;
})
// this allows for using the scrollbar in an overflowed list
.bind( 'mousedown.selectmenu mouseup.selectmenu', function() { return false; });
// needed when window is resized
// TODO seems to be useless, but causes errors (fnagel 01.08.11)
// see: https://github.com/fnagel/jquery-ui/issues/147
// $(window).bind( "resize.selectmenu", $.proxy( self._refreshPosition, this ) );
},
_init: function() {
var self = this, o = this.options;
// serialize selectmenu element options
var selectOptionData = [];
this.element
.find('option')
.each(function() {
var opt = $(this);
selectOptionData.push({
value: opt.attr('value'),
text: self._formatText(opt.text()),
selected: opt.attr('selected'),
disabled: opt.attr('disabled'),
classes: opt.attr('class'),
typeahead: opt.attr('typeahead'),
parentOptGroup: opt.parent('optgroup'),
bgImage: o.bgImage.call(opt)
});
});
// active state class is only used in popup style
var activeClass = (self.options.style == "popup") ? " ui-state-active" : "";
// empty list so we can refresh the selectmenu via selectmenu()
this.list.html("");
// write li's
if (selectOptionData.length) {
for (var i = 0; i < selectOptionData.length; i++) {
var thisLiAttr = { role : 'presentation' };
if ( selectOptionData[ i ].disabled ) {
thisLiAttr[ 'class' ] = this.namespace + '-state-disabled';
}
var thisAAttr = {
html: selectOptionData[i].text,
href : '#nogo',
tabindex : -1,
role : 'option',
'aria-selected' : false
};
if ( selectOptionData[ i ].disabled ) {
thisAAttr[ 'aria-disabled' ] = selectOptionData[ i ].disabled;
}
if ( selectOptionData[ i ].typeahead ) {
thisAAttr[ 'typeahead' ] = selectOptionData[ i ].typeahead;
}
var thisA = $('<a/>', thisAAttr);
var thisLi = $('<li/>', thisLiAttr)
.append(thisA)
.data('index', i)
.addClass(selectOptionData[i].classes)
.data('optionClasses', selectOptionData[i].classes || '')
.bind("mouseup.selectmenu", function(event) {
if (self._safemouseup && !self._disabled(event.currentTarget) && !self._disabled($( event.currentTarget ).parents( "ul>li." + self.widgetBaseClass + "-group " )) ) {
var changed = $(this).data('index') != self._selectedIndex();
self.index($(this).data('index'));
self.select(event);
if (changed) {
self.change(event);
}
self.close(event, true);
}
return false;
})
.bind("click.selectmenu", function() {
return false;
})
.bind('mouseover.selectmenu focus.selectmenu', function(e) {
// no hover if diabled
if (!$(e.currentTarget).hasClass(self.namespace + '-state-disabled') && !$(e.currentTarget).parent("ul").parent("li").hasClass(self.namespace + '-state-disabled')) {
self._selectedOptionLi().addClass(activeClass);
self._focusedOptionLi().removeClass(self.widgetBaseClass + '-item-focus ui-state-hover');
$(this).removeClass('ui-state-active').addClass(self.widgetBaseClass + '-item-focus ui-state-hover');
}
})
.bind('mouseout.selectmenu blur.selectmenu', function() {
if ($(this).is(self._selectedOptionLi().selector)) {
$(this).addClass(activeClass);
}
$(this).removeClass(self.widgetBaseClass + '-item-focus ui-state-hover');
});
// optgroup or not...
if ( selectOptionData[i].parentOptGroup.length ) {
var optGroupName = self.widgetBaseClass + '-group-' + this.element.find( 'optgroup' ).index( selectOptionData[i].parentOptGroup );
if (this.list.find( 'li.' + optGroupName ).length ) {
this.list.find( 'li.' + optGroupName + ':last ul' ).append( thisLi );
} else {
$(' <li role="presentation" class="' + self.widgetBaseClass + '-group ' + optGroupName + (selectOptionData[i].parentOptGroup.attr("disabled") ? ' ' + this.namespace + '-state-disabled" aria-disabled="true"' : '"' ) + '><span class="' + self.widgetBaseClass + '-group-label">' + selectOptionData[i].parentOptGroup.attr('label') + '</span><ul></ul></li> ')
.appendTo( this.list )
.find( 'ul' )
.append( thisLi );
}
} else {
thisLi.appendTo(this.list);
}
// append icon if option is specified
if (o.icons) {
for (var j in o.icons) {
if (thisLi.is(o.icons[j].find)) {
thisLi
.data('optionClasses', selectOptionData[i].classes + ' ' + self.widgetBaseClass + '-hasIcon')
.addClass(self.widgetBaseClass + '-hasIcon');
var iconClass = o.icons[j].icon || "";
thisLi
.find('a:eq(0)')
.prepend('<span class="' + self.widgetBaseClass + '-item-icon ui-icon ' + iconClass + '"></span>');
if (selectOptionData[i].bgImage) {
thisLi.find('span').css('background-image', selectOptionData[i].bgImage);
}
}
}
}
}
} else {
$('<li role="presentation"><a href="#nogo" tabindex="-1" role="option"></a></li>').appendTo(this.list);
}
// we need to set and unset the CSS classes for dropdown and popup style
var isDropDown = ( o.style == 'dropdown' );
this.newelement
.toggleClass( self.widgetBaseClass + '-dropdown', isDropDown )
.toggleClass( self.widgetBaseClass + '-popup', !isDropDown );
this.list
.toggleClass( self.widgetBaseClass + '-menu-dropdown ui-corner-bottom', isDropDown )
.toggleClass( self.widgetBaseClass + '-menu-popup ui-corner-all', !isDropDown )
// add corners to top and bottom menu items
.find( 'li:first' )
.toggleClass( 'ui-corner-top', !isDropDown )
.end().find( 'li:last' )
.addClass( 'ui-corner-bottom' );
this.selectmenuIcon
.toggleClass( 'ui-icon-triangle-1-s', isDropDown )
.toggleClass( 'ui-icon-triangle-2-n-s', !isDropDown );
// transfer classes to selectmenu and list
if ( o.transferClasses ) {
var transferClasses = this.element.attr( 'class' ) || '';
this.newelement.add( this.list ).addClass( transferClasses );
}
// set menu width to either menuWidth option value, width option value, or select width
if ( o.style == 'dropdown' ) {
this.list.width( o.menuWidth ? o.menuWidth : o.width );
} else {
this.list.width( o.menuWidth ? o.menuWidth : o.width - o.handleWidth );
}
// reset height to auto
this.list.css( 'height', 'auto' );
var listH = this.listWrap.height();
// calculate default max height
if ( o.maxHeight && o.maxHeight < listH ) {
this.list.height( o.maxHeight );
} else {
var winH = $( window ).height() / 3;
if ( winH < listH ) this.list.height( winH );
}
// save reference to actionable li's (not group label li's)
this._optionLis = this.list.find( 'li:not(.' + self.widgetBaseClass + '-group)' );
// transfer disabled state
if ( this.element.attr( 'disabled' ) ) {
this.disable();
} else {
this.enable()
}
// update value
this.index( this._selectedIndex() );
// needed when selectmenu is placed at the very bottom / top of the page
window.setTimeout( function() {
self._refreshPosition();
}, 200 );
},
destroy: function() {
this.element.removeData( this.widgetName )
.removeClass( this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled' )
.removeAttr( 'aria-disabled' )
.unbind( ".selectmenu" );
// TODO unneded as event binding has been disabled
// $( window ).unbind( ".selectmenu" );
$( document ).unbind( ".selectmenu" );
// unbind click on label, reset its for attr
$( 'label[for=' + this.newelement.attr('id') + ']' )
.attr( 'for', this.element.attr( 'id' ) )
.unbind( '.selectmenu' );
this.newelementWrap.remove();
this.listWrap.remove();
this.element.show();
// call widget destroy function
$.Widget.prototype.destroy.apply(this, arguments);
},
_typeAhead: function( code, eventType ){
var self = this, focusFound = false, C = String.fromCharCode(code).toUpperCase();
c = C.toLowerCase();
if ( self.options.typeAhead == 'sequential' ) {
// clear the timeout so we can use _prevChar
window.clearTimeout('ui.selectmenu-' + self.selectmenuId);
// define our find var
var find = typeof( self._prevChar ) == 'undefined' ? '' : self._prevChar.join( '' );
function focusOptSeq( elem, ind, c ){
focusFound = true;
$( elem ).trigger( eventType );
typeof( self._prevChar ) == 'undefined' ? self._prevChar = [ c ] : self._prevChar[ self._prevChar.length ] = c;
}
this.list.find( 'li a' ).each( function( i ) {
if ( !focusFound ) {
// allow the typeahead attribute on the option tag for a more specific lookup
var thisText = $( this ).attr( 'typeahead' ) || $(this).text();
if ( thisText.indexOf( find + C ) === 0 ) {
focusOptSeq( this, i, C );
} else if (thisText.indexOf(find+c) === 0 ) {
focusOptSeq( this, i, c );
}
}
});
// set a 1 second timeout for sequenctial typeahead
// keep this set even if we have no matches so it doesnt typeahead somewhere else
window.setTimeout( function( el ) {
self._prevChar = undefined;
}, 1000, self );
} else {
// define self._prevChar if needed
if ( !self._prevChar ) { self._prevChar = [ '' , 0 ]; }
focusFound = false;
function focusOpt( elem, ind ){
focusFound = true;
$( elem ).trigger( eventType );
self._prevChar[ 1 ] = ind;
}
this.list.find( 'li a' ).each(function( i ){
if (!focusFound){
var thisText = $(this).text();
if ( thisText.indexOf( C ) === 0 || thisText.indexOf( c ) === 0 ) {
if (self._prevChar[0] == C){
if ( self._prevChar[ 1 ] < i ){ focusOpt( this, i ); }
} else{
focusOpt( this, i );
}
}
}
});
this._prevChar[ 0 ] = C;
}
},
// returns some usefull information, called by callbacks only
_uiHash: function() {
var index = this.index();
return {
index: index,
option: $("option", this.element).get(index),
value: this.element[0].value
};
},
open: function(event) {
var self = this, o = this.options;
if ( self.newelement.attr("aria-disabled") != 'true' ) {
self._closeOthers(event);
self.newelement.addClass('ui-state-active');
self.listWrap.appendTo( o.appendTo );
self.list.attr('aria-hidden', false);
if ( o.style == "dropdown" ) {
self.newelement.removeClass('ui-corner-all').addClass('ui-corner-top');
}
self.listWrap.addClass( self.widgetBaseClass + '-open' );
// positioning needed for IE7 (tested 01.08.11 on MS VPC Image)
// see https://github.com/fnagel/jquery-ui/issues/147
if ( $.browser.msie && $.browser.version.substr( 0,1 ) == 7 ) {
self._refreshPosition();
}
var selected = self.list.attr('aria-hidden', false).find('li:not(.' + self.widgetBaseClass + '-group):eq(' + self._selectedIndex() + '):visible a');
if (selected.length) selected[0].focus();
// positioning needed for FF, Chrome, IE8, IE7, IE6 (tested 01.08.11 on MS VPC Image)
self._refreshPosition();
self._trigger("open", event, self._uiHash());
}
},
close: function(event, retainFocus) {
if ( this.newelement.is('.ui-state-active') ) {
this.newelement
.removeClass('ui-state-active');
this.listWrap.removeClass(this.widgetBaseClass + '-open');
this.list.attr('aria-hidden', true);
if ( this.options.style == "dropdown" ) {
this.newelement.removeClass('ui-corner-top').addClass('ui-corner-all');
}
if ( retainFocus ) {
this.newelement.focus();
}
this._trigger("close", event, this._uiHash());
}
},
change: function(event) {
this.element.trigger("change");
this._trigger("change", event, this._uiHash());
},
select: function(event) {
if (this._disabled(event.currentTarget)) { return false; }
this._trigger("select", event, this._uiHash());
},
_closeOthers: function(event) {
$('.' + this.widgetBaseClass + '.ui-state-active').not(this.newelement).each(function() {
$(this).data('selectelement').selectmenu('close', event);
});
$('.' + this.widgetBaseClass + '.ui-state-hover').trigger('mouseout');
},
_toggle: function(event, retainFocus) {
if ( this.list.parent().is('.' + this.widgetBaseClass + '-open') ) {
this.close(event, retainFocus);
} else {
this.open(event);
}
},
_formatText: function(text) {
return (this.options.format ? this.options.format(text) : text);
},
_selectedIndex: function() {
return this.element[0].selectedIndex;
},
_selectedOptionLi: function() {
return this._optionLis.eq(this._selectedIndex());
},
_focusedOptionLi: function() {
return this.list.find('.' + this.widgetBaseClass + '-item-focus');
},
_moveSelection: function(amt, recIndex) {
// do nothing if disabled
if (!this.options.disabled) {
var currIndex = parseInt(this._selectedOptionLi().data('index') || 0, 10);
var newIndex = currIndex + amt;
// do not loop when using up key
if (newIndex < 0) {
newIndex = 0;
}
if (newIndex > this._optionLis.size() - 1) {
newIndex = this._optionLis.size() - 1;
}
// Occurs when a full loop has been made
if (newIndex === recIndex) { return false; }
if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) {
// if option at newIndex is disabled, call _moveFocus, incrementing amt by one
(amt > 0) ? ++amt : --amt;
this._moveSelection(amt, newIndex);
} else {
return this._optionLis.eq(newIndex).trigger('mouseup');
}
}
},
_moveFocus: function(amt, recIndex) {
if (!isNaN(amt)) {
var currIndex = parseInt(this._focusedOptionLi().data('index') || 0, 10);
var newIndex = currIndex + amt;
} else {
var newIndex = parseInt(this._optionLis.filter(amt).data('index'), 10);
}
if (newIndex < 0) {
newIndex = 0;
}
if (newIndex > this._optionLis.size() - 1) {
newIndex = this._optionLis.size() - 1;
}
//Occurs when a full loop has been made
if (newIndex === recIndex) { return false; }
var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
this._focusedOptionLi().find('a:eq(0)').attr('id', '');
if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) {
// if option at newIndex is disabled, call _moveFocus, incrementing amt by one
(amt > 0) ? ++amt : --amt;
this._moveFocus(amt, newIndex);
} else {
this._optionLis.eq(newIndex).find('a:eq(0)').attr('id',activeID).focus();
}
this.list.attr('aria-activedescendant', activeID);
},
_scrollPage: function(direction) {
var numPerPage = Math.floor(this.list.outerHeight() / this.list.find('li:first').outerHeight());
numPerPage = (direction == 'up' ? -numPerPage : numPerPage);
this._moveFocus(numPerPage);
},
_setOption: function(key, value) {
this.options[key] = value;
// set
if (key == 'disabled') {
this.close();
this.element
.add(this.newelement)
.add(this.list)[value ? 'addClass' : 'removeClass'](
this.widgetBaseClass + '-disabled' + ' ' +
this.namespace + '-state-disabled')
.attr("aria-disabled", value);
}
},
disable: function(index, type){
// if options is not provided, call the parents disable function
if ( typeof( index ) == 'undefined' ) {
this._setOption( 'disabled', true );
} else {
if ( type == "optgroup" ) {
this._disableOptgroup(index);
} else {
this._disableOption(index);
}
}
},
enable: function(index, type) {
// if options is not provided, call the parents enable function
if ( typeof( index ) == 'undefined' ) {
this._setOption('disabled', false);
} else {
if ( type == "optgroup" ) {
this._enableOptgroup(index);
} else {
this._enableOption(index);
}
}
},
_disabled: function(elem) {
return $(elem).hasClass( this.namespace + '-state-disabled' );
},
_disableOption: function(index) {
var optionElem = this._optionLis.eq(index);
if (optionElem) {
optionElem.addClass(this.namespace + '-state-disabled')
.find("a").attr("aria-disabled", true);
this.element.find("option").eq(index).attr("disabled", "disabled");
}
},
_enableOption: function(index) {
var optionElem = this._optionLis.eq(index);
if (optionElem) {
optionElem.removeClass( this.namespace + '-state-disabled' )
.find("a").attr("aria-disabled", false);
this.element.find("option").eq(index).removeAttr("disabled");
}
},
_disableOptgroup: function(index) {
var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index );
if (optGroupElem) {
optGroupElem.addClass(this.namespace + '-state-disabled')
.attr("aria-disabled", true);
this.element.find("optgroup").eq(index).attr("disabled", "disabled");
}
},
_enableOptgroup: function(index) {
var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index );
if (optGroupElem) {
optGroupElem.removeClass(this.namespace + '-state-disabled')
.attr("aria-disabled", false);
this.element.find("optgroup").eq(index).removeAttr("disabled");
}
},
index: function(newValue) {
if (arguments.length) {
if (!this._disabled($(this._optionLis[newValue]))) {
this.element[0].selectedIndex = newValue;
this._refreshValue();
} else {
return false;
}
} else {
return this._selectedIndex();
}
},
value: function(newValue) {
if (arguments.length) {
this.element[0].value = newValue;
this._refreshValue();
} else {
return this.element[0].value;
}
},
_refreshValue: function() {
var activeClass = (this.options.style == "popup") ? " ui-state-active" : "";
var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
// deselect previous
this.list
.find('.' + this.widgetBaseClass + '-item-selected')
.removeClass(this.widgetBaseClass + "-item-selected" + activeClass)
.find('a')
.attr('aria-selected', 'false')
.attr('id', '');
// select new
this._selectedOptionLi()
.addClass(this.widgetBaseClass + "-item-selected" + activeClass)
.find('a')
.attr('aria-selected', 'true')
.attr('id', activeID);
// toggle any class brought in from option
var currentOptionClasses = (this.newelement.data('optionClasses') ? this.newelement.data('optionClasses') : "");
var newOptionClasses = (this._selectedOptionLi().data('optionClasses') ? this._selectedOptionLi().data('optionClasses') : "");
this.newelement
.removeClass(currentOptionClasses)
.data('optionClasses', newOptionClasses)
.addClass( newOptionClasses )
.find('.' + this.widgetBaseClass + '-status')
.html(
this._selectedOptionLi()
.find('a:eq(0)')
.html()
);
this.list.attr('aria-activedescendant', activeID);
},
_refreshPosition: function() {
var o = this.options;
// if its a native pop-up we need to calculate the position of the selected li
if ( o.style == "popup" && !o.positionOptions.offset ) {
var selected = this._selectedOptionLi();
var _offset = "0 -" + ( selected.outerHeight() + selected.offset().top - this.list.offset().top );
}
// update zIndex if jQuery UI is able to process
var zIndexElement = this.element.zIndex();
if ( zIndexElement ) {
this.listWrap.css( 'zIndex', zIndexElement );
}
this.listWrap.position({
// set options for position plugin
of: o.positionOptions.of || this.newelement,
my: o.positionOptions.my,
at: o.positionOptions.at,
offset: o.positionOptions.offset || _offset,
collision: o.positionOptions.collision || 'flip'
});
}
});
})(jQuery);
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
$(document).ready(function(){
$('#tree-slider td.tree-item-file-name a, #tree-breadcrumbs a').live("click", function() {
history.pushState({ path: this.path }, '', this.href)
})
$("#tree-slider tr.tree-item").live('click', function(e){
if(e.target.nodeName != "A") {
e.stopPropagation();
$(this).find("td.tree-item-file-name a").click();
return false;
}
});
$("#projects-list .project").live('click', function(e){
if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
location.href = $(this).attr("url");
e.stopPropagation();
return false;
}
});
$("#issues-table .issue").live('click', function(e){
if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
location.href = $(this).attr("url");
e.stopPropagation();
return false;
}
});
$(document).keypress(function(e) {
if( $(e.target).is(":input") ) return;
switch(e.which) {
case 115: focusSearch();
e.preventDefault();
}
});
});
function focusSearch() {
$("#search").focus();
}
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require_tree .
*/
// Place all the styles related to the Dashboard controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
@mixin round-borders-all($radius) {
border: 1px solid #eaeaea;
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
border-radius: $radius;
}
table.highlighttable
{
margin:0px;
padding:0px;
font-size:12px;
table-layout:fixed
}
td.code,
td.linenos{
padding:0;
margin:0;
vertical-align:top;
}
.highlight{
background:none;
padding:10px 0px 0px 0;
margin-left:10px;
}
.highlight pre{
}
.linenodiv pre {
white-space:pre-line;
}
td.linenos {
background:#ECECEC;
color:#777;
padding:10px 0px 0px 10px;
float:left;
width:45px;
border-right: 1px solid #ccc;
}
td.code .highlight {
overflow-x: scroll;
}
table.highlighttable pre{
padding:0;
margin:0;
font-family: 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;
}
.git-empty .highlight {
@include round-borders-all(4px);
background:#eee;
padding:5px;
//overflow-x:scroll;
pre{
padding:0;
line-height:2.0;
margin:0;
font-family: 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;}
}
.shadow{
-webkit-box-shadow:0 5px 15px #000;
-moz-box-shadow:0 5px 15px #000;
box-shadow:0 5px 15px #000;
}
.hll { background-color: #ffffff }
.c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #000000; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #303030 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc{font-weight:bold;} /* Keyword.Constant */
.highlight .kd{font-weight:bold;} /* Keyword.Declaration */
.highlight .kn{font-weight:bold;} /* Keyword.Namespace */
.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */
.highlight .kr{font-weight:bold;} /* Keyword.Reserved */
.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na{color:#008080;} /* Name.Attribute */
.highlight .nb{color:#0086B3;} /* Name.Builtin */
.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */
.highlight .no{color:#008080;} /* Name.Constant */
.highlight .ni{color:#800080;}
.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */
.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */
.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */
.highlight .nt{color:#000080;} /* Name.Tag */
.highlight .nv{color:#008080;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2{color:#d14;} /* Literal.String.Double */
.highlight .se{color:#d14;} /* Literal.String.Escape */
.highlight .sh{color:#d14;} /* Literal.String.Heredoc */
.highlight .si{color:#d14;} /* Literal.String.Interpol */
.highlight .sx{color:#d14;} /* Literal.String.Other */
.highlight .sr{color:#d14;} /* Literal.String.Regex */
.highlight .s1{color:#d14;} /* Literal.String.Single */
.highlight .ss{color:#d14;} /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb }
// Place all the styles related to the Issues controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
/* Selectmenu
----------------------------------*/
.ui-selectmenu { background:none; font-size:12px;display: block; display: inline-block; position: relative; height: 2.2em; vertical-align: middle; text-decoration: none; overflow: hidden; zoom: 1; }
.ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top: 50%; }
.ui-selectmenu-menu { padding:0; margin:0; position:absolute; top: 0; display: none; z-index: 1005;} /* z-index: 1005 to make selectmenu work with dialog */
.ui-selectmenu-menu ul { padding:0; margin:0; list-style:none; position: relative; overflow: auto; overflow-y: auto ; overflow-x: hidden; }
.ui-selectmenu-open { display: block; }
.ui-selectmenu.ui-widget { background:none; }
.ui-selectmenu-menu-popup { margin-top: -1px; }
.ui-selectmenu-menu-dropdown { }
.ui-selectmenu-menu li.ui-state-active { background:#F7FBFC; border:none; padding:1px 0;}
.ui-selectmenu-menu li { padding:0; margin:0; display: block; border-top: 1px dotted transparent; border-bottom: 1px dotted transparent; border-right-width: 0 !important; border-left-width: 0 !important; font-weight: normal !important; }
.ui-selectmenu-menu li a,.ui-selectmenu-status { line-height: 1.4em; display: block; padding: .405em 2.1em .405em 1em; outline:none; text-decoration:none; }
.ui-selectmenu-menu li.ui-state-disabled a, .ui-state-disabled { cursor: default; }
.ui-selectmenu-menu li.ui-selectmenu-hasIcon a,
.ui-selectmenu-hasIcon .ui-selectmenu-status { padding-left: 20px; position: relative; margin-left: 5px; }
.ui-selectmenu-menu li .ui-icon, .ui-selectmenu-status .ui-icon { position: absolute; top: 1em; margin-top: -8px; left: 0; }
.ui-selectmenu-status { line-height: 1.4em; }
.ui-selectmenu-open li.ui-selectmenu-item-focus { background: none repeat scroll 0 0 #FFF6BF; border:1px solid #eaeaea;}
.ui-selectmenu-open li.ui-selectmenu-item-selected { }
.ui-selectmenu-menu li span,.ui-selectmenu-status span { display:block; margin-bottom: .2em; }
.ui-selectmenu-menu li .ui-selectmenu-item-header { font-weight: bold; }
.ui-selectmenu-menu li .ui-selectmenu-item-content { }
.ui-selectmenu-menu li .ui-selectmenu-item-footer { opacity: .8; }
/* for optgroups */
.ui-selectmenu-menu .ui-selectmenu-group { font-size: 1em; }
.ui-selectmenu-menu .ui-selectmenu-group .ui-selectmenu-group-label { line-height: 1.4em; display:block; padding: .6em .5em 0; font-weight: bold; }
.ui-selectmenu-menu .ui-selectmenu-group ul { margin: 0; padding: 0; }
/* IE6 workaround (dotted transparent borders) */
* html .ui-selectmenu-menu li { border-color: pink; filter:chroma(color=pink); width:100%; }
* html .ui-selectmenu-menu li a { position: relative }
/* IE7 workaround (opacity disabled) */
*+html .ui-state-disabled, *+html .ui-state-disabled a { color: silver; }
// Place all the styles related to the Profile controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the Projects controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
@mixin round-borders-bottom($radius) {
border-top: 1px solid #eaeaea;
-moz-border-radius-bottomright: $radius;
-moz-border-radius-bottomleft: $radius;
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
-webkit-border-bottom-left-radius: $radius;
-webkit-border-bottom-right-radius: $radius;
}
@mixin round-borders-top($radius) {
border-top: 1px solid #eaeaea;
-moz-border-radius-topright: $radius;
-moz-border-radius-topleft: $radius;
border-top-right-radius: $radius;
border-top-left-radius: $radius;
-webkit-border-top-left-radius: $radius;
-webkit-border-top-right-radius: $radius;
}
@mixin round-borders-all($radius) {
border: 1px solid #eaeaea;
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
border-radius: $radius;
}
@mixin hover-color {
background: #fff !important;
background: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#FFF6BF)) !important;
background: -moz-linear-gradient(top,#fff,#FFF6BF) !important;
background: transparent 9 !important;
}
.diff_file {
border:1px solid #CCC;
margin-bottom:1em;
.diff_file_header {
padding:5px 5px;
border-bottom:1px solid #CCC;
background: #eee;
}
.diff_file_content {
overflow-x: scroll;
background:#fff;
color:#333;
font-size: 12px;
font-family: 'Courier New', 'andale mono','lucida console',monospace;
}
.diff_file_content_image {
background:#eee;
text-align:center;
img {
padding:100px;
max-width:300px;
}
}
}
#logo {
&:hover {
background:none;
}
}
.file_stats {
margin-bottom:10px;
@include round-borders-all(4px);
span {
border-top: 1px solid #eaeaea;
padding:5px 5px;
display:block;
&:first-child {
border-top:none;
}
img {
width:18px;
float:left;
margin-right: 6px;
}
}
}
.round-borders {
@include round-borders-all(4px);
padding: 4px 0px;
}
table.round-borders {
float:left;
}
.day-commits-table {
@include round-borders-all(4px);
padding: 4px 0px;
margin-bottom:10px;
display:block;
width:100%;
background: #E6F1F6;
.day-header {
padding:10px;
h3 {
margin:0px;
}
}
ul {
display:block;
list-style:none;
margin:0px;
padding:0px;
li.commit {
display:list-item;
padding:8px;
margin:0px;
background: #F7FBFC;
border-top: 1px solid #E2EAEE;
&:first-child {
border-top: 1px solid #E2EAEE;
}
&:nth-child(2n+1) {
background: white;
}
a.button {
width:85px;
padding:10px;
margin:0px;
float:right;
}
p {
margin-bottom: 3px;
font-size: 13px;
}
}
}
}
@mixin panel-color {
background: #111 !important;
background: -webkit-gradient(linear,left top,left bottom,from(#333),to(#111)) !important;
background: -moz-linear-gradient(top,#333,#111) !important;
background: transparent 9 !important;
}
#header-panel {
@include panel-color;
height:40px;
position:fixed;
z-index:999;
top:0px;
width:100%;
margin-bottom:10px;
overflow:hidden;
.button{
color:#bbb;
border:none;
margin:0px;
height:25px;
background:transparent;
padding:10px 20px 5px 20px;
&:hover{
color:white;
}
&.current {
border-bottom: 3px solid #EAEAEA !important;
padding: 10px 20px 0;
color: #eaeaea;
}
}
.search-holder {
float:left;
width:290px;
input {
@include round-borders-all(4px);
width:290px;
border-color:#888;
padding:5px;
background:#666;
color:#222;
&:focus {
background:#fff;
color:#000;
}
}
}
}
#content-container{
min-height:250px;
background: #fff;
@include round-borders-bottom(8px);
borders:2px solid #eaeaea;
border-top: none;
padding:20px;
}
body {
background: #eaeaea;
}
a {
color: #111;
}
.diff_file_content{
.old_line, .new_line {
background:#ECECEC;
color:#777;
width:15px;
float:left;
padding: 0px 10px;
border-right: 1px solid #ccc;
}
}
.view_file_content{
.old_line, .new_line {
background:#ECECEC;
color:#777;
width:15px;
float:left;
padding: 0px 10px;
border-right: 1px solid #ccc;
}
.old_line{
display:none;
}
}
.view_file {
border:1px solid #CCC;
margin-bottom:1em;
.view_file_header {
padding:5px 5px;
border-bottom:1px solid #CCC;
background: #eee;
}
.view_file_content {
background:#fff;
color:#514721;
font-size: 11px;
}
.view_file_content_image {
background:#eee;
text-align:center;
img {
padding:100px;
max-width:300px;
}
}
}
.back_small.button{
}
input.ssh_project_url {
padding:5px;
margin:0px;
float:right;
width:400px;
text-align:center;
}
.day-commits-table li.commit {
cursor:pointer;
&:hover {
@include hover-color;
}
}
/*
#FFF6BF
#FFD324
*/
#tree-slider tr.tree-item {
cursor:pointer;
&:hover {
@include hover-color;
td {
@include hover-color;
}
}
}
#projects-list .project {
height:50px;
}
#projects-list .project,
#issues-table .issue{
cursor:pointer;
&:hover {
@include hover-color;
td {
@include hover-color;
}
}
}
.clear {
clear: both;
}
.top_project_menu {
a {
border-right: 1px solid #FFFFFF;
box-shadow: -1px 0 #DDDDDD inset;
color: #666;
display: block;
font-size: 16px;
text-decoration: none;
line-height: 20px;
padding: 11px 26px 12px 24px;
text-shadow: 0 1px 0 #FFFFFF;
float:left;
&.current {
background-color: #FFFFFF;
color: #222222;
}
}
}
.top_bar {
margin-top:50px;
background-color: #F4F4F4;
@include round-borders-top(8px);
box-shadow: 0 1px #FFFFFF inset, 0 -1px #DDDDDD inset;
height: 43px;
overflow: hidden;
width:990px;
}
/** FORM INPUTS **/
.user_new,
.edit_user,
.new_project,
.edit_project {
input[type='text'],
input[type='email'],
input[type='password'],
textarea {
width:400px;
padding:8px;
font-size:14px;
@include round-borders-all(4px);
}
}
.input_button {
//@include round-borders-all(4px);
padding:8px;
font-size:14px;
cursor:pointer;
background-color: #F5F5F5;
border-color: #EEEEEE #DEDEDE #DEDEDE #EEEEEE;
border-right: 1px solid #DEDEDE;
border-style: solid;
border-width: 1px;
}
tbody tr:nth-child(2n) td, tbody tr.even td {
background: none repeat scroll 0 0 #F7FBFC;
border-top: 1px solid #E2EAEE;
border-bottom: 1px solid #E2EAEE;
}
.top_menu_count {
background: none repeat scroll 0 0 #FFF6BF;
border-color: #FFD324;
color: #514721;
border: 1px solid #DDDDDD;
padding: 2px;
font-size:12px;
position:relative;
top:-14px;
left:10px;
border-top:none;
}
#logo {
color: #EAEAEA;
font-family: monospace;
font-size: 26px;
padding: 4px;
text-decoration: none;
text-shadow: #555 1px 1px;
}
/** FALSH **/
#flash_container {
height:40px;
position:fixed;
z-index:1009;
top:0px;
width:100%;
margin-bottom:10px;
overflow:hidden;
background:white;
cursor:pointer;
border-bottom:1px solid #777;
h4 {
color:#444;
font-size:22px;
padding-top:5px;
}
}
/** Buttons **/
.lbutton,
.lite_button {
display:block;
float:left;
margin: 0px 5px;
padding:5px 10px;
font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;
border:1px solid #D3D3D3;
background:white;
font-size:12px;
line-height:130%;
text-decoration:none;
font-weight:bold;
color:#565656;
cursor:pointer;
&:hover {
border:1px solid #C2E1EF;
color: #0099FF;
}
&.hm {
margin: 0px 0px;
}
&.vm {
margin: 5px 0px;
}
}
/** Notes **/
#notes-list {
display:block;
list-style:none;
margin:0px;
padding:0px;
li {
display:list-item;
padding:8px;
margin:0px;
background: #F7FBFC;
border-top: 1px solid #E2EAEE;
&:first-child {
border-top: none;
}
&:nth-child(2n+1) {
background: white;
}
p {
margin-bottom: 3px;
font-size: 12px;
}
}
}
.notes_count {
background: none repeat scroll 0 0 #FFF6BF;
border-color: #FFD324;
color: #514721;
border: 2px solid #DDDDDD;
margin-bottom: 1em;
margin-top: 3px;
padding: 2px 5px;
position: relative;
right: 6px;
top: 6px;
}
.note_author {
float:left;
width:60px;
}
.note_content {
float:left;
width:750px;
}
.issue_notes {
.note_content {
float:left;
width:400px;
}
}
class Admin::MailerController < ApplicationController
before_filter :authenticate_user!
before_filter :authenticate_admin!
def preview
end
def preview_note
@note = Note.first
@user = @note.author
@project = @note.project
case params[:type]
when "Commit" then
@commit = @project.commit
render :file => 'notify/note_commit_email.html.haml', :layout => 'notify'
when "Issue" then
@issue = Issue.first
render :file => 'notify/note_issue_email.html.haml', :layout => 'notify'
else
render :file => 'notify/note_wall_email.html.haml', :layout => 'notify'
end
rescue
render :text => "Preview not avaialble"
end
def preview_user_new
@user = User.first
@password = "DHasJKDHAS!"
render :file => 'notify/new_user_email.html.haml', :layout => 'notify'
rescue
render :text => "Preview not avaialble"
end
def preview_issue_new
@issue = Issue.first
@user = @issue.assignee
@project = @issue.project
render :file => 'notify/new_issue_email.html.haml', :layout => 'notify'
rescue
render :text => "Preview not avaialble"
end
end
class Admin::ProjectsController < ApplicationController
before_filter :authenticate_user!
before_filter :authenticate_admin!
def index
@admin_projects = Project.page(params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render json: @admin_projects }
end
end
def show
@admin_project = Project.find_by_code(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @admin_project }
end
end
def new
@admin_project = Project.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @admin_project }
end
end
def edit
@admin_project = Project.find_by_code(params[:id])
end
def create
@admin_project = Project.new(params[:project])
respond_to do |format|
if @admin_project.save
format.html { redirect_to [:admin, @admin_project], notice: 'Project was successfully created.' }
format.json { render json: @admin_project, status: :created, location: @admin_project }
else
format.html { render action: "new" }
format.json { render json: @admin_project.errors, status: :unprocessable_entity }
end
end
end
def update
@admin_project = Project.find_by_code(params[:id])
respond_to do |format|
if @admin_project.update_attributes(params[:project])
format.html { redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @admin_project.errors, status: :unprocessable_entity }
end
end
end
def destroy
@admin_project = Project.find_by_code(params[:id])
@admin_project.destroy
respond_to do |format|
format.html { redirect_to admin_projects_url }
format.json { head :ok }
end
end
end
class Admin::TeamMembersController < ApplicationController
before_filter :authenticate_user!
before_filter :authenticate_admin!
def index
@admin_team_members = UsersProject.page(params[:page]).per(100).order("project_id DESC")
respond_to do |format|
format.html # index.html.erb
format.json { render json: @admin_team_members }
end
end
def show
@admin_team_member = UsersProject.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @admin_team_member }
end
end
def new
@admin_team_member = UsersProject.new(params[:team_member])
respond_to do |format|
format.html # new.html.erb
format.json { render json: @admin_team_member }
end
end
def edit
@admin_team_member = UsersProject.find(params[:id])
end
def create
@admin_team_member = UsersProject.new(params[:team_member])
@admin_team_member.project_id = params[:team_member][:project_id]
respond_to do |format|
if @admin_team_member.save
format.html { redirect_to admin_team_member_path(@admin_team_member), notice: 'UsersProject was successfully created.' }
format.json { render json: @admin_team_member, status: :created, location: @team_member }
else
format.html { render action: "new" }
format.json { render json: @admin_team_member.errors, status: :unprocessable_entity }
end
end
end
def update
@admin_team_member = UsersProject.find(params[:id])
@admin_team_member.project_id = params[:team_member][:project_id]
respond_to do |format|
if @admin_team_member.update_attributes(params[:team_member])
format.html { redirect_to admin_team_member_path(@admin_team_member), notice: 'UsersProject was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @admin_team_member.errors, status: :unprocessable_entity }
end
end
end
def destroy
@admin_team_member = UsersProject.find(params[:id])
@admin_team_member.destroy
respond_to do |format|
format.html { redirect_to admin_team_members_url }
format.json { head :ok }
end
end
end
class Admin::UsersController < ApplicationController
before_filter :authenticate_user!
before_filter :authenticate_admin!
def index
@admin_users = User.page(params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render json: @admin_users }
end
end
def show
@admin_user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @admin_user }
end
end
def new
@admin_user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @admin_user }
end
end
def edit
@admin_user = User.find(params[:id])
end
def create
admin = params[:user].delete("admin")
@admin_user = User.new(params[:user])
@admin_user.admin = (admin && admin.to_i > 0)
respond_to do |format|
if @admin_user.save
Notify.new_user_email(@admin_user, params[:user][:password]).deliver
format.html { redirect_to [:admin, @admin_user], notice: 'User was successfully created.' }
format.json { render json: @admin_user, status: :created, location: @admin_user }
else
format.html { render action: "new" }
format.json { render json: @admin_user.errors, status: :unprocessable_entity }
end
end
end
def update
admin = params[:user].delete("admin")
if params[:user][:password].empty?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
@admin_user = User.find(params[:id])
@admin_user.admin = (admin && admin.to_i > 0)
respond_to do |format|
if @admin_user.update_attributes(params[:user])
format.html { redirect_to [:admin, @admin_user], notice: 'User was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @admin_user.errors, status: :unprocessable_entity }
end
end
end
def destroy
@admin_user = User.find(params[:id])
@admin_user.destroy
respond_to do |format|
format.html { redirect_to admin_users_url }
format.json { head :ok }
end
end
end
class ApplicationController < ActionController::Base
before_filter :authenticate_user!
protect_from_forgery
helper_method :abilities, :can?
protected
def abilities
@abilities ||= Six.new
end
def can?(object, action, subject)
abilities.allowed?(object, action, subject)
end
def project
@project ||= Project.find_by_code(params[:project_id])
end
def add_project_abilities
abilities << Ability
end
def authenticate_admin!
return redirect_to(new_user_session_path) unless current_user.is_admin?
end
def authorize_project!(action)
return redirect_to(new_user_session_path) unless can?(current_user, action, project)
end
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /^authorize_(.*)!$/
authorize_project!($1.to_sym)
else
super
end
end
end
require "base64"
class CommitsController < ApplicationController
before_filter :project
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
def index
@repo = project.repo
@branch = if !params[:branch].blank?
params[:branch]
elsif !params[:tag].blank?
params[:tag]
else
"master"
end
if params[:path]
@commits = @repo.log(@branch, params[:path], :max_count => params[:limit] || 100, :skip => params[:offset] || 0)
else
@commits = @repo.commits(@branch, params[:limit] || 100, params[:offset] || 0)
end
respond_to do |format|
format.html # index.html.erb
format.js
format.json { render json: @commits }
end
end
def show
@commit = project.repo.commits(params[:id]).first
@notes = project.notes.where(:noteable_id => @commit.id, :noteable_type => "Commit")
@note = @project.notes.new(:noteable_id => @commit.id, :noteable_type => "Commit")
respond_to do |format|
format.html # show.html.erb
format.js
format.json { render json: @commit }
end
end
end
class DashboardController < ApplicationController
end
class IssuesController < ApplicationController
before_filter :authenticate_user!
before_filter :project
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_issue!
before_filter :authorize_write_issue!, :only => [:new, :create, :close, :edit, :update]
before_filter :authorize_admin_issue!, :only => [:destroy]
respond_to :js
def index
@issues = case params[:f].to_i
when 1 then @project.issues.all
when 2 then @project.issues.closed
when 3 then @project.issues.opened.assigned(current_user)
else @project.issues.opened
end
respond_to do |format|
format.html # index.html.erb
format.js
end
end
def new
@issue = @project.issues.new
respond_with(@issue)
end
def edit
@issue = @project.issues.find(params[:id])
respond_with(@issue)
end
def show
@issue = @project.issues.find(params[:id])
@notes = @issue.notes
@note = @project.notes.new(:noteable => @issue)
end
def create
@issue = @project.issues.new(params[:issue])
@issue.author = current_user
if @issue.save
Notify.new_issue_email(@issue).deliver
end
respond_with(@issue)
end
def update
@issue = @project.issues.find(params[:id])
@issue.update_attributes(params[:issue])
respond_to do |format|
format.js
format.html { redirect_to [@project, @issue]}
end
end
def destroy
@issue = @project.issues.find(params[:id])
@issue.destroy
respond_to do |format|
format.js { render :nothing => true }
end
end
end
class KeysController < ApplicationController
respond_to :js
def index
@keys = current_user.keys.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @keys }
end
end
def new
@key = current_user.keys.new
respond_with(@key)
end
def create
@key = current_user.keys.new(params[:key])
@key.save
respond_with(@key)
end
# DELETE /keys/1
# DELETE /keys/1.json
def destroy
@key = current_user.keys.find(params[:id])
@key.destroy
respond_to do |format|
format.html { redirect_to keys_url }
format.js { render :nothing => true }
format.json { head :ok }
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment