/*
Behaviour
Class is inspired from Ben Nolan's behaviour.js script
(http://bennolan.com/behaviour/) but uses Prototype's
$$() and Element.getElementsBySelector() functions since
they support more CSS syntax and are already loaded with
prototype.
*/
var Behaviour = {
rules : $H({}),
register : function(new_rules) {
Behaviour.rules = Behaviour.rules.merge(new_rules);
},
apply : function(el) {
//console.log('START BEHAVIOUR APPLICATION');
Behaviour.rules.each(function(pair) {
var rule = pair.key;
//var start_time = new Date().valueOf();
//console.log('applying: ' + rule);
var behaviour = pair.value;
// if we have an element, use Element.select()
// else use $$() to find the targets
var targets;
if( el ) {
targets = $(el).select(rule);
} else {
targets = $$(rule);
}
// if we got anything back then apply the behaviour
//console.log(' found ' + targets.size() + ' elements');
if( targets.size() > 0 ) {
targets.each(function(target) { behaviour(target) });
}
//var end_time = new Date().valueOf();
//console.log(' took: ' + (end_time - start_time) + 'ms');
});
}
};
var Smolder = {};
Smolder.load = function(target, json) {
if(! json) json = {};
// update the navigation if we need to
if( json.update_nav ) Smolder.update_nav();
// apply our registered behaviours
Behaviour.apply(target);
// run any code from Smolder.onload()
var size = Smolder.onload_code.length;
for(var i=0; i< size; i++) {
var code = Smolder.onload_code.pop();
if( code ) code();
}
// show any messages we got
Smolder.show_messages(json);
};
/*
Smolder.onload()
Add some code that will get executed after the DOM is loaded
(but without having to wait on images, etc to load).
Multiple calls will not overwrite previous calls and all code
given will be executed in the order give.
*/
Smolder.onload_code = [];
Smolder.onload = function(code) {
Smolder.onload_code.push(code);
};
/*
Smolder.Cookie.get(name)
Returns the value of a specific cookie.
*/
Smolder.Cookie = {};
Smolder.Cookie.get = function(name) {
var value = null;
var cookie = document.cookie;
var start, end;
if ( cookie.length > 0 ) {
start = cookie.indexOf( name + '=' );
// if the cookie exists
if ( start != -1 ) {
start += name.length + 1; // need to account for the '='
// set index of beginning of value
end = cookie.indexOf( ';', start );
if ( end == -1 ) end = cookie.length;
value = unescape( cookie.substring( start, end ) );
}
}
return value;
};
/*
Smolder.Cookie.set(name, value)
Sets a cookie to a particular value.
*/
Smolder.Cookie.set = function(name, value) {
document.cookie = name + '=' + value;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.update_nav = function(){
Smolder.Ajax.update({
url : '/app/public/nav',
target : 'nav'
});
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: Smolder.Ajax.request
// takes the following named args
// url : the full url of the request (required)
// parmas : an object of query params to send along
// indicator : the id of the image to use as an indicator (optional defaults to 'indicator')
// onComplete: a call back function to be executed after the normal processing (optional)
// Receives as arguments, the same args passed into Smolder.Ajax.request
//
// Smolder.Ajax.request({
// url : '/app/some_mod/something',
// params : { foo: 1, bar: 2 },
// indicator : 'add_indicator',
// onComplete : function(args) {
// // do something
// }
// });
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.Ajax = {};
Smolder.Ajax.request = function(args) {
var url = args.url;
var params = args.params || {};
var indicator = args.indicator;
var on_complete = args.onComplete || Prototype.emptyFunction;;
var on_failure = args.onFailure || Prototype.emptyFunction;;
var on_exception = args.onException || Prototype.emptyFunction;;
// tell the user that we're doing something
Smolder.show_indicator(indicator);
// add the ajax=1 flag to the existing query params
params.ajax = 1;
new Ajax.Request(
url,
{
parameters : params,
asynchronous: true,
evalScripts : true,
onComplete : function(request, json) {
if(! json ) json = {};
Smolder.show_messages(json);
// hide the indicator
Smolder.hide_indicator(indicator);
// do whatever else the caller wants
args.request = request;
args.json = json || {};
on_complete(args);
},
onException: function(request, exception) {
on_exception();
alert("ERROR FROM AJAX REQUEST:\n" + exception);
},
onFailure: function(request) {
on_failure();
Smolder.show_error();
}
}
);
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: Smolder.Ajax.update
// takes the following named args
// url : the full url of the request (required)
// parmas : an object of query params to send along
// target : the id of the element receiving the contents (optional defaults to 'content')
// indicator : the id of the image to use as an indicator (optional defaults to 'indicator')
// onComplete: a call back function to be executed after the normal processing (optional)
// Receives as arguments, the same args passed into Smolder.Ajax.update
//
// Smolder.Ajax.update({
// url : '/app/some_mod/something',
// params : { foo: 1, bar: 2 },
// target : 'div_id',
// indicator : 'add_indicator',
// onComplete : function(args) {
// // do something
// }
// });
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.Ajax.update = function(args) {
var url = args.url;
var params = args.params || {};
var target = args.target;
var indicator = args.indicator;
var on_complete = args.onComplete || Prototype.emptyFunction;
var on_failure = args.onFailure || Prototype.emptyFunction;
var on_exception = args.onFailure || Prototype.emptyFunction;
// tell the user that we're doing something
Smolder.show_indicator(indicator);
// add the ajax=1 flag to the existing query params
params.ajax = 1;
// the default target
if( target == null || target == '' )
target = 'content';
new Ajax.Updater(
{ success : target },
url,
{
parameters : params,
asynchronous: true,
evalScripts : true,
onComplete : function(request, json) {
Smolder.load(target, json);
// hide the indicator
Smolder.hide_indicator(indicator);
// do whatever else the caller wants
args.request = request;
args.json = json || {};
on_complete(args);
},
onException: function(request, exception) {
on_exception();
alert("ERROR FROM AJAX REQUEST:\n" + exception);
},
onFailure: function(request) {
on_failure();
Smolder.show_error();
}
}
);
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: Smolder.Ajax.form_update
// takes the following named args
// form : the form object (required)
//
// All other arguments are passed to the underlying Smolder.Ajax.update() call
//
// Smolder.Ajax.form_update({
// form : formObj,
// target : 'div_id'
// });
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.Ajax.form_update = function(args) {
var form = args.form;
args.url = form.action;
args.params = Form.serialize(form, true);
if(! args.onComplete ) args.onComplete = Prototype.emptyFunction;;
// disable all of the inputs of this form that
// aren't already and remember which ones we disabled
var form_disabled_inputs = Smolder.disable_form(form);
var oldOnComplete = args.onComplete;
var reset_things = function() {
// reset which forms are open
Smolder.PopupForm.shown_popup_id = '';
// if we have a form, enable all of the inputs that we disabled
Smolder.reenable_form(form, form_disabled_inputs);
};
args.onComplete = function(request, json) {
oldOnComplete(request, json);
reset_things();
};
args.onFailure = reset_things;
args.onException = reset_things;
// now submit this normally
Smolder.Ajax.update(args);
};
Smolder.disable_form = function(form) {
// disable all of the inputs of this form that
// aren't already and remember which ones we disabled
var disabled = $H();
$A(form.elements).each(
function(input, i) {
if( !input.disabled ) {
disabled.set(input.name, true);
input.disabled = true;
}
}
);
return disabled.keys();
};
Smolder.reenable_form = function(form, inputs) {
// if we have a form, enable all of the inputs
// that we disabled
if( form && inputs.length > 0 ) {
$A(inputs).each(
function(name, i) {
if( name && form.elements[name] ) {
$A(form.elements[name]).each(function(input) {
input.disabled = false;
});
}
}
);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.show_error = function() {
new Notify.Alert(
$('ajax_error_container').innerHTML,
{
messagecolor : '#FFFFFF',
autoHide : 'false'
}
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.PopupForm = {
shown_popup_id: '',
toggle: function(popup_id) {
// first turn off any other forms showing of this type
var old_popup_id = Smolder.PopupForm.shown_popup_id;
if( old_popup_id != '' && $(old_popup_id) != null ) {
Smolder.PopupForm.hide();
}
if( old_popup_id == popup_id ) {
Smolder.PopupForm.shown_popup_id = '';
} else {
new Effect.SlideDown(popup_id, { duration: .1 });
Smolder.PopupForm.shown_popup_id = popup_id;
}
return false;
},
show: function(popup_id) {
if( Smolder.PopupForm.shown_popup_id != popup_id ) {
Smolder.PopupForm.toggle(popup_id);
}
},
hide: function() {
new Effect.SlideUp( Smolder.PopupForm.shown_popup_id, { duration: .1 } );
Smolder.PopupForm.shown_popup_id = '';
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.changeSmokeGraph = function(form) {
var type = form.elements['type'].value;
var url = form.action + "/" + escape(type) + "?change=1&";
// add each field that we want to see to the URL
var fields = new Array('total', 'pass', 'fail', 'skip', 'todo', 'duration');
fields.each(
function(value, index) {
if( form.elements[value].checked ) {
url = url + escape(value) + '=1&';
}
}
);
// add any extra args that we might want to search by
var extraArgs = ['start', 'stop', 'tag', 'platform', 'architecture'];
for(var i = 0; i < extraArgs.length; i++) {
var arg = extraArgs[i];
if( form.elements[arg] != null && form.elements[arg].value != '') {
url = url + arg + '=' + escape(form.elements[arg].value) + '&';
}
}
$('graph_image').src = url;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.toggleSmokeValid = function(form) {
// TODO - replace with one regex
var trigger = form.id.replace(/_trigger$/, '');
var smokeId = trigger.replace(/^(in)?valid_form_/, '');
var divId = "smoke_test_" + smokeId;
// we are currently not showing any other forms
Smolder.PopupForm.shown_form_id = '';
Smolder.Ajax.form_update({
form : form,
target : divId,
indicator : trigger + "_indicator"
});
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.newSmokeReportWindow = function(url) {
window.open(
url,
'report_details',
'resizeable=yes,width=850,height=600,scrollbars=yes'
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.makeFormAjaxable = function(element) {
// find which element it targets
var target;
var matches = element.className.match(/(^|\s)for_([^\s]+)($|\s)/);
if( matches != null )
target = matches[2];
// find which indicator it uses
var indicatorId;
matches = element.className.match(/(^|\s)show_([^\s]+)($|\s)/);
if( matches != null )
indicatorId = matches[2];
element.onsubmit = function(event) {
Smolder.Ajax.form_update({
form : element,
target : target,
indicator : indicatorId
});
return false;
};
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.makeLinkAjaxable = function(element) {
var target;
// find which target it targets
var matches = element.className.match(/(^|\s)for_([^\s]+)($|\s)/);
if( matches != null )
target = matches[2];
// find which indicator it uses
var indicatorId;
matches = element.className.match(/(^|\s)show_([^\s]+)($|\s)/);
if( matches != null )
indicatorId = matches[2];
element.onclick = function(event) {
Smolder.Ajax.update({
url : element.href,
target : target,
indicator : indicatorId
});
return false;
};
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.show_indicator = function(indicator) {
indicator = $(indicator);
if( indicator ) Element.show(indicator);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.hide_indicator = function(indicator) {
indicator = $(indicator);
if( indicator ) Element.hide(indicator);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.highlight = function(el) {
new Effect.Highlight(
el,
{
'startcolor' : '#ffffff',
'endcolor' : '#ffff99',
'restorecolor': '#ffff99'
}
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.unHighlight = function(el) {
new Effect.Highlight(
el,
{
'startcolor' : '#ffff99',
'endcolor' : '#ffffff',
'restorecolor': '#ffffff'
}
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.flash = function(el) {
new Effect.Highlight(
el,
{
'startcolor' : '#ffff99',
'endcolor' : '#ffffff',
'restorecolor': '#ffffff'
}
);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.show_messages = function(json) {
if( json ) {
var msgs = json.messages || [];
msgs.each( function(msg) { Smolder.show_message(msg.type, msg.msg) } );
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.__message_count = 0;
Smolder.message_template = new Template('<div class="#{type}" id="message_#{count}">#{text}</div>');
Smolder.show_message = function(type, text) {
Smolder.__message_count++;
// insert it at the top of the messages
$('message_container').insert({
top: Smolder.message_template.evaluate({
type : type,
count : Smolder.__message_count,
text : text
})
});
// fade it out after 10 secs, or onclick
var el = $('message_' + Smolder.__message_count);
var fade = function() { new Effect.Fade(el, { duration: .4 } ); };
el.onclick = fade;
setTimeout(fade, 7000);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Smolder.setup_tooltip = function(trigger, target) {
trigger.onclick = function() {
new Effect.toggle(target, 'appear', { duration: .4 });
};
}
// CRUD abstraction for Smolder
Smolder.__known_CRUDS = { };
Smolder.CRUD = Class.create();
/* Class methods */
Smolder.CRUD.find = function(id) { return Smolder.__known_CRUDS[id] };
Smolder.CRUD.remember = function(crud) { Smolder.__known_CRUDS[crud.div.id] = crud; };
Smolder.CRUD.forget = function(crud) { Smolder.__known_CRUDS[crud.div.id] = false; };
/* Object methods */
Object.extend(Smolder.CRUD.prototype, {
initialize: function(id, url) {
this.div = $(id);
this.url = url;
this.list_url = url + '/list';
// initialize these if we don't already have a crud
this.add_shown = false;
// find the containers, triggers and indicator that won't change
this.list_container = this.div.select('.list_container')[0];
this.add_container = this.div.select('.add_container')[0];
this.indicator = this.div.select('.indicator')[0].id;
this.add_trigger = this.div.select('.add_trigger')[0];
// add the handlers for the triggers
this.add_trigger.onclick = function() {
this.toggle_add();
// prevent submission of the link
return false;
}.bindAsEventListener(this);
// find our triggers that might change (edit and delete)
this.refresh();
// the fact that we've created this CRUD
Smolder.CRUD.remember(this);
},
refresh: function() {
this.edit_triggers = $(this.list_container).select('.edit_trigger');
this.delete_triggers = $(this.list_container).select('.delete_trigger');
this.edit_triggers.each(
function(trigger) {
trigger.onclick = function() {
this.show_edit(trigger);
// prevent submission of the link
return false;
}.bindAsEventListener(this);
}.bindAsEventListener(this)
);
this.delete_triggers.each(
function(trigger) {
trigger.onclick = function() {
this.show_delete(trigger);
// prevent submission of the link
return false;
}.bindAsEventListener(this);
}.bindAsEventListener(this)
);
},
toggle_add: function() {
if( this.add_shown ) {
this.hide_add();
} else {
this.show_add();
}
},
hide_add: function() {
new Effect.SlideUp(this.add_container);
this.add_shown = false;
},
show_add: function() {
Smolder.Ajax.update({
url : this.add_trigger.href,
target : this.add_container.id,
indicator : this.indicator,
onComplete : function(args) {
if( !this.add_shown ) {
new Effect.SlideDown(this.add_container)
}
this.add_shown = true;
// make sure we submit the add changes correctly
this._handle_form_submit('add_form');
}.bindAsEventListener(this)
});
},
_handle_form_submit: function(name) {
var form = $(this.add_container).select('.' + name)[0];
if( form ) {
form.onsubmit = function() {
this.submit_change(form);
return false;
}.bindAsEventListener(this);
}
},
show_edit: function(trigger) {
var matches = trigger.className.match(/(^|\s)for_item_(\d+)($|\s)/);
var itemId = matches[2];
if( itemId == null )
return;
Smolder.Ajax.update({
url : trigger.href,
target : this.add_container.id,
indicator : this.indicator,
onComplete : function() {
if( !this.add_shown ) {
Effect.SlideDown(this.add_container);
}
this.add_shown = true;
// setup the 'cancel' button
var cancel = $(this.add_container).select('.edit_cancel')[0];
cancel.onclick = function() { this.hide_add(); }.bindAsEventListener(this);
// make sure we submit the add changes correctly
this._handle_form_submit('edit_form');
}.bindAsEventListener(this)
});
},
show_delete: function(trigger) {
var matches = trigger.className.match(/(^|\s)for_item_(\d+)($|\s)/);
var itemId = matches[2];
// set the onsubmit handler for the form in this popup
var form = $('delete_form_' + itemId);
form.onsubmit = function() {
Smolder.Ajax.update({
url : form.action,
target : this.list_container_id,
indicator : 'delete_indicator_' + itemId
});
return false;
}.bindAsEventListener(this);
// show the popup form
var popup = 'delete_' + itemId;
Smolder.PopupForm.toggle(popup);
},
submit_change: function(form) {
// find the add_inidicator
var indicator = $(this.add_container).select('.add_indicator')[0].id;
Smolder.Ajax.form_update({
form : form,
target : this.add_container.id,
indicator : indicator,
onComplete : function(args) {
if(! args.json ) args.json = {};
// if the submission changed the list
if( args.json.list_changed ) {
this.add_shown = false;
Element.hide(this.add_container);
this.update_list();
}
// since the add/edit forms may exist still
// (ie, their submission was incorrect so it reappears with error msgs)
// we need to make sure they're submitted correctly the 2nd time
this._handle_form_submit('add_form');
this._handle_form_submit('edit_form');
}.bindAsEventListener(this)
});
},
update_list: function () {
Smolder.Ajax.update({
url : this.list_url,
indicator : this.indicator,
target : this.list_container_id
});
}
});
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// These are our JS behaviors that are applied externally to HTML elements just like CSS
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
var myrules = {
'a.calendar_trigger' : function(element) {
// now find the id's of the calendar div and input based on the id of the trigger
// triggers are named $inputId_calendar_trigger, and calendar divs are named
// $inputId_calendar
var inputId = element.id.replace(/_calendar_trigger/, '');
var input = $(inputId);
Calendar.setup({
inputField : input.name,
ifFormat : "%m/%d/%Y",
button : element.id,
weekNumbers : false,
showOthers : true,
align : 'CL',
cache : true
});
},
'a.smoke_reports_nav' : function(element) {
// set the limit and then do an ajax request for the form
element.onclick = function() {
var offset = 0;
var matches = element.className.match(/(^|\s)offset_([^\s]+)($|\s)/);
if( matches != null )
offset = matches[2];
$('smoke_reports').elements['offset'].value = offset;
Smolder.Ajax.form_update({
form : $('smoke_reports'),
indicator : 'paging_indicator'
});
return false;
};
},
'form.change_smoke_graph' : function(element) {
element.onsubmit = function() {
Smolder.changeSmokeGraph(element);
return false;
}
},
'a.popup_form' : function(element) {
var popupId = element.id.replace(/_trigger$/, '');
element.onclick = function() {
Smolder.PopupForm.toggle(popupId);
return false;
};
},
'input.cancel_popup' : function(element) {
element.onclick = function() {
Smolder.PopupForm.hide();
};
},
'form.toggle_smoke_valid' : function(element) {
element.onsubmit = function() {
Smolder.toggleSmokeValid(element);
return false;
}
},
'#platform_auto_complete' : function(element) {
new Ajax.Autocompleter(
'platform',
'platform_auto_complete',
'/app/projects/platform_options'
);
},
'#architecture_auto_complete' : function(element) {
new Ajax.Autocompleter(
'architecture',
'architecture_auto_complete',
'/app/projects/architecture_options'
);
},
'input.auto_submit' : function(element) {
element.onchange = function(event) {
element.form.onsubmit();
return false;
}
},
'select.auto_submit' : function(element) {
element.onchange = function(event) {
element.form.onsubmit();
return false;
}
},
// for ajaxable forms and anchors the taget div for updating is determined
// as follows:
// Specify a the target div's id by adding a 'for_$id' class to the elements
// class list:
// <a class="ajaxable for_some_div" ... >
// This will make the target a div named "some_div"
// If no target is specified, then it will default to "content"
'a.ajaxable' : function(element) {
Smolder.makeLinkAjaxable(element);
},
'form.ajaxable' : function(element) {
Smolder.makeFormAjaxable(element);
},
'div.crud' : function(element) {
var matches = element.className.match(/(^|\s)for_(\w+)($|\s)/);
var url = "/app/" + matches[2];
new Smolder.CRUD(element.id, url);
},
'form.resetpw_form': function(element) {
Smolder.makeFormAjaxable(element);
// extend the onsubmit handler to turn off the popup
var popupId = element.id.replace(/_form$/, '');
var oldOnSubmit = element.onsubmit;
element.onsubmit = function() {
oldOnSubmit();
Smolder.PopupForm.toggle(popupId);
return false;
};
},
// on the preferences form, the project selector should update
// the preferences form with the selected projects preferences
// from the server
'#project_preference_selector': function(element) {
var form = element.form;
// if we start off looking at the default options
if( element.value == form.elements['default_pref_id'].value ) {
Element.show('dev_prefs_sync_button');
// if we want to show some info - Element.show('default_pref_info');
}
element.onchange = function() {
// if we are the default preference, then show the stuff
// that needs to be shown
if( element.value == form.elements['default_pref_id'].value ) {
Element.show('dev_prefs_sync_button');
// if we want to show some info - Element.show('default_pref_info');
} else {
Element.hide('dev_prefs_sync_button');
// if we want to show some info - Element.hide('default_pref_info');
}
// get the preference details from the server
Smolder.show_indicator('pref_indicator');
new Ajax.Request(
'/app/developer_prefs/get_pref_details',
{
parameters: Form.serialize(form),
asynchronous: true,
onComplete: function(response, json) {
// for every value in our JSON response, set that
// same element in the form
$A(['email_type', 'email_freq', 'email_limit']).each(
function(name) {
var elm = form.elements[name];
elm.value = json[name];
Smolder.flash(elm);
}
);
Smolder.hide_indicator('pref_indicator');
},
onFailure: function() { Smolder.show_error() }
}
);
};
},
// submit the preference form to sync the other preferences
'#dev_prefs_sync_button': function(element) {
element.onclick = function() {
var form = $('update_pref');
form.elements['sync'].value = 1;
Smolder.Ajax.form_update({
form : form,
target : 'developer_prefs'
});
};
},
// hightlight selected text, textarea and select inputs
'input.hl': function(element) {
element.onfocus = function() { Smolder.highlight(element); };
element.onblur = function() { Smolder.unHighlight(element); };
},
'textarea.hl': function(element) {
element.onfocus = function() { Smolder.highlight(element); };
element.onblur = function() { Smolder.unHighlight(element); };
},
'select.hl': function(element) {
element.onfocus = function() { Smolder.highlight(element); };
element.onblur = function() { Smolder.unHighlight(element); };
},
// setup tooltips
'.tooltip_trigger': function(element) {
var matches = element.className.match(/(^|\s)for_([^\s]+)($|\s)/);
if( matches ) {
var target = matches[2];
if( target ) {
Smolder.setup_tooltip(element, $(target));
Smolder.setup_tooltip($(target), $(target));
}
}
},
// TAP Matrix triggers for more test file details
'.tap a.details_trigger' : function(el) {
// get the id of the target div
var matches = el.id.match(/^for_(.*)$/);
var target = matches[1];
// get the id of the indicator image
matches = el.className.match(/(^|\s)show_(\S*)($|\s)/);
var indicator = matches[2];
el.onclick = function() {
if( Element.visible(target) ) {
$(target + '_tap_stream').hide();
Effect.BlindUp(target, { duration: .1 });
} else {
$(indicator).style.visibility = 'visible';
Smolder.Ajax.update({
url : el.href,
target : target,
indicator : 'none',
onComplete : function() {
window.setTimeout(function() { $(indicator).style.visibility = 'hidden'}, 200);
Effect.BlindDown(
target,
// reapply any dynamic bits
{
afterFinish : function() {
$(target + '_tap_stream').show();
$$('.tooltip_trigger').each(function(el) {
var diag = $(el).select('.tooltip')[0];
Smolder.setup_tooltip(el, diag);
});
},
duration : .1
}
);
}
});
}
return false;
};
},
'.tap div.diag': function(el) {
Smolder.setup_tooltip(el, el);
},
'#toggle_tests_trigger' : function(el) {
el.onchange = function() {
var count = 0;
$$('.tap tbody').each(function(row) {
if( el.checked ) {
if( row.hasClassName('passed') ) {
row.hide();
} else {
if( count % 2 == 1 ) {
if(row.hasClassName('even')) {
row.removeClassName('even');
row.addClassName('odd');
}
} else {
if(row.hasClassName('odd')) {
row.removeClassName('odd');
row.addClassName('even');
}
}
count++;
}
} else {
if( row.hasClassName('passed') ) {
row.show();
}
if( count % 2 == 1 ) {
if(row.hasClassName('even')) {
row.removeClassName('even');
row.addClassName('odd');
}
} else {
if(row.hasClassName('odd')) {
row.removeClassName('odd');
row.addClassName('even');
}
}
count++;
}
});
};
},
'.tap a.show_all' : function(el) {
Event.observe(el, 'click', function() {
// an anonymous function that we use as a callback after each
// panel is opened so that it opens the next one
var show_details = function(index) {
var el = $('testfile_details_' + index);
// apply the behaviours if we're the last one
if( ! el ) {
Behaviour.apply();
return;
}
// we only need to fetch it if we're not already visible
if( Element.visible(el) ) {
show_details(++index);
} else {
matches = el.id.match(/^testfile_details_(\d+)$/);
var index = matches[1];
var indicator = $('indicator_' + index);
var div = $('testfile_details_' + index);
indicator.style.visibility = 'visible';
Smolder.Ajax.update({
url : $('for_testfile_details_' + index).href,
target : div,
indicator : 'none',
onComplete : function() {
Element.show(div);
indicator.style.visibility = 'hidden';
show_details(++index);
}
});
}
};
show_details(0);
});
}
};
Behaviour.register(myrules);