PageSourceSearch

https://www.cfkargentina.com/js/newsticker.jquery.js

js cfkargentina.com collected 2026-10-02 04:53:22 UTC 61,031 bytes, 1,499 lines download raw bytes

1// Module pattern
2(function( $ ) {
3  
4    // Backwards compatibility
5    if ( $.fn.on === undefined ) {
6        $.fn.on = function( event, fn ) {
7            this.bind( event, fn );
8        }
9    }
10    
11    // Backwards compatibility
12    if ( $.fn.off === undefined ) {
13        $.fn.off = function( event, fn ) {
14            return this.unbind( event, fn );
15        }
16    }
17         
18    // The plugin wrapper
19    $.fn.newsticker = function( options ) {
20        var self = this;
21        
22        self.methods = $.fn.newsticker.methods;        
23        self.api = $.fn.newsticker.api;
24        self.delegate = $.fn.newsticker.delegate;              
25        self.settings = $.extend( {}, $.fn.newsticker.defaults, options);                                                     
26        
27        // Method call return
28        return this.each( function() {
29            self.api( 'init', $(this) );
30        });
31    }
32    
33    // Default newsticker settings
34    $.fn.newsticker.defaults = {        
35        style               : 'scroll',
36        showControls        : true,
37        tickerTitle         : '#Juanes',
38        feedItems           : 10,
39        feeds               : 'https://search.twitter.com/search.atom?q=%23Juanes',
40        feedFormat          : '%title% Posteado por %author%',
41        noCache             : false,        
42        twitter             : '', 
43        twitterFormat       : '%excerpt% Posteado en <a href="%link%">Twitter</a> %timeago%',
44        twitterCount        : '',        
45        parseTwitterLinks   : true,
46        openLinksInNewWindow: false,
47        facebook            : '',
48        facebookFormat      : '%excerpt%... Posteado en <a href="%link%">Facebook</a> %timeago%',
49        facebookCount       : '',
50        lastfm              : '',
51        lastfmFormat        : '<a href="%link%">%title%</a> listened to %timeago%',
52        lastfmCount         : '',
53        tumblr              : '',
54        tumblrFormat        : '<a href="%link%">%title%</a> posted by %author%, %timeago%',
55        tumblrCount         : '',        
56        pinterest           : '',
57        pinterestFormat     : '<a href="%item_link%">%excerpt%</a> pinned %timeago%',
58        pinterestCount      : '',
59        excerptLength       : 100,
60        sortBy              : 'timestamp',
61        reverseOrder        : false,       
62        autoStart           : true,
63        timeAgoFormat       : function( date ) {            
64                                  return $.fn.newsticker.methods.getTimeAgo( date );
65                              }, 
66        dateFormat          : function( date ) {
67                                  return $.fn.newsticker.methods.getFormattedDate( date );
68                              }      
69    }
70    
71    // An interface to call style methods
72    $.fn.newsticker.delegate = function( name ) {            
73        var style_method = this.style[name],
74            args = Array.prototype.slice.call(arguments, 1);
75        
76        if ( typeof( style_method ) === 'function' ) {
77            return style_method.apply( this, args );
78        }            
79        return false;
80    } 
81    
82    // An interface to call general newsticker methods
83    $.fn.newsticker.api = function( method ) {
84        var api_method = this.methods[method],            
85            args = Array.prototype.slice.call(arguments, 1);        
86        
87        if ( typeof( api_method ) === 'function' ) {
88            return api_method.apply( this, args );
89        }
90        return false;
91    }
92    
93    // Global newsticker methods
94    $.fn.newsticker.methods = {        
95        
96        // Get unique newsticker ID
97        getId : function() {
98            var newDate = new Date;
99            return newDate.getTime();
100        },
101        
102        // Once-off initialisation routine
103        init : function( element ) {           
104          
105            // Validate newsticker style and load if valid
106            if ( typeof( $.fn.newsticker.styles[ this.settings.style] ) === 'object' ) {
107                this.style = $.fn.newsticker.styles[ this.settings.style ];
108            }
109            else {
110                console.log( 'ERROR: Invalid display style.' );
111                return;
112            }            
113             
114            // Update settings with defaults from newsticker style object
115            this.settings = $.extend( this.delegate( 'settings' ), this.settings);
116             
117            // Start style initialization
118            this.delegate( 'init' );
119
120            // Create dom object
121            this.dom = {};
122            this.dom.list = element;            
123            
124            // Compile feeds array. Check for 'sugar' feeds -- Twitter, Facebook page, Last.fm, Googe Plus 
125            this.api( 'getFeeds' );
126            
127            if (this.feeds.length === 0 
128                && this.settings.twitter.length === 0 
129                && this.settings.facebook.length === 0
130                && this.settings.lastfm.length === 0
131                && this.settings.tumblr.length === 0
132                && this.settings.pinterest.length === 0) {
133                // List items
134                this.dom.items = this.dom.list.children('li');
135
136                // Startup
137                this.api( 'startup' );
138            } 
139        }, 
140        
141        // Startup. This is a sort of second init, called only when all the list items are loaded
142        startup : function() {          
143            var self = this,
144                dom = this.dom,
145                settings = this.settings,
146                list = dom.list;
147            
148            // Make dom modifications -- this is applied to all newsticker instances, regardless of style               
149            // Wrap the list inside a div, and insert a title before it
150            list.wrap('<div class="newsticker_wrapper newsticker_style_'+settings.style+'" id="newsticker_'+this.api( 'getId' )+'" style="position: relative; z-index: 150; overflow: hidden; "></div>');  
151
152            // Insert title if set
153            if (settings.tickerTitle.length > 0) {
154                $('<div class="newsticker_title"><h4>'+settings.tickerTitle+'</h4></div>').insertBefore(list);              
155            }
156            
157			// Save both of the new dom elements
158            dom.wrapper = list.parent(); 
159            dom.title = dom.wrapper.children('.newsticker_title');            
160
161            // Add controls if set to true
162            if (settings.showControls === true) {              
163                var pause_or_resume = settings.autoStart === false ? 'resume' : 'pause',
164                    controls;
165
166                $('<ul class="newsticker_controls">\
167                    <li class="previous"></li>\
168                    <li class="'+pause_or_resume+'"></li>\
169                    <li class="next"></li>\
170                  </ul>').insertAfter(list);
171
172                controls = list.next('.newsticker_controls');
173                
174                controls.children('.previous').on('click', function() {
175                    self.delegate( 'previous' );
176                });                
177                controls.children('.pause').on('click', function() {
178                    self.delegate( 'pause' );
179                });
180                controls.children('.resume').on('click', function() {
181                    self.delegate( 'resume' );
182                });
183                controls.children('.next').on('click', function() {
184                    self.delegate( 'next' );
185                });                
186            }
187
188            // Save controls
189            dom.controls = controls === undefined ? dom.wrapper.children('.newsticker_controls') : controls;
190            
191            // Pause animation on hover if set to true
192            if (settings.pauseOnHover === true) {
193                dom.items.on('mouseover', function(){ self.delegate( 'pause' ); });
194                dom.items.on('mouseout', function(){ self.delegate( 'resume' ); });
195            }            
196            
197            // Handle window resize
198            $(window).resize( function() {
199                self.api( 'resize' );
200            });
201
202            // Allow styles to make their own DOM manipulations
203            this.delegate( 'manipulateDom' ); 
204
205            // Loop through individual items
206            this.delegate( 'itemLoop' );
207            
208            // Start animation
209            this.delegate( 'start' );        
210        },
211        
212        // Get collection of feeds to fetch
213        getFeeds : function() {
214            var self = this,
215                settings = self.settings,
216                feedItems = settings.feedItems,
217                count,
218                url;
219            
220            self.feeds = [];            
221            
222            // Feeds
223            if (settings.feeds.length > 0) {                
224                var _feeds = typeof (settings.feeds) === 'string' ? [settings.feeds] : settings.feeds;
225                
226                for (var i = 0, max = _feeds.length; i < max; i += 1) {
227                    var _feed = _feeds[i];
228                    
229                    url = typeof (_feed) === 'string' ? _feed : _feed.url;
230                    count = _feed.hasOwnProperty('count') ? _feed.count : feedItems;                    
231                    self.feeds.push({
232                        'type'  : 'feed',
233                        'url'   : document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=' + parseInt(count) + '&callback=?&q=' + encodeURIComponent( url ),
234                        'count' : count
235                    });
236                }
237            }
238             
239            // Twitter feed
240            if (settings.twitter.length > 0) {
241                count = settings.twitterCount > 0 ? settings.twitterCount : feedItems;                
242                self.feeds.push({
243                    'type'  : 'twitter',
244                    'url'   : 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=' + encodeURIComponent( settings.twitter ) + '&callback=?&include_entities=1&count=' + parseInt(count),
245                    'count' : count
246                });                
247            }            
248            
249            // Last.fm feed
250            if (settings.lastfm.length > 0) {
251                count = settings.lastfmCount > 0 ? settings.lastfmCount : feedItems;
252                url = 'http://ws.audioscrobbler.com/1.0/user/' + settings.lastfm + '/recenttracks.rss';
253                self.feeds.push({
254                    'type'  : 'lastfm',
255                    'url'   : document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=' + parseInt(count) + '&callback=?&q=' + encodeURIComponent( url ),
256                    'count' : count
257                });
258            }
259            
260            // Tumblr feed
261            if (settings.tumblr.length > 0) {
262                count = settings.tumblrCount > 0 ? settings.tumblrCount : feedItems;
263                url = 'http://' + settings.tumblr + '.tumblr.com/rss';
264                self.feeds.push({
265                    'type'  : 'tumblr',
266                    'url'   : document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=' + parseInt(count) + '&callback=?&q=' + encodeURIComponent( url ),
267                    'count' : count
268                });
269            }      
270            
271            // Pinterest feed
272            if (settings.pinterest.length > 0) {
273                count = settings.pinterestCount > 0 ? settings.pinterestCount : feedItems;
274                url = 'http://pinterest.com/' + settings.pinterest + '/feed.rss';
275                self.feeds.push({
276                    'type'  : 'pinterest',
277                    'url'   : document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=' + parseInt(count) + '&callback=?&q=' + encodeURIComponent( url ),
278                    'count' : count
279                });
280            }      
281            
282            // Facebook page feed -- this should always be the last feed requested
283            if (settings.facebook.length > 0) {
284                var fb,
285                    date = new Date();
286                
287                $.ajax({
288                    url: document.location.protocol + '//graph.facebook.com/'+settings.facebook, // The timestamp is appended to prevent ID caching
289                    dataType: 'jsonp',
290                    success: function(json){
291                        fb = json;
292                    },
293                    error: function(xhr, status, error) {
294                        console.log( 'An error occurred while trying to fetch this profile from Facebook' );                        
295                        fb = 'error';
296                    },
297                    complete: function() {
298                        if ( fb !== 'error' ) {
299                            self.api( 'completeFacebookRequest', fb );                                                
300                        }
301                    }
302                });                              
303            }
304            else {
305                self.api( 'getFeedItems' );
306            }
307        },  
308        
309        // Executed when request to Facebook for a Facebook page JSON object is completed
310        completeFacebookRequest : function( fb ) {
311            var settings = this.settings,
312                count = settings.facebookCount > 0 ? settings.facebookCount : settings.feedItems,
313                url = 'https://www.facebook.com/feeds/page.php?id=' + fb.id + '&format=rss20';                
314            
315            this.feeds.push({
316                'type'  : 'facebook',
317                'url'   : document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=' + parseInt(count) + '&callback=?&q=' + encodeURIComponent( url ),
318                'count' : count,
319                'data'  : fb
320            });     
321
322            // Get list items from feed
323            this.api( 'getFeedItems'  );
324        },
325        
326        // Add items from fetched RSS feed
327        addItems : function( items, response, type ) {
328            var entries = this.api( 'getItemsFromResponse', response, type ), 
329                max = entries.length, 
330                i = 0;                
331            
332            for (i; i < max; i += 1) {
333                var entry = entries[i];
334                entry.timestamp = this.api( 'getTimestamp', entry, type );
335                items.push( entry );
336            }
337            
338            return items;            
339        },
340        
341        // Get entries from ajax call response
342        getItemsFromResponse : function( response, type ) {
343            switch (type) {
344                case 'twitter':
345                    return response;
346                    break;
347                default:
348                    return response.responseData.feed.entries;
349                    break;
350            }
351        },
352        
353        // Get timestamp
354        getTimestamp : function( item, type )  {
355            switch (type) {
356                case 'twitter':
357                    var v = item.created_at.split(' ');
358                    return new Date(Date.parse( v[1] + " " + v[2] + ", " +v[5] + " " + v[3] + " UTC"));
359                    break;
360                default:
361                    return new Date( item.publishedDate );
362                    break;
363            }
364        },
365        
366        // Get feed items
367        getFeedItems : function() {
368            var self = this,
369                items = [],
370                feeds = this.feeds,
371                complete = 0, 
372                feed, type, url;
373                
374            for (var i = 0, max = feeds.length; i < max; i += 1) {              
375                feed = feeds[i],
376                type = feed.type, 
377                url = feed.url;
378                    
379                // Prevent feed caching
380                if ( self.settings.noCache === true ) {
381                    var timestamp = new Date().getTime();
382                    url += '&' + timestamp;
383                }
384                                
385                $.ajax({
386                  url: url,
387                  dataType: 'json',
388                  success: function(data) {                                                                
389                      if ( type === 'feed' && data.responseStatus !== 200) {
390                          console.log( 'Unable to load feed' );
391                          return;
392                      }          
393                      
394                      // Add items to collection
395                      self.api( 'addItems', items, data, type );
396                  }, 
397                  error: function(xhr, status, error) {
398                      console.log( 'An error occurred while trying to fetch feed from ' + feed.url + '. Status: ' + status );
399                  },
400                  complete: function() {                      
401                      // Make sure that every feed call has been completed before proceeding
402                      complete += 1;
403                      if (complete === max) {                                                  
404                          self.api( 'completeFeedItemsRequest', items, type );                        
405                      }                                                                
406                  }
407                });              
408            }        
409        },
410        
411        // Function to execute when feed items retrieval is complete
412        completeFeedItemsRequest : function( items, type ) {
413            var i,
414                settings = this.settings,
415                max = items.length > settings.feedItems ? settings.feedItems : items.length,
416                html,
417                list = this.dom.list, 
418                sort_by = settings.sortBy,
419                reverse = settings.reverseOrder;                              
420
421            // Sort items
422            if (sort_by === 'random') {                              
423                items = this.api( 'randomize', items );
424            }
425            else {
426                items.sort( this.api('sortBy', sort_by, reverse ) );
427            }                          
428
429            for (i = 0; i < max; i += 1) {
430                html = this.api( 'displayFeedItem', items[i], type );
431                list.append( html );
432            }
433
434            this.dom.items = list.children('li');                
435            this.api( 'startup' );
436        },
437        
438        // Sort feed items
439        sortBy : function(field, reverse) {
440                        
441            var key = function(x) {
442                return x[field];
443            };
444          
445            return function( a, b ) {
446                var A = key(a), 
447                    B = key(b);
448                    
449                return ( (A < B) ? -1 :
450                         (A > B) ? +1 : 0) * [-1,1][+!!reverse];
451            }          
452        },        
453        
454        // Randomly order feed items
455        randomize : function( array ) {
456            var tmp, 
457                current, 
458                top = array.length;
459          
460            if (top) while( --top ) {
461                current = Math.floor( Math.random() * (top + 1) );
462                tmp = array[current];
463                array[current] = array[top];
464                array[top] = tmp;
465            }
466            
467            return array;
468        },
469        
470        // Get feed item format
471        getFormat : function( type ) {
472            var settings = this.settings;
473            
474            switch (type) {                        
475                case 'facebook':
476                    return settings.facebookFormat.length > 0 ? settings.facebookFormat : settings.feedFormat;
477                    break;
478                case 'twitter':
479                    return settings.twitterFormat.length > 0 ? settings.twitterFormat : settings.feedFormat;
480                    break;
481                case 'lastfm':
482                    return settings.lastfmFormat.length > 0 ? settings.lastfmFormat : settings.feedFormat;
483                    break;
484                case 'tumblr':
485                    return settings.tumblrFormat.length > 0 ? settings.tumblrFormat : settings.feedFormat;
486                    break;
487                case 'pinterest':
488                    return settings.pinterestFormat.length > 0 ? settings.pinterestFormat : settings.feedFormat;
489                    break;
490                default:
491                    return settings.feedFormat;
492                    break;
493            }
494        },
495        
496        // Display feed item
497        displayFeedItem : function( item, type ) {
498            var text = this.api( 'getFormat', type ),
499                replace = ['author', 'excerpt', 'link', 'item_link', 'title', 'timeago', 'date'],
500                replacement,
501                key;
502
503            for (var i = 0; i < replace.length; i += 1) {                            
504                key = replace[i];
505                
506                // Get replacement
507                if (key === 'timeago') {
508                    replacement = this.settings.timeAgoFormat( item.timestamp );
509                }
510                else if (key === 'date') {
511                    replacement = this.settings.dateFormat.apply( this, [ item.timestamp ] );
512                }
513                else {
514                    replacement = this.api( 'getReplacement', item, key, type );
515                }
516
517                // Do replacement
518                switch (key) {                
519                    case 'author':
520                        text = text.replace( /\%author\%/g, replacement );
521                        break;
522
523                    case 'excerpt':
524                        text = text.replace( /\%excerpt\%/g, replacement );
525                        break;
526
527                    case 'link':
528                        text = text.replace( /\%link\%/g, replacement );
529                        break;
530                        
531                    case 'item_link':
532                        text = text.replace( /\%item_link\%/g, replacement );
533                        break;                        
534
535                    case 'title':
536                        text = text.replace( /\%title\%/g, replacement );
537                        break;
538
539                    case 'timeago':
540                        text = text.replace( /\%timeago\%/g, replacement );                        
541                        break;
542
543                    case 'date':
544                        text = text.replace( /\%date\%/g, replacement);
545                        break;
546                }                    
547            }
548
549            return '<li>
549' + text + '</li>';
550        },
551        
552        // Get entry key
553        getReplacement : function( item, key, type ) {          
554            switch (key) {                
555                case 'author' :
556                    switch (type) {
557                        case 'twitter':
558                            return item.user.name;
559                            break;
560
561                        default:
562                            return item.author;
563                            break;
564                    }
565                    break;
566                    
567                case 'excerpt' :
568                    switch (type) {
569                        case 'twitter':
570                            var text = this.api( 'getTwitterText', item, this.settings.parseTwitterLinks );
571                            
572                            return text;   
573                            break;
574                        
575                        case 'facebook':
576                            var t = $(item.content).text();
577                            
578                            if (t === '') {
579                                return item.contentSnippet.length > this.settings.excerptLength 
580                                      ? item.contentSnippet.slice(0, this.settings.excerptLength)
581                                      : item.contentSnippet;  
582                            }
583                            else {
584                                return t;
585                            }                            
586                            break;
587                            
588                        case 'lastfm':                            
589                            return item.title; 
590                            break;                          
591                        
592                        default:
593                            return item.contentSnippet.length > this.settings.excerptLength 
594                                      ? item.contentSnippet.slice(0, this.settings.excerptLength)
595                                      : item.contentSnippet;  
596                            break;
597                    }
598                    break;
599                    
600                case 'link' :
601                    switch (type) {
602                        case 'twitter':
603                            return 'https://twitter.com/#!/'+ item.user.screen_name; 
604                            break;
605                            
606                        case 'facebook':
607                            return 'http://facebook.com/' + this.settings.facebook;
608                            break;
609                        
610                        case 'pinterest':
611                            return 'http://pinterest.com/' + this.settings.pinterest + '/';
612                            break;
613                        
614                        default:
615                            return item.link;  
616                            break;
617                    }
618                    break;
619                    
620                case 'item_link' :
621                    switch (type) {
622                        case 'twitter':
623                            return 'https://twitter.com/#!/'+ item.user.name + '/statuses/'+ item.id_str;  
624                            break;
625                        
626                        case 'lastfm':
627                            return item.content;
628                            break;
629
630                        default:
631                            return item.link;
632                            break;
633                    }
634                    break;
635                    
636                case 'title' :
637                    switch (type) {
638                        case 'twitter':
639                            return '';  
640                            break;
641                        
642                        default:
643                            return item.title;  
644                            break;
645                    }
646                    break;
647                
648            }             
649        },
650        
651        // Get Twitter text
652        getTwitterText: function( item, parseLinks ) {
653            var text = item.text,                
654                self = this,
655                entities = [],
656                links,
657                entity;
658            
659            text = text.length > this.settings.excerptLength 
660                ? text.slice(0, this.settings.excerptLength)
661                : text;
662            
663            if ( parseLinks === false ) {
664                return text;
665            }   
666                     
667            // Parse URLs in tweets            
668            jQuery.each( item.entities, function(name, links) {                
669                for ( var i = 0, max = links.length; i < max; i += 1 ) {
670                    entity = links[i];
671                    entity.type = name;
672                    entity.start = entity.indices[0];
673                    entities.push( entity );
674                }
675            });
676
677            entities.sort( this.api('sortBy', 'start', false ) );
678
679            for ( var i = 0, max = entities.length; i < max; i += 1 ) {
680                text = this.api( 'parseTwitterLink', text, entities[i] );
681            }
682
683            return text;
684        },
685        
686        // Parse Twitter link
687        parseTwitterLink: function( text, entity ) {
688            var start = entity.start,
689                end = entity.indices[1],
690                url,
691                text;
692                
693            if ( start < this.settings.excerptLength ) {
694                url = this.api( 'getTwitterLink', entity );    
695                text = text.slice(0, start) + url + text.slice(end);    
696            }
697            
698            return text;
699        },        
700        
701        // Get Twitter link, depending on whether it's a URL, user mention or hashtag
702        getTwitterLink: function( entity ) {
703            var target = this.settings.openLinksInNewWindow === true ? 'target="_blank"' : '';
704            switch ( entity.type ) {
705                case 'urls' : 
706                    return '<a href="' + entity.url + '" ' + target + '>' + entity.display_url + '</a>';
707                    break;
708                case 'user_mentions':
709                    return '<a href="https://twitter.com/#!/' + entity.screen_name + '" ' + target + '>@' + entity.screen_name + '</a>';
710                    break;
711                case 'hashtags':
712                    return '<a href="https://twitter.com/#!/search/' + entity.text + '" ' + target + '>#' + entity.text + '</a>';                
713                    break;                
714            }
715        },
716                
717        // Default way to display time ago
718        getTimeAgo: function( date ) {
719            var now = new Date(),
720                elapsed = now.getTime() - date.getTime(), // milliseconds elapsed
721                day = 86400000,
722                minute = 60000,
723                hour = 3600000,                            
724                units,
725                timeago;
726            
727            if (elapsed < hour) {
728                units = Math.ceil( elapsed / minute);                            
729                timeago = units > 1 ? units + ' minutes ago' : units + ' minute ago';
730            } else if (elapsed < day) {
731                units = Math.ceil( elapsed / hour);                            
732                timeago = units > 1 ? units + ' hours ago' : units + ' hour ago';
733            } else {                
734                units = Math.ceil( elapsed / day);                            
735                timeago = units > 1 ? units + ' days ago' : units + ' day ago';
736            }  
737
738            return timeago;
739        },
740
741        // Default date format
742        getFormattedDate: function( date ) {
743            var date = new Date( date ),
744                months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
745
746            return date.getDate() + ' ' + months[ date.getMonth() ]; // eg. 16 Aug
747        },
748        
749        // Get newsticker list width 
750        getListWidth : function() {
751            if (this.settings.showControls) {
752                return this.dom.controls.position().left - this.dom.title.outerWidth( true );
753            }
754            else {
755                return this.dom.wrapper.width() - this.dom.title.outerWidth( true ) - 1;
756            }
757        },
758        
759        // Pause function to be executed whenever pause is initiated
760        pause : function() {            
761            if (this.settings.showControls === true) {                
762                var self = this;
763                
764                this.dom.controls.children('.pause')
765                    .removeClass('pause')
766                    .addClass('resume')
767                    .off('click', function() {
768                        self.delegate( 'pause' )
769                    })
770                    .on('click', function() {
771                        self.delegate( 'resume' )
772                    });
773            }
774        },
775
776        // Resume function to be executed whenever resume is initiated
777        resume : function() {            
778            if (this.settings.showControls === true) {                
779                var self = this;
780              
781                this.dom.controls.children('.resume')
782                    .removeClass('resume')
783                    .addClass('pause')
784                    .off('click', function() {
785                        self.delegate( 'resume' );
786                    })
787                    .on('click', function() {
788                        self.delegate( 'pause' )
789                    });
790            }
791        },
792        
793        // Handle window resizing
794        resize : function() {
795            // First try delegating the resizing to the style's resize method. If none exists, handle it ourselves
796            if (this.delegate( 'resize' ) === false) {
797                this.dom.list.width( this.api( 'getListWidth' ) );
798            }
799        }        
800    }    
801
802    // Newsticker styles collection 
803    $.fn.newsticker.styles = {
804
805        // 
806        // Fading news ticker
807        //
808        fade : {
809          
810            // Loads style-specific settings
811            settings : function() {                
812                return {
813                    'fadeOutSpeed'      : 'slow',
814                    'fadeInSpeed'       : 'slow',
815                    'transitionSpeed'   : 4000,
816                    'pauseOnHover'      : true
817                };
818            },
819            
820            // Manipulate individual list item
821            manipulateItem : function(item, is_first) {
822                var self = this;
823                
824                item.css({
825                    'position' : 'absolute',
826                    'left' : 0,
827                    'top' : 0
828                });
829                
830                if (is_first) {
831                    item.addClass('display');
832                }
833                else {
834                    item.hide();
835                }
836            },
837            
838            // Style-specific dom manipulations (see methods.mani
838pulateDom for other dom manipulations)
839            manipulateDom : function() {                          
840                this.dom.wrapper.css({'width' : '100%'});
841                this.dom.title.css({'float' : 'left', 'margin' : 0});
842                this.dom.list.css({'float' : 'left', 'width' : this.api('getListWidth') + 'px', 'position' : 'relative', 'list-style' : 'none'});                
843            },
844
845            // Loop through each individual list item
846            itemLoop : function() {
847                var is_first = true,
848                    self = this;
849
850                this.dom.items.each( function() {                    
851                    self.delegate( 'manipulateItem', $(this), is_first);
852                    is_first = false;
853                });
854            },
855
856            // Get adjacent item (either previous or next)
857            adjacentItem : function( movement ) {
858                var self = this;
859                
860                this.dom.items.each(function() {
861                    if ( $(this).hasClass('display') ) {
862                        self.delegate( 'itemTransform', $(this), movement );
863                    }
864                })
865            },
866            
867            // Item transformation (called by nextItem and previousItem)
868            // The item passed to this function is the one currently on display
869            itemTransform : function( item, movement ) {
870                // Fade out current item
871                this.delegate( 'itemFadeOut', item );
872                
873                if (movement === 'next') {                    
874                    if ( item.is('li:last-child') ) {
875                        this.delegate( 'itemFadeIn', this.dom.items.first() );
876                    }
877                    else {
878                        this.delegate( 'itemFadeIn', item.next() );
879                    }                  
880                }
881                else if (movement === 'previous') {
882                    if ( item.is('li:first-child') ) {
883                        this.delegate( 'itemFadeIn', this.dom.items.last() );
884                    }
885                    else {
886                        this.delegate( 'itemFadeIn', item.prev() );
887                    }
888                }
889            },
890            
891            // Fade item in
892            itemFadeIn : function( item ) {
893                item.fadeIn( this.settings.fadeInSpeed, function() {
894                    item.addClass('display');
895                });
896            },
897            
898            // Fade item out
899            itemFadeOut : function( item ) {
900                item.fadeOut( this.settings.fadeOutSpeed, function() {
901                    item.removeClass('display');
902                });
903            },
904
905            // Start fade action
906            start : function() {
907                var self = this;
908                
909                this.animationId = window.setInterval( function() {
910                    self.delegate( 'adjacentItem', 'next' );
911                }, this.settings.transitionSpeed)
912            },
913
914            // Pause fade
915            pause : function() {
916                clearInterval( this.animationId );
917                this.api( 'pause' );
918                return this;
919            },
920
921            // Resume fade
922            resume : function() {
923                this.delegate( 'start' );
924                this.api( 'resume' );                
925                return this;
926            },
927
928            // Next item
929            next : function() {
930                this.delegate( 'pause' )
931                    .delegate( 'adjacentItem', 'next' );
932                return this;
933            },
934
935            // Previous item
936            previous : function() {
937                this.delegate( 'pause' )
938                    .delegate( 'adjacentItem', 'previous' );
939                return this;
940            }
941            
942        },
943        
944        // 
945        // Reveal news ticker
946        //       
947        reveal : {    
948          
949            // Initialization script
950            init : function() {         
951                this.progress = {   
952                    animate : true,
953                    original : {},
954                    span : {},
955                    text : '',
956                    html: '',
957                    length : 0,
958                    i: 0,
959                    j: 0,
960                    k: 0,
961                    elements: {},
962                    nextHtml: {},
963                    nextHtmlIndex: [],
964                    nextHtmlContent : ''
965                };
966            },
967            
968            // Custom settings for this display style
969            settings : function() {     
970                return {
971                    'letterRevealSpeed'     : 70,
972                    'transitionSpeed'       : 2000,
973                    'pauseOnHover'          : false
974                };                         
975            },
976
977            getLength: function() {
978                var progress = this.progress;
979                
980                if (progress.length === 0) {
981                    progress.length = progress.text.length;
982                }
983                return progress.text.length;
984            },  
985
986            resetTicker: function( vars ) {
987                var progress = this.progress;
988                
989                progress.span = vars.span;
990                progress.elements = vars.elements;
991                progress.text = vars.text;
992                progress.html = vars.html;
993                progress.length = 0;                
994                progress.j = 0;                
995                this.delegate( 'getNextHtml' );                
996                progress.i = 0;                    
997            },
998            
999            getNextHtml: function() {
1000                var progress = this.progress;
1001                 
1002                if ( progress.elements.length <= progress.j ) {
1003                    progress.nextHtml = {};    
1004                    progress.nextHtmlIndex = [-1];
1005                }
1006                else {
1007                    progress.nextHtml = progress.elements[progress.j];                        
1008                    progress.nextHtmlIndex = progress.nextHtml.indeces;
1009                    progress.nextHtmlContent = $(progress.nextHtml).text();
1010                    progress.k = 0;
1011                }
1012            },
1013
1014            increment: function() {
1015                var self = this,
1016                    progress = self.progress;            
1017                                
1018
1019                if ( progress.nextHtmlIndex.start === progress.i ) {
1020                    clearInterval( this.animationId );
1021                    
1022                    this.animationId = window.setInterval( function() {
1023                        self.delegate( 'incrementHtml' );
1024                    }, self.settings.letterRevealSpeed );
1025                                  
1026                }                    
1027                else {
1028                    progress.span.html( progress.text.slice(0, progress.i) ); 
1029                    progress.i += 1;   
1030                }
1031            },
1032            
1033            incrementHtml: function() {                
1034                var self = this,
1035                    progress = self.progress,
1036                    text = progress.span.text,
1037                    element = $( self.delegate( 'getOuterHtml', $(progress.nextHtml) ) ),
1038                    reveal;            
1039                
1040                progress.k += 1;            
1041                
1042                reveal = progress.nextHtmlContent.slice(0, progress.k);
1043                element = $( self.delegate( 'getOuterHtml', element.children().text( reveal ) ) );
1044                
1045                progress.span.html( progress.text.slice(0, progress.i) + element.html() );
1046                
1047                if (progress.k === progress.nextHtmlIndex.length ) {
1048                    progress.i += progress.nextHtmlIndex.element.html().length;
1049                    
1050                    clearInterval( this.animationId );
1051                                    
1052                    progress.j += 1;
1053                    self.delegate( 'getNextHtml' );                                        
1054                    this.animationId = window.setInterval( function() {
1055                        self.delegate( 'revealLetter' );
1056                    }, self.settings.letterRevealSpeed );                                  
1057                }
1058            },
1059
1060            revealAll: function() {
1061                var progress = this.progress;
1062                
1063                progress.span.html( progress.html );
1064                progress.i = this.delegate( 'getLength' );  
1065            },
1066
1067            manipulateDom : function() {
1068                var self = this, 
1069                    dom = self.dom,
1070                    list = dom.list;
1071                
1072                dom.wrapper.css({'width' : '100%'});                   
1073                dom.title.css({'float' : 'left', 'overflow' : 'hidden'});                
1074                list.css({'float' : 'left', 'position' : 'relative', 'list-style' : 'none', 'margin' : 0, 'padding' : 0});
1075                list.width( this.api( 'getListWidth' ) + 'px' );
1076            },
1077            
1078            pause : function() {                              
1079                this.delegate( 'stopAnimation' );
1080                this.delegate( 'revealAll' );
1081                this.api( 'pause' );                
1082                return this;
1083            },
1084
1085            resume : function() {  
1086                var self = this, 
1087                    progress = self.progress;
1088
1089                progress.animate = true;               
1090                this.animationId = window.setTimeout( function() {
1091                    self.delegate( 'adjacentItem', 'next' );
1092                }, 50 );            
1093                self.api( 'resume' );                
1094                return self;
1095            },
1096            
1097            // Reveal adjacent item
1098            adjacent : function( side ) {              
1099                this.delegate( 'stopAnimation' );
1100                this.api( 'pause' );
1101                this.delegate( 'adjacentItem', side );
1102                this.delegate( 'revealAll' );
1103                return this;
1104            },
1105
1106            // Reveal previous item
1107            previous : function() { 
1108                return this.delegate( 'adjacent', 'previous' );                
1109            },                       
1110
1111            // Reveal next item
1112            next : function() {                
1113                return this.delegate( 'adjacent', 'next' );
1114            },
1115
1116            // Stop animation. Used by pause, previous and next methods.
1117            stopAnimation : function() {
1118                clearInterval(this.animationId);                
1119                this.progress.animate = false;
1120            },
1121
1122            // Manipulate individual list item
1123            manipulateItem : function(item, is_first) {
1124                // Give each list item position and wrap text in span
1125                item.css({'position' : 'absolute', 'left' : 0, 'top' : 0, 'z-index' : 1})
1126                    .wrapInner('<span class="original_text" />');
1127
1128                // Hide each span and make it a block element -- IE8 fix
1129                item.children('span').css({'opacity' : 0, 'display' : 'block', 'position' : 'relative', 'z-index' : 4});
1130
1131                if (is_first) {
1132                    item.addClass('revealing');
1133                }
1134            },
1135
1136            // Loop through items before animation begins
1137            itemLoop : function() {
1138                var is_first = true,
1139                    self = this,
1140                    dom = self.dom;
1141
1142                dom.items.each( function() {
1143                    self.delegate( 'manipulateItem', $(this), is_first );
1144                    is_first = false;                                                            
1145                });
1146            },                       
1147
1148            // Prepare a new item for reveal
1149            prepareItem : function() {
1150                var self = this,                    
1151                    item = self.dom.list.find('.revealing'),
1152                    progress = self.progress,
1153                    html, text;
1154
1155                if (item.children('.revealing_text').length === 0) {
1156                    item.append('<span class="revealing_text" />')
1157                        .children('.revealing_text').css({'opacity' : 1, 'position' : 'absolute', 'left' : 0, 'top' : 0});
1158                }
1159
1160                item.css({ 'z-index' : 2 });
1161                
1162                html = item.children('.original_text');
1163                text = self.delegate( 'decodeHtml', html.html() );                 
1164
1165                this.delegate( 'resetTicker', {
1166                    span : item.children('.revealing_text'),
1167                    text : text,
1168                    html : html.html(),
1169                    elements : this.delegate( 'getElements', html, text )
1170                });                         
1171
1172                if (progress.animate === true) {
1173                    self.delegate( 'animate' );
1174                }                
1175            },
1176            
1177            // Return the links within a given list item
1178            getElements : function( html, text ) {
1179                var self = this,
1180                    elements = html.children();
1181                    
1182                elements.each( function( i, element ) {
1183                    elements[i].indeces = self.delegate( 'getElement', $(element), html.html() );
1184                });                        
1185                
1186                return elements;        
1187            },
1188            
1189            // Return start point and length of HTML element
1190            getElement : function( element, original_string ) {
1191                var el = this.delegate( 'getOuterHtml', element ),
1192                    start = original_string.indexOf( el.html() ),
1193                    length = element.text().length;
1194
1195                return {
1196                    'start' : start, 
1197                    'length' : length, 
1198                    'element' : el
1199                };
1200            },
1201            
1202            // Decode HTML
1203            decodeHtml: function(string) {
1204                string = string.replace( /<script[^>]*>([\S\s]*?)<\/script>/gmi, '' );
1205                string = $("<div/>").html(string).html();
1206                return string;
1207            },
1208            
1209            // Return outer HTML
1210            // @see http://stackoverflow.com/questions/2419749/get-selected-elements-outer-html
1211            getOuterHtml : function( element ) {
1212                return element.clone().wrap('<p>').parent();
1213            },
1214
1215            // Animate
1216            animate: function() {
1217                var self = this;
1218                this.animationId = window.setInterval( function() {
1219                    self.delegate( 'revealLetter' );
1220                }, self.settings.letterRevealSpeed );
1221            },
1222
1223            // Reveal the next letter
1224            revealLetter : function() {
1225                var self = this, 
1226                    progress = self.progress;
1227
1228                self.delegate( 'increment' );
1229
1230                if ( progress.i > self.delegate( 'getLength' ) ) {
1231                    clearInterval(this.animationId);
1232                    this.animationId = window.setTimeout( function() {
1233                        self.delegate( 'adjacentItem', 'next' );
1234                    }, self.settings.transitionSpeed );
1235                }
1236            },
1237            
1238            // Adjacent item
1239            adjacentItem : function( side ) {            
1240                var dom = this.dom,
1241                    current = dom.list.find('.revealing').removeClass('revealing'),
1242                    adjacent = this.delegate( side === 'previous' ? 'getPreviousItem' : 'getNextItem', dom, current );
1243                    
1244                adjacent.addClass('revealing');
1245                current
1246                    .css({ 'z-index' : 1 })
1247                    .children('.revealing_text').text('');
1248                this.delegate( 'prepareItem' );
1249            },
1250            
1251            // Start revealing the next item
1252            getNextItem : function(dom, current) {              
1253                return ( current.is('li:last-child') ) ? dom.list.find('li:first-child') : current.next();              
1254            },
1255
1256            // Start revealing the previous item
1257            getPreviousItem : function(dom, current) {
1258                return ( current.is('li:first-child') ) ? dom.list.find('li:last-child') : current.prev();                                  
1259            },
1260
1261            // Start the animation process
1262            start : function() {
1263                if (this.settings.autoStart === true) {
1264                    this.delegate( 'prepareItem' );
1265                }                
1266            }          
1267        },
1268        
1269        // 
1270        // Scrolling news ticker
1271        //
1272        scroll : {
1273            
1274            // Initialization script
1275            init : function() {
1276                this.progress = {
1277                    autoScroll : this.settings.autoStart,
1278                    left : 0,
1279                    boundary : 0,
1280                    last : {},
1281                    current : {},
1282                    animationId : 0
1283                };
1284            },
1285
1286            // Manages the scrolling action    
1287            resetLeft : function() {
1288                this.progress.left = parseInt( this.dom.list.css('left') );
1289            },      
1290
1291            // Loads style-specific settings
1292            settings : function() {                
1293                return {
1294                    'scrollSpeed' : 50,
1295                    'slideSpeed' : 1000,
1296                    'slideEasing' : 'swing',
1297                    'pauseOnHover' : true
1298                };
1299            },
1300
1301            // Style-specific dom manipulations
1302            manipulateDom : function(is_secondary) {        
1303                var dom = this.dom,
1304                    is_secondary = typeof( is_secondary ) === 'undefined' ? false : is_secondary;
1305                
1306                if (is_secondary === false) {
1307                    dom.wrapper.css({'width' : '10000px', 'position' : 'relative'});
1308                    dom.title.css({'float' : 'left'});
1309                    dom.list.wrap('<div class="newsticker_scroller" />')
1310                            .css({'position' : 'absolute', 'left' : 10});
1311                    dom.scroller = this.dom.wrapper.children('.newsticker_scroller');
1312                }
1313                else if (is_secondary === true) {
1314                    dom.wrapper.css({'width' : '100%'});
1315                    dom.scroller.css({'position' : 'absolute', 'height' : '100%', 'overflow' : 'hidden', 'width' : this.api( 'getListWidth' )+'px', 'left' : dom.title.outerWidth(true)+'px'});
1316                }
1317            },
1318            
1319            // Individual news item dom manipulations
1320            // @return integer. Next X coordinate.
1321            manipulateItem : function( item, x ) {
1322                var width = item.css({'float' : 'left'}).outerWidth(true);                
1323                item.css({'position' : 'absolute', 'display' : 'inline', 'left' : x+'px', 'width' : width+'px'});
1324                x += width;
1325                return x;
1326            },            
1327
1328            // Set up style-specific item modifications
1329            itemLoop : function() {
1330                var self = this,
1331                    x = 0,
1332                    progress = this.progress,
1333                    dom = this.dom;
1334
1335                dom.items.each( function() {
1336                    x = self.delegate( 'manipulateItem', $(this), x );  
1337                });
1338
1339                progress.current = dom.items.first();
1340                progress.last = dom.items.last();
1341                progress.boundary = dom.items.length === 1 ? progress.current.width() : progress.current.next().position().left;
1342                
1343                self.delegate( 'manipulateDom', true );
1344            },
1345
1346            // Start -- if autoScroll is off, this does nothing
1347            start : function() {
1348                if (this.progress.autoScroll === true) {
1349                    this.delegate( 'animate' );
1350                }
1351            },
1352
1353            // Sets off the scrolling animation
1354            animate : function() {
1355                var self = this,
1356                    progress = self.progress;
1357
1358                if (progress.autoScroll === false) {
1359                    progress.autoScroll = true;
1360                }
1361
1362                progress.animationId = window.setInterval( function() {
1363                    self.delegate( 'doAnimation' );                    
1364                }, self.settings.scrollSpeed);
1365            },
1366            
1367            // Do animation
1368            doAnimation : function() {
1369                var progress = this.progress;
1370
1371                if (progress.left + progress.boundary < 0) {
1372                    this.delegate( 'nextItem' );
1373                }
1374                
1375                progress.left -= 1;
1376                this.dom.list.css({ 'left' : progress.left+'px' });                
1377            },
1378
1379            // Pause scroll
1380            pause : function() {
1381                var progress = this.progress;
1382                
1383                progress.autoScroll = false;
1384                clearInterval(progress.animationId);
1385                this.api( 'pause' );
1386                return this;
1387            },
1388
1389            // Resume scrolling
1390            resume : function() {                
1391                this.delegate( 'animate' );
1392                this.api( 'resume' );
1393                return this;
1394            },
1395
1396            // Next item -- fired by next control button
1397            next : function() {
1398                var self = this,
1399                    progress = self.progress,
1400                    settings = self.settings,
1401                    left = progress.boundary < 0 ? progress.left - progress.current.width() : '-' + progress.boundary;
1402                                    
1403                self.delegate( 'pause' );
1404                
1405                self.dom.list.animate({'left' : left + 'px'}, settings.slideSpeed, settings.slideEasing, function() {
1406                    self.delegate( 'resetLeft' );
1407                    self.delegate( 'nextItem' );
1408                });            
1409            },
1410            
1411            // Window resize
1412            resize : function() {
1413                this.dom.scroller.width( this.api( 'getListWidth' ));
1414            },
1415
1416            // Previous item -- fired by previous control button
1417            previous : function() {
1418                var self = this,
1419                    progress = self.progress,
1420                    settings = self.settings,
1421                    previous,
1422                    left;
1423
1424                self.delegate( 'pause' );
1425                
1426                previous = self.delegate( 'getPrevious' );
1427                previous.css({'left' : progress.current.position().left - parseInt( previous.width() )}); 
1428                left = previous.position().left < 0 ? (0 - previous.position().left) : '-' + previous.position().left;            
1429
1430                self.dom.list.animate({'left' : left + 'px'}, settings.slideSpeed, settings.slideEasing, function() {
1431                    self.delegate( 'resetLeft' );
1432                    self.delegate( 'previousItem', previous );
1433                });
1434            },
1435
1436            // Switch to next item
1437            nextItem : function() {
1438                var progress = this.progress,
1439                    dom = this.dom,
1440                    last = dom.items.last(),
1441                    first = dom.items.first(),
1442                    new_x = progress.last.outerWidth() + progress.last.position().left,
1443                    current = progress.current;
1444
1445                current.css({'left' : new_x+'px'});
1446
1447                if ( current.next().length === 0 ) {
1448                    progress.current = first;
1449                    progress.last = last;
1450                }                    
1451                else {
1452                    progress.current = current.next();
1453                    progress.last = progress.current.prev();                       
1454                }
1455
1456                // Set next boundary
1457                if ( progress.current.next().length === 0 ) {
1458                    progress.boundary = first.position().left;
1459                } 
1460                else {                    
1461                    progress.boundary = progress.current.next().position().left;
1462                }
1463            },
1464
1465            // Get previous item
1466            getPrevious : function() {
1467                var progress = this.progress;
1468                
1469                if (progress.current.prev().length === 0) {
1470                    return this.dom.items.last();
1471                }
1472
1473                return progress.current.prev();
1474            },
1475
1476            // Switch to previous item
1477            previousItem : function( previous ) {
1478                var progress = this.progress,
1479                    dom = this.dom;
1480                    
1481                progress.current = previous;
1482                if ( progress.current.prev().length === 0 ) {
1483                    progress.last = dom.items.last();
1484                }
1485                else {
1486                    progress.last = progress.current.prev();
1487                }
1488
1489                // Set next boundary
1490                if ( progress.current.next().length === 0) {
1491                    progress.boundary = dom.items.first().position().left;
1492                } 
1493                else {                    
1494                    progress.boundary = progress.current.next().position().left;
1495                }
1496            }                        
1497        }        
1498    }
1499})( 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.