/*
Script: moostick.js
Moostick: A flexible animated news headlines ticker
Copyright:
copyright (c) 2007 Stephane Daury:
License:
GNU Public License:
Version Information:
- Version: start
- Revision: $Id$
Requirements:
- Cascading Style Sheets (CSS):
- Javascript:
- MooTools:
*/
if(typeof(window['MooTools']) == "undefined"){
var mstkRedirect = 'http://www.mootools.net/';
if(confirm('Moostick requires the MooTools JavaScript framework.\n'
+ 'Be sure to include it before Moostick.\n\n'
+ 'Click OK for more info, or Cancel to load the page anyway.')){
top.location.href = redirect;
}
}
else{
var MoostickHelpers = {
checkQuery: function(val){
var init = false;
if(val.length > 0){
$ES('script').each(function(s){
if(s.src.match('moostick.js') && s.src.match(val))
init = true;
});
}
return init;
},
checkArray: function(lists){
if(!lists[0])
return [lists];
else
return lists;
}
} // end MoostickHelpers
if(MoostickHelpers.checkQuery('init=false') === false){
window.addEvent('domready', function() {
new MoostickInit(false, true);
});
}
var MoostickInit = Class({
lists : false,
autoStart : false,
interval : 3500,
fxOptions : {},
trustOpacity : false,
initialize: function(lists, autoStart, interval, fxOptions, trust4Speed, trustOpacity) {
this.lists = (!lists)
? this.lists
: lists;
this.autoStart = (autoStart === true)
? autoStart
: this.autoStart;
this.interval = (!interval) || (interval.toInt() < 500)
? this.interval
: interval.toInt();
this.fxOptions = ((!fxOptions) || (typeof(fxOptions) != 'object'))
? this.fxOptions
: fxOptions;
this.trustOpacity = (trustOpacity === true)
? trustOpacity
: this.trustOpacity;
if(autoStart === true){
if(trust4Speed === true){
// Kamikaze mode!
this._fastMode();
}
else{
// Cautious mode
this._safeMode();
}
}
},
_fastMode: function(){
this.lists = MoostickHelpers.checkArray(this.lists);
this.lists.each(function(list){
new Moostick(
list,
this.autoStart,
this.interval,
this.fxOptions,
this.trust4Speed,
this.trustOpacity
)
}, this);
},
_safeMode: function(){
if(this.lists === false){
var defaultLists = false;
// Scan for a list with the recommended default id
if($('moostick'))
defaultLists = [$('moostick')];
// Or can for (a) list(s) with the recommended default class
else if($$('.moostick'))
defaultLists = $$('.moostick');
this.lists = (!defaultLists) ? false : defaultLists;
}
if(this.lists){
this.lists = MoostickHelpers.checkArray(this.lists);
this.lists.each(function(list){
new Moostick(
list,
this.autoStart,
this.interval,
this.fxOptions,
this.trust4Speed,
this.trustOpacity
)
}, this);
}
}
}); // end MoostickInit
var Moostick = Class({
list : {},
autoStart : false,
interval : 3500,
fxOptions : {},
trustOpacity : false,
_firstRun : true,
_elSched : null,
initialize: function(list, autoStart, interval, fxOptions, trust4Speed, trustOpacity) {
this.list = ((!list) || (typeof(list) != 'object'))
? this.list
: list;
this.autoStart = (autoStart === true)
? autoStart
: this.autoStart;
this.interval = (!interval) || (interval.toInt() < 500)
? this.interval
: interval.toInt();
this.fxOptions = ((!fxOptions) || (typeof(fxOptions) != 'object'))
? this.fxOptions
: fxOptions;
this.trustOpacity = (trustOpacity === true)
? trustOpacity
: this.trustOpacity;
this.list.moostick = this;
if(autoStart === true){
if(trust4Speed === true){
// Kamikaze mode!
this._fastMode();
}
else{
// Cautious mode
this._safeMode();
}
}
},
startTick: function(list, interval, fxOptions, trust4Speed, trustOpacity){
this.initialize(list, true, interval, fxOptions, trust4Speed, trustOpacity);
},
stopTick: function(){
// TODO: figure out why removeEvent isn't working here
this.list.$events.mouseenter = false;
this.list.$events.mouseleave = false;
this.pauseTick();
},
pauseTick: function(){
this._elSched = $clear(this._elSched);
},
resumeTick: function(){
this._schedule();
},
_fastMode: function(){
this._liHandler();
this._schedule();
},
_safeMode: function(){
if(this.list){
if($ES('li', this.list)){
var items = $ES('li', this.list);
// Assign proprietary CSS class if not already assigned
if(!this.list.hasClass('moostick')) this.list.addClass('moostick');
// Test for an indication of existing style assignements,
var noStyle = false;
if( this.list.getStyle('overflow') != 'hidden'
|| items[0].getStyle('display') != 'block'
|| items[0].getStyle('list-style-type') != 'none'){
// we'll assume (!) no compatible style has been applied
noStyle = true;
}
if(noStyle){
this.list.setStyles({
'display' : 'block',
'height' : '1.1em',
'margin' : 0,
'padding' : '2px 0 2px 0',
'overflow': 'hidden'
});
this._liHandler({
'display' : 'block',
'list-style-type': 'none',
'margin' : '0 auto 0 auto',
'padding' : 0
});
}
else{
this._liHandler();
}
// We should now have a *more* trustworthy environment
this._schedule();
}
}
},
_setMouseEvents: function(){
this.list.addEvents({
'mouseenter': function(){
this.moostick.pauseTick();
},
'mouseleave': function(){
this.moostick.resumeTick();
}
});
},
_liHandler: function(styles){
// Verify styles value and format
if((!styles) || (typeof(styles) != 'object')) styles = false;
// no need to even loop if no styles were sent and trusting opacity
if((this.trustOpacity !== true) || (styles !== false)){
$ES('li', this.list).each(function(li){
// Apply styles before forcing opacity
if(styles !== false) li.setStyles(styles);
// Turn off all li but first
if(this.trustOpacity !== true)
li.setOpacity(0);
});
}
},
_schedule: function(noFade){
if(!this._elSched){
var firstItem = $E('li', this.list);
if(firstItem.getStyle('opacity') != 1)
this._fadeIn(firstItem);
else if(this._firstRun === true)
this._fadeIn(firstItem);
this._elSched = this._run.periodical(
this.interval,
this,
this.list
);
listEvents = this.list.$events;
if(!listEvents)
this._setMouseEvents();
else if((!listEvents.mouseenter) && (!listEvents.mouseleave))
this._setMouseEvents();
}
},
_run: function(){
var items = $ES('li', this.list);
// if we have at least 2
if(items[1]){
// move first to last
items[0].injectAfter(items.getLast());
// fade new first in
this._fadeIn(items[1]);
// set new last off, for future fade in
$ES('li', this.list).getLast().setOpacity(0);
}
},
_fadeIn: function(item){
item.effect('opacity', this.fxOptions).start(0,1);
this._firstRun = false;
}
}); // end Moostick
}