/*!
* jquery ui widget @version
*
* copyright 2011, authors.txt (http://jqueryui.com/about)
* dual licensed under the mit or gpl version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/ui/widget
*/
(function ($, undefined) {
var slice = array.prototype.slice;
var _cleandata = $.cleandata;
$.cleandata = function (elems) {
for (var i = 0, elem;
(elem = elems[i]) != null; i++) {
$(elem).triggerhandler("remove");
}
_cleandata(elems);
};
$.widget = function (name, base, prototype) {
var namespace = name.split(".")[0],
fullname;
name = name.split(".")[1];
fullname = namespace + "-" + name;
if (!prototype) {
prototype = base;
base = $.widget;
}
// create selector for plugin
$.expr[":"][fullname] = function (elem) {
return !!$.data(elem, name);
};
$[namespace] = $[namespace] || {};
// create the constructor using $.extend() so we can carry over any
// static properties stored on the existing constructor (if there is one)
$[namespace][name] = $.extend(function (options, element) {
// allow instantiation without "new" keyword
if (!this._createwidget) {
return new $[namespace][name](options, element);
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if (arguments.length) {
this._createwidget(options, element);
}
}, $[namespace][name]);
var baseprototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
baseprototype.options = $.widget.extend({}, baseprototype.options);
$.each(prototype, function (prop, value) {
if ($.isfunction(value)) {
prototype[prop] = (function () {
var _super = function (method) {
return base.prototype[method].apply(this, slice.call(arguments, 1));
};
var _superapply = function (method, args) {
return base.prototype[method].apply(this, args);
};
return function () {
var __super = this._super,
__superapply = this._superapply,
returnvalue;
this._super = _super;
this._superapply = _superapply;
returnvalue = value.apply(this, arguments);
this._super = __super;
this._superapply = __superapply;
return returnvalue;
};
}());
}
});
$[namespace][name].prototype = $.widget.extend(baseprototype, {
namespace: namespace,
widgetname: name,
widgeteventprefix: name,
widgetbaseclass: fullname
}, prototype);
$.widget.bridge(name, $[namespace][name]);
};
$.widget.extend = function (target) {
var input = slice.call(arguments, 1),
inputindex = 0,
inputlength = input.length,
key, value;
for (; inputindex < inputlength; inputindex++) {
for (key in input[inputindex]) {
value = input[inputindex][key];
if (input[inputindex].hasownproperty(key) && value !== undefined) {
target[key] = $.isplainobject(value) ? $.widget.extend({}, target[key], value) : value;
}
}
}
return target;
};
$.widget.bridge = function (name, object) {
$.fn[name] = function (options) {
var ismethodcall = typeof options === "string",
args = slice.call(arguments, 1),
returnvalue = this;
// allow multiple hashes to be passed on init
options = !ismethodcall && args.length ? $.widget.extend.apply(null, [options].concat(args)) : options;
if (ismethodcall) {
this.each(function () {
var instance = $.data(this, name);
if (!instance) {
return $.error("cannot call methods on " + name + " prior to initialization; " + "attempted to call method '" + options + "'");
}
if (!$.isfunction(instance[options]) || options.charat(0) === "_") {
return $.error("no such method '" + options + "' for " + name + " widget instance");
}
var methodvalue = instance[options].apply(instance, args);
if (methodvalue !== instance && methodvalue !== undefined) {
returnvalue = methodvalue.jquery ? returnvalue.pushstack(methodvalue.get()) : methodvalue;
return false;
}
});
} else {
this.each(function () {
var instance = $.data(this, name);
if (instance) {
instance.option(options || {})._init();
} else {
object(options, this);
}
});
}
return returnvalue;
};
};
$.widget = function (options, element) {
// allow instantiation without "new" keyword
if (!this._createwidget) {
return new $[namespace][name](options, element);
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if (arguments.length) {
this._createwidget(options, element);
}
};
$.widget.prototype = {
widgetname: "widget",
widgeteventprefix: "",
defaultelement: "
",
options: {
disabled: false,
// callbacks
create: null
},
_createwidget: function (options, element) {
element = $(element || this.defaultelement || this)[0];
this.element = $(element);
this.options = $.widget.extend({}, this.options, this._getcreateoptions(), options);
this.bindings = $();
this.hoverable = $();
this.focusable = $();
if (element !== this) {
$.data(element, this.widgetname, this);
this._bind({
remove: "destroy"
});
}
this._create();
this._trigger("create");
this._init();
},
_getcreateoptions: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function () {
this._destroy();
// we can probably remove the unbind calls in version 2
// all event bindings should go through this._bind()
this.element.unbind("." + this.widgetname).removedata(this.widgetname);
this.widget().unbind("." + this.widgetname).removeattr("aria-disabled").removeclass(
this.widgetbaseclass + "-disabled " + "ui-state-disabled");
// clean up events and states
this.bindings.unbind("." + this.widgetname);
this.hoverable.removeclass("ui-state-hover");
this.focusable.removeclass("ui-state-focus");
},
_destroy: $.noop,
widget: function () {
return this.element;
},
option: function (key, value) {
var options = key,
parts, curoption, i;
if (arguments.length === 0) {
// don't return a reference to the internal hash
return $.widget.extend({}, this.options);
}
if (typeof key === "string") {
if (value === undefined) {
return this.options[key];
}
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split(".");
key = parts.shift();
if (parts.length) {
curoption = options[key] = $.widget.extend({}, this.options[key]);
for (i = 0; i < parts.length - 1; i++) {
curoption[parts[i]] = curoption[parts[i]] || {};
curoption = curoption[parts[i]];
}
curoption[parts.pop()] = value;
} else {
options[key] = value;
}
}
this._setoptions(options);
return this;
},
_setoptions: function (options) {
var self = this;
$.each(options, function (key, value) {
self._setoption(key, value);
});
return this;
},
_setoption: function (key, value) {
this.options[key] = value;
if (key === "disabled") {
this.widget().toggleclass(this.widgetbaseclass + "-disabled ui-state-disabled", !! value).attr("aria-disabled", value);
this.hoverable.removeclass("ui-state-hover");
this.focusable.removeclass("ui-state-focus");
}
return this;
},
enable: function () {
return this._setoption("disabled", false);
},
disable: function () {
return this._setoption("disabled", true);
},
_bind: function (element, handlers) {
// no element argument, shuffle and use this.element
if (!handlers) {
handlers = element;
element = this.element;
} else {
// accept selectors, dom elements
element = $(element);
this.bindings = this.bindings.add(element);
}
var instance = this;
$.each(handlers, function (event, handler) {
element.bind(event + "." + instance.widgetname, function () {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if (instance.options.disabled === true || $(this).hasclass("ui-state-disabled")) {
return;
}
return (typeof handler === "string" ? instance[handler] : handler).apply(instance, arguments);
});
});
},
_hoverable: function (element) {
this.hoverable = this.hoverable.add(element);
this._bind(element, {
mouseenter: function (event) {
$(event.currenttarget).addclass("ui-state-hover");
},
mouseleave: function (event) {
$(event.currenttarget).removeclass("ui-state-hover");
}
});
},
_focusable: function (element) {
this.focusable = this.focusable.add(element);
this._bind(element, {
focusin: function (event) {
$(event.currenttarget).addclass("ui-state-focus");
},
focusout: function (event) {
$(event.currenttarget).removeclass("ui-state-focus");
}
});
},
_trigger: function (type, event, data) {
var callback = this.options[type],
args;
event = $.event(event);
event.type = (type === this.widgeteventprefix ? type : this.widgeteventprefix + type).tolowercase();
data = data || {};
// copy original event properties over to the new event
// this would happen if we could call $.event.fix instead of $.event
// but we don't have a way to force an event to be fixed multiple times
if (event.originalevent) {
for (var i = $.event.props.length, prop; i;) {
prop = $.event.props[--i];
event[prop] = event.originalevent[prop];
}
}
this.element.trigger(event, data);
args = $.isarray(data) ? [event].concat(data) : [event, data];
return !($.isfunction(callback) && callback.apply(this.element[0], args) === false || event.isdefaultprevented());
}
};
$.each({
show: "fadein",
hide: "fadeout"
}, function (method, defaulteffect) {
$.widget.prototype["_" + method] = function (element, options, callback) {
options = options || {};
var hasoptions = !$.isemptyobject(options),
effectname = options.effect || defaulteffect;
options.complete = callback;
if (options.delay) {
element.delay(options.delay);
}
if (hasoptions && $.effects && ($.effects.effect[effectname] || $.uibackcompat !== false && $.effects[effectname])) {
element[method](options);
} else if (effectname !== method && element[effectname]) {
element[effectname](options.duration, options.easing, callback);
} else {
element.queue(function () {
$(this)[method]();
if (callback) {
callback.call(element[0]);
}
});
}
};
});
// deprecated
if ($.uibackcompat !== false) {
$.widget.prototype._getcreateoptions = function () {
return $.metadata && $.metadata.get(this.element[0])[this.widgetname];
};
}
})(jquery);
/*
slidesjs, let the good times roll
*/
(function($) {
$.widget("js.slides", {
options: {
width: 1000, // [number] define the slide width
responsive: false, // [boolean] slideshow will scale to its container
height: 492, // [number] define the slide height
navigation: true, // [boolean] auto generate the naviagation, next/previous buttons
pagination: true, // [boolean] auto generate the pagination
effects: {
navigation: "slide", // [string] can be either "slide" or "fade"
pagination: "slide" // [string] can be either "slide" or "fade"
},
direction: "left", // [string] define the slide direction: "up", "right", "down", "left"
fade: {
interval: 1000, // [number] interval of fade in milliseconds
crossfade: false, // [boolean] todo: add this feature. crossfade the slides, great for images, bad for text
easing: "" // [string] dependency: jquery easing plug-in
},
slide: {
interval: 1000, // [number] interval of fade in milliseconds
browserwindow: false, // [boolean] slide in/out from browser window, bad ass
easing: "" // [string] dependency: jquery easing plug-in
},
preload: {
active: false, // [boolean] preload the slides before showing them, this needs some work
image: "../images/loading.gif" // [string] define the path to a load .gif, yes i should do something cooler
},
startatslide: 1, // [number] what should the first slide be?
playinterval: 5000, // [number] time spent on each slide in milliseconds
pauseinterval: 8000, // [number] time spent on pause, triggered on any navigation or pagination click
autoheight: false, // [boolean] todo: add this feature. auto sets height based on each slide
navigatestart: function( current ){
// console.log( "navigatestart: ", current );
},
navigateend: function( current ){
// console.log( "navigateend: ", current );
},
loaded: function() {
// console.log( "loaded" );
}
},
_create: function() {
// error correction for only 1 slide
if (this.element.children().length < 2) {
return;
}
if ( this.options.slide.browserwindow ) {
this.element.css({
width: window.innerwidth,
position: "relative",
left: - (window.innerwidth / 2) + (this.options.width / 2),
overflow: "hidden"
});
$(window).resize( $.proxy(function() {
this.element.css({
width: window.innerwidth,
left: - (window.innerwidth / 2) + (this.options.width / 2)
});
this.slidescontainer.css({
left: this.options.slide.browserwindow ? (window.innerwidth - this.options.width) / 2 : ""
});
},this));
}
this.slidescontainer = this.element.children().not(".slidesnavigation").wrapall( "
" ).parent().css({
width: this.options.responsive ? "100%" : this.options.width,
height: this.options.height,
overflow: this.options.slide.browserwindow ? "visible" : "hidden",
position: "relative",
left: this.options.slide.browserwindow ? (window.innerwidth - this.options.width) / 2 : ""
});
this.slidescontrol = this.slidescontainer.wrapinner( "
" ).children().css({
display: "none"
});
// define the slides
this.slides = this.slidescontrol.children();
// set css for slidescontrol
this.slidescontrol.css({
position: "relative",
width: this.options.responsive ? "100%" : this.options.width,
height: this.options.height,
left: 0
});
// set css for each slide
this.slides.css({
position: "absolute",
top: 0,
left: 0,
zindex: 0,
display: "none"
});
// show the starting slide with a fade in
this.slides.eq( this.options.startatslide - 1 ).fadein( this.options.fade.interval );
if ( this.options.preload.active ) {
/* todo: loading image, need to remove on load callback
this.slidescontainer.css({
backgroundimage: "url(" + this.options.preload.image + ")",
backgroundposition: "50% 50%",
backgroundrepeat: "no-repeat"
});
*/
var preloadimage;
if (this.slides.eq( this.options.startatslide - 1 ).is("img")) {
preloadimage = this.slides.eq( this.options.startatslide - 1 ).attr("src");
} else {
preloadimage = this.slides.eq( this.options.startatslide - 1 ).find("img").attr("src");
}
this._loadimage( preloadimage ).then( $.proxy(function( url ) {
this.slidescontrol.fadein( this.options.fade.interval );
this._trigger( "loaded", this.options.startatslide, this );
},this));
} else {
this.slidescontrol.fadein( this.options.fade.interval );
}
if ( this.options.navigation ) {
this.prevbutton = $("
",{
"class": "slidesprevious slidesnavigation",
href: "#",
title: "previous",
text: ""
}).appendto( this.element );
this.nextbutton = $("",{
"class": "slidesnext slidesnavigation",
href: "#",
title: "next",
text: ""
}).appendto( this.element );
} else {
this.nextbutton = $(".slidesnext");
this.prevbutton = $(".slidesprevious");
}
if (this.options.pagination) {
this._buildpagination();
// add current class to first pagination
this.pagination.children().eq( this.options.startatslide - 1 ).addclass("slidescurrent");
}
this.current = this.options.startatslide - 1;
this.element.delegate( ".slidesnavigation", "click", $.proxy(this, "_navigate") );
this.total = this.slides.length;
},
_loaded: function() {
if ( this.options.responsive ) {
// todo: cleanup and condense
this.slidescontainer.css({
height: this.slides.height()
});
this.slidescontrol.css({
height: this.slides.height()
});
$(window).resize( $.proxy(function() {
this.slidescontainer.css({
height: this.slides.height()
});
this.slidescontrol.css({
height: this.slides.height()
});
},this));
}
},
_buildpagination: function() {
if (this.pagination) {
// remove the current paginaiton
this.pagination.remove();
// redefine slides with new children
this.slides = this.slidescontrol.children();
}
this.pagination = $("",{
"class": "slidespagination"
}).appendto(this.element);
this.slides.each(
$.proxy(function(index, element) {
$("").appendto(this.pagination);
},this)
);
},
_loadimage: function(imagesrc) {
var deferred, preloader;
var loadimagecache = {};
if (typeof loadimagecache[imagesrc] === "undefined") {
deferred = $.deferred();
preloader = new image();
preloader.onload = function() {
deferred.resolve(this.src);
};
preloader.onerror = function() {
deferred.reject(this.src);
};
preloader.src = imagesrc;
loadimagecache[imagesrc] = deferred;
}
return loadimagecache[imagesrc];
},
next: function( effect ) {
this._navigate("next", effect);
},
previous: function( effect ) {
this._navigate("previous", effect);
},
slide: function( slide, effect ) {
this.element.data("goto", (slide - 1));
this._navigate("pagination", effect);
},
_navigate: function( event, effect ) {
var to, position, direction, next, prev, pagination, $target = $(event.target), currentslide = this.slides.eq( this.current );
/*
slide to error correction
*/
if ( this.element.data("goto") < 0 ) {
// if goto is less then 0
this.element.data("goto",0);
} else if ( this.element.data("goto") > this.total ) {
// if goto is greater then total slides
this.element.data("goto",(this.total - 1));
}
/*
check if slides is currently animating
*/
if ( this.element.data("animated") || $target.data("slidesindex") === this.current || this.element.data("goto") === this.current ) {
return false;
}
/*
is this event coming from a click?
*/
if (typeof(event) === "object") {
event.preventdefault();
// pause on navigation item click
if ( this.state === "playing" && this.options.pauseinterval ) {
this.pause();
}
} else {
if (event === "next") {
next = true;
} else {
prev = true;
}
}
/*
set to animated
*/
this.element.data("animated",true);
if ( $target.hasclass( "slidesnext" ) ) {
// next button clicked
next = true;
} else if ( $target.hasclass("slidesprevious") ) {
// previous button clicked
prev = true;
} else if ( $target.hasclass("slidespaginationitem") || event === "pagination") {
// paginaiton item clicked
if ( this.current > $target.data("slidesindex") || this.current > this.element.data("goto") ) {
prev = true;
} else {
next = true;
}
pagination = true;
effect = effect ? effect : this.options.effects.pagination;
}
if (pagination) {
// get next from data-slidesindex
to = this.element.data("goto") > -1 ? this.element.data("goto") : $target.data("slidesindex");
} else {
// get next based on curent
to = next ? (this.current + 1) : (prev ? this.current - 1 : this.current);
}
// pass slide from number
this._trigger("navigatestart", ( this.current + 1 ), this);
// creat the loop
if ( to == this.slides.length && !pagination ) {
// last slide, loop to first
to = 0;
} else if ( to == -1 && !pagination ) {
// first slide, loop to last
to = this.slides.length - 1;
}
if (this.options.pagination) {
// change the pagination
this.pagination.children().removeclass("slidescurrent");
this.pagination.children().eq( to ).addclass("slidescurrent");
}
// effects methods
if (effect === "fade") {
this._fade({
next: next,
to: to,
currentslide: currentslide
});
} else {
this._slide({
next: next,
to: to,
currentslide: currentslide
});
}
},
_slide: function (navigatedata) {
/*
thanks to thomas reynolds
*/
var isflipped = navigatedata.next ? 1 : -1;
var isopposite = this.options.direction.match(/right|down/) ? -1 : 1;
var type = this.options.direction.match(/left|right/) ? "horizontal" : "vertical";
var vector = (type == "horizontal") ? "width" : "height";
vector = this.options.responsive ? this.slides.width() : this.options[vector] ;
var position = vector * isopposite * isflipped;
if (this.options.slide.browserwindow) {
if (navigatedata.next) {
position = math.abs( this.options.width - window.innerwidth - position);
} else {
position = this.options.width - window.innerwidth + position;
}
}
var direction = position * -1;
// setup the "to" slide
this.slides.eq( navigatedata.to ).css({
left: type === "vertical" ? 0 : position,
top: type === "vertical" ? position : 0,
zindex: 5,
display: "block"
});
// animate control
this.slidescontrol.animate({
left: type === "vertical" ? 0 : direction,
top: type === "vertical" ? direction : 0
},this.options.slide.interval, this.options.slide.easing, $.proxy(function(){
// after animation reset control position
this.slidescontrol.css({
top: 0,
left:0
});
// reset and show next
this.slides.eq( navigatedata.to ).css({
top: 0,
left:0,
zindex: 5
});
// reset previous slide
navigatedata.currentslide.css({
top: 0,
left:0,
display: "none",
zindex: 0
});
this.current = navigatedata.to;
this._trigger("navigateend", ( this.current + 1 ), this);
}, this));
},
_fade: function (navigatedata) {
// put hidden to slide above current
this.slides.eq( navigatedata.to ).css({
zindex: 10
// fade in next
}).fadein(this.options.fade.interval, this.options.fade.easing, $.proxy(function(){
// hide previous
navigatedata.currentslide.css({
display: "none",
zindex: 0
});
// reset zindex
this.slides.eq( navigatedata.to ).css({
zindex: 0
});
this.current = navigatedata.to;
this._trigger("navigateend", ( this.current + 1 ), this);
}, this));
},
play: function( gotonext ) {
if (gotonext !== false) {
this._navigate("next");
}
var playinterval = setinterval( $.proxy(function() {
this._navigate("next");
}, this), this.options.playinterval);
// set status
this.state = "playing";
// store the unique interval id
this.element.data("playintervalid",playinterval);
},
pause: function() {
cleartimeout( this.element.data("pausetimeoutid") );
clearinterval( this.element.data("playintervalid") );
var pausetimeout = settimeout($.proxy(function() {
this.play();
}, this), this.options.pauseinterval);
// set status
this.state = "paused";
// store the unique pause timeout id
this.element.data("pausetimeoutid",pausetimeout);
},
stop: function() {
clearinterval( this.element.data("playintervalid") );
// set status
this.state = "stopped";
},
update: function() {
this._buildpagination();
},
status: function( key ) {
if (key) {
return this[key] ? this[key] : false;
} else {
return {
"state": this.state,
"current": this.current,
"total": this.total
};
}
},
_setoption: function(key, value) {
switch(key) {
/*
todo: this needs work, note status function use of this[key]
$("#slides").slides("option","pagination", false);
case "pagination":
if (value !== this.options.pagination ) {
value ? this._buildpagination() : this.pagination.remove();
}
break;
*/
}
$.widget.prototype._setoption.apply(this,arguments);
},
destroy: function() {
this.slidescontainer.contents().unwrap();
this.slidescontrol.contents().unwrap();
this.element.unbind();
this.pagination.remove();
this.nextbutton.remove();
this.prevbutton.remove();
this.slides.attr( "style", "" );
$.widget.prototype.destroy.call(this);
},
_trigger: function( event, current ) {
if (event != "create") {
this.options[event]( current );
}
if (event === "navigateend") {
this.element.data("animated",false);
}
if (event === "loaded") {
this._loaded();
}
}
});
})(jquery);