1/* 2 Vertical News Ticker 1.21 3 Original by: Tadas Juozapaitis ( kasp3rito [eta] gmail (dot) com ) 4 https://github.com/kasp3r/vTicker 5 Forked/Modified by: Richard Hollis @richhollis - richhollis.co.uk 6 */ 7(function($) { 8 var defaults, internal, methods; 9 defaults = { 10 speed: 700, 11 pause: 4000, 12 showItems: 1, 13 mousePause: true, 14 height: 0, 15 animate: true, 16 margin: 0, 17 padding: 0, 18 startPaused: false, 19 autoAppend: true, 20 direction:'up' 21 }; 22 internal = { 23 moveUp: function(state, attribs) { 24 return internal.showNextItem(state, attribs, 'up'); 25 }, 26 moveDown: function(state, attribs) { 27 return internal.showNextItem(state, attribs, 'down'); 28 }, 29 nextItemState: function(state, dir) { 30 var height, obj; 31 obj = state.element.children('ul'); 32 height = state.itemHeight; 33 if (state.options.height > 0) { 34 height = obj.children('li:first').height(); 35 } 36 height += state.options.margin + state.options.padding * 2; 37 return { 38 height: height, 39 options: state.options, 40 el: state.element, 41 obj: obj, 42 selector: dir === 'up' ? 'li:first' : 'li:last', 43 dir: dir 44 }; 45 }, 46 showNextItem: function(state, attribs, dir) { 47 var obj; 48 obj = state.element.children('ul'); 49 height = obj.children('li:last').height(); 50 var clone, nis; 51 nis = internal.nextItemState(state, dir); 52 nis.el.trigger('vtickerv2.beforeTick'); 53 clone = nis.obj.children(nis.selector).clone(true); 54 if (nis.dir === 'down') { 55 56 nis.obj.css('top', '-' + height + 'px').prepend(clone); 57 } 58 if (attribs && attribs.animate) { 59 if (!state.animating) { 60 internal.animateNextItem(nis, state); 61 } 62 } else { 63 internal.nonAnimatedNextItem(nis); 64 } 65 if (nis.dir === 'up' && state.options.autoAppend) { 66 clone.appendTo(nis.obj); 67 } 68 return nis.el.trigger('vtickerv2.afterTick'); 69 }, 70 animateNextItem: function(nis, state) { 71 72 var opts; 73 state.animating = true; 74 opts = nis.dir === 'up' ? { 75 top: '-=' + nis.height + 'px' 76 } : { 77 top: 0 78 }; 79 return nis.obj.animate(opts, state.options.speed, function() { 80 $(nis.obj).children(nis.selector).remove(); 81 $(nis.obj).css('top', '0px'); 82 return state.animating = false; 83 }); 84 }, 85 nonAnimatedNextItem: function(nis) { 86 nis.obj.children(nis.selector).remove(); 87 return nis.obj.css('top', '0px'); 88 }, 89 nextUsePause: function() { 90 var options, state; 91 state = $(this).data('state'); 92 options = state.options; 93 if (state.isPaused || internal.hasSingleItem(state)) { 94 return; 95 } 96 if(options.direction=='down'){ 97 return methods.prev.call(this, { 98 animate: options.animate 99 }); 100 } 101 else{ 102 103 return methods.next.call(this, { 104 animate: options.animate 105 }); 106 } 107 }, 108 startInterval: function() { 109 var options, state; 110 state = $(this).data('state'); 111 options = state.options; 112 return state.intervalId = setInterval((function(_this) { 113 return function() { 114 return internal.nextUsePause.call(_this); 115 }; 116 })(this), options.pause); 117 }, 118 stopInterval: function() { 119 var state; 120 if (!(state = $(this).data('state'))) { 121 return; 122 } 123 if (state.intervalId) { 124 clearInterval(state.intervalId); 125 } 126 return state.intervalId = void 0; 127 }, 128 restartInterval: function() { 129 internal.stopInterval.call(this); 130 return internal.startInterval.call(this); 131 }, 132 getState: function(from, elem) { 133 var state; 134 if (!(state = $(elem).data('state'))) { 135 throw new Error("vtickerv2: No state available from " + from); 136 } 137 return state; 138 }, 139 isAnimatingOrSingleItem: function(state) { 140 return state.animating || this.hasSingleItem(state); 141 }, 142 hasMultipleItems: function(state) { 143 return state.itemCount > 1; 144 }, 145 hasSingleItem: function(state) { 146 return !internal.hasMultipleItems(state); 147 }, 148 bindMousePausing: (function(_this) { 149 return function(el, state) { 150 return el.bind('mouseenter', function() {
151 if (state.isPaused) { 152 return; 153 } 154 state.pausedByCode = true; 155 internal.stopInterval.call(this); 156 return methods.pause.call(this, true); 157 }).bind('mouseleave', function() { 158 if (state.isPaused && !state.pausedByCode) { 159 return; 160 } 161 state.pausedByCode = false; 162 methods.pause.call(this, false); 163 return internal.startInterval.call(this); 164 }); 165 }; 166 })(this), 167 setItemLayout: function(el, state, options) { 168 var box; 169 el.css({ 170 overflow: 'hidden', 171 position: 'relative' 172 }).children('ul').css({ 173 position: 'absolute', 174 margin: 0, 175 padding: 0 176 }).children('li').css({ 177 margin: options.margin, 178 padding: options.padding 179 }); 180 if (isNaN(options.height) || options.height === 0) { 181 el.children('ul').children('li').each(function() { 182 if ($(this).height() > state.itemHeight) { 183 return state.itemHeight = $(this).height(); 184 } 185 }); 186 el.children('ul').children('li').each(function() { 187 return $(this).height(state.itemHeight); 188 }); 189 box = options.margin + options.padding * 2; 190 return el.height((state.itemHeight + box) * options.showItems + options.margin); 191 } else { 192 return el.height(options.height); 193 } 194 }, 195 defaultStateAttribs: function(el, options) { 196 return { 197 itemCount: el.children('ul').children('li').length, 198 itemHeight: 0, 199 itemMargin: 0, 200 element: el, 201 animating: false, 202 options: options, 203 isPaused: options.startPaused, 204 pausedByCode: false 205 }; 206 } 207 }; 208 methods = { 209 init: function(options) { 210 var clonedDefaults, el, state; 211 if (state = $(this).data('state')) { 212 methods.stop.call(this); 213 } 214 state = null; 215 clonedDefaults = jQuery.extend({}, defaults); 216 options = $.extend(clonedDefaults, options); 217 el = $(this); 218 state = internal.defaultStateAttribs(el, options); 219 $(this).data('state', state); 220 internal.setItemLayout(el, state, options); 221 if (!options.startPaused) { 222 internal.startInterval.call(this); 223 } 224 if (options.mousePause) { 225 return internal.bindMousePausing(el, state); 226 } 227 }, 228 pause: function(pauseState) { 229 var el, state; 230 state = internal.getState('pause', this); 231 if (!internal.hasMultipleItems(state)) { 232 return false; 233 } 234 state.isPaused = pauseState; 235 el = state.element; 236 if (pauseState) { 237 $(this).addClass('paused'); 238 return el.trigger('vtickerv2.pause'); 239 } else { 240 $(this).removeClass('paused'); 241 return el.trigger('vtickerv2.resume'); 242 } 243 }, 244 next: function(attribs) { 245 var state; 246 state = internal.getState('next', this); 247 if (internal.isAnimatingOrSingleItem(state)) { 248 return false; 249 } 250 internal.restartInterval.call(this); 251 return internal.moveUp(state, attribs); 252 }, 253 prev: function(attribs) { 254 var state; 255 state = internal.getState('prev', this); 256 if (internal.isAnimatingOrSingleItem(state)) { 257 return false; 258 } 259 internal.restartInterval.call(this); 260 return internal.moveDown(state, attribs); 261 }, 262 stop: function() { 263 var state; 264 state = internal.getState('stop', this); 265 return internal.stopInterval.call(this); 266 }, 267 remove: function() { 268 var el, state; 269 state = internal.getState('remove', this); 270 internal.stopInterval.call(this); 271 el = state.element; 272 el.unbind(); 273 return el.remove(); 274 } 275 }; 276 return $.fn.vtickerv2 = function(method) { 277 if (methods[method]) { 278 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 279 } 280 if (typeof method === 'object' || !method) { 281 return methods.init.apply(this, arguments); 282 } 283 return $.error('Method ' + method + ' does not exist on jQuery.vtickerv2'); 284 }; 285})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.