vendor: 12,853 bytes, lines 1-301
1/*! 2 * jQuery Ticker Plugin v1.2.1 3 * https://github.com/BenjaminRH/jquery-ticker 4 * 5 * Copyright 2014 Benjamin Harris 6 * Released under the MIT license 7 */ 8(function($) { 9 10 // The ticker plugin 11 $.fn.ticker = function(options) { 12 // Extend our defaults with user-specified options 13 var opts = $.extend({}, $.fn.ticker.defaults, options); 14 15 // Handle each of the given containers 16 return this.each(function () { 17 // Setup the ticker elements 18 var tickerContainer = $(this); // Outer-most ticker container 19 var headlineContainer; // Inner headline container 20 var headlineElements = tickerContainer.find('li'); // Original headline elements 21 var headlines = []; // List of all the headlines 22 var headlineTagMap = {}; // Maps the indexes of the HTML tags in the headlines to the headline index 23 var outerTimeoutId; // Stores the outer ticker timeout id for pauses 24 var innerTimeoutId; // Stores the inner ticker timeout id for pauses 25 var currentHeadline = 0; // The index of the current headline in the list of headlines 26 var currentHeadlinePosition = 0; // The index of the current character in the current headline 27 var firstOuterTick = true; // Whether this is the first time doing the outer tick 28 var firstInnerTick = true; // Whether this is the first time doing the inner tick in this rendition of the outer one 29 30 var allowedTags = ['a', 'b', 'strong', 'span', 'i', 'em', 'u']; 31 32 if (opts.finishOnHover || opts.pauseOnHover) { 33 // Setup monitoring hover state 34 tickerContainer.removeClass('hover'); 35 tickerContainer.hover(function() { 36 $(this).toggleClass('hover'); 37 }); 38 } 39 40 // Save all the headline text 41 var h, l; 42 headlineElements.each(function (index, element) { 43 h = stripTags($(this).html(), allowedTags); // Strip all but the allowed tags 44 l = locateTags(h); // Get the locations of the allowed tags 45 h = stripTags(h); // Remove all of the HTML tags from the headline 46 headlines.push(h); // Add the headline to the headlines list 47 headlineTagMap[headlines.length - 1] = l; // Associate the tag map with the headline 48 }); 49 50 // Randomize? 51 if (opts.random) shuffleArray(headlines); 52 53 // Now delete all the elements and add the headline container 54 tickerContainer.find('ul').after('<div></div>').remove(); 55 headlineContainer = tickerContainer.find('div'); 56 57 // Function to actually do the outer ticker, and handle pausing 58 function outerTick() { 59 firstInnerTick = true; 60 61 if (firstOuterTick) { 62 firstOuterTick = false; 63 innerTick(); 64 return; 65 } 66 67 outerTimeoutId = setTimeout(function () { 68 if (opts.pauseOnHover && tickerContainer.hasClass('hover')) { 69 // User is hovering over the ticker and pause on hover is enabled 70 clearTimeout(innerTimeoutId); 71 outerTick(); 72 return; 73 } 74 75 innerTick(); 76 }, opts.itemSpeed); 77 } 78 79 // Function to handle the ticking for individual headlines 80 function innerTick() { 81 if (firstInnerTick) { 82 firstInnerTick = false; 83 tick(); 84 return; 85 } 86 87 if (currentHeadlinePosition > headlines[currentHeadline].length) { 88 advance(); 89 return; 90 } 91 92 if (opts.finishOnHover && opts.pauseOnHover && tickerContainer.hasClass('hover') && currentHeadlinePosition <= headlines[currentHeadline].length) { 93 // Let's quickly complete the headline 94 // This is outside the timeout because we want to do this instantly without the pause 95 96 // Update the text 97 headlineContainer.html(getCurrentTick()); 98 // Advance our position 99 currentHeadlinePosition += 1; 100 101 innerTick(); 102 return; 103 } 104 else { 105 // Handle as normal 106 innerTimeoutId = setTimeout(function () { 107 if (opts.pauseOnHover && tickerContainer.hasClass('hover')) { 108 // User is hovering over the ticker and pause on hover is enabled 109 clearTimeout(innerTimeoutId); 110 innerTick(); 111 return; 112 } 113 114 tick(); 115 advance(); 116 }, opts.cursorSpeed); 117 } 118 } 119 120 function advance() { 121 // Advance headline and reset character position, if it's at the end of the current headline 122 if (currentHeadlinePosition > headlines[currentHeadline].length) { // > here and not == because the ticker cursor takes an extra loop 123 currentHeadline += 1; 124 currentHeadlinePosition = 0; 125 126 // Reset the headline and character positions if we've cycled through all the headlines 127 if (currentHeadline == headlines.length) currentHeadline = 0; 128 129 // STOP! We've advanced a headline. Now we just need to pause. 130 clearTimeout(innerTimeoutId); 131 clearTimeout(outerTimeoutId); 132 outerTick(); 133 } 134 } 135 136 // Do the individual ticks 137 function tick() { 138 // Now let's update the ticker with the current tick string 139 if (currentHeadlinePosition === 0 && opts.fade) { 140 clearTimeout(innerTimeoutId); 141 142 // Animate the transition if it's enabled 143 headlineContainer.fadeOut(opts.fadeOutSpeed, function () { 144 // Now it's faded out, let's update the text 145 headlineContainer.html(getCurrentTick()); 146 // And fade in 147 headlineContainer.fadeIn(opts.fadeInSpeed, function () { 148 // Advance our position 149 currentHeadlinePosition += 1; 150 // And now we're in, let's start the thing off again without the delay 151 innerTick(); 152 }); 153 }); 154 } 155 else { 156 // Update the text 157 headlineContainer.html(getCurrentTick()); 158 // Advance our position 159 currentHeadlinePosition += 1; 160 clearTimeout(innerTimeoutId); 161 innerTick(); 162 } 163 } 164 165 // Get the current tick string 166 function getCurrentTick() { 167 var cursor, i, j, location; 168 switch (currentHeadlinePosition % 2) { 169 case 1: 170 cursor = opts.cursorOne; 171 break; 172 case 0: 173 cursor = opts.cursorTwo; 174 break; 175 } 176 177 // Don't display the cursor this was the last character of the headline 178 if (currentHeadlinePosition >= headlines[currentHeadline].length) cursor = ''; 179 180 // Generate the headline 181 var headline = ''; 182 var openedTags = []; 183 for (i = 0; i < currentHeadlinePosition; i++) { 184 location = null; 185 // Check to see if there's meant to be a tag at this index 186 for (j = 0; j < headlineTagMap[currentHeadline].length; j++) { 187 // Find a tag mapped to this location, if one exists 188 if (headlineTagMap[currentHeadline][j] && headlineTagMap[currentHeadline][j].start === i) { 189 location = headlineTagMap[currentHeadline][j]; // It does exist! 190 break; 191 } 192 } 193 194 if (location) { 195 // Add the tag to the headline 196 headline += location.tag; 197 198 // Now deal with the tag for proper HTML 199 if (! location.selfClosing) { 200 if (location.tag.charAt(1) === '/') { 201 openedTags.pop(); 202 } 203 else { 204 openedTags.push(location.name); 205 } 206 } 207 } 208 209 // Add the character to the headline 210 headline += headlines[currentHeadline][i]; 211 } 212 213 // Now close the tags, if we need to (because it hasn't finished with all the text in the tag) 214 for (i = 0; i < openedTags.length; i++) { 215 headline += '</' + openedTags[i] + '>'; 216 } 217 218 return headline + cursor; 219 } 220 221 // Start it 222 outerTick(); 223 }); 224 }; 225 226 /** 227 * Randomize array element order in-place. 228 * Using Fisher-Yates shuffle algorithm. 229 */ 230 function shuffleArray(array) { 231 for (var i = array.length - 1; i > 0; i--) { 232 var j = Math.floor(Math.random() * (i + 1)); 233 var temp = array[i]; 234 array[i] = array[j]; 235 array[j] = temp; 236 } 237 return array; 238 } 239 240 /** 241 * Strip all HTML tags from a string. 242 * An array of safe tags can be passed, which will not be 243 * stripped from the string with the rest of the tags. 244 */ 245 function stripTags(text, safeTags) { 246 safeTags = safeTags || []; 247 var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/img; 248 var comments = /<!--.*?-->/img; 249 return text.replace(comments, '').replace(tags, function (a, b) { 250 return safeTags.indexOf(b.toLowerCase()) !== -1 ? a : ''; 251 }); 252 } 253 254 /** 255 * Locates all of the requested tags in a string. 256 */ 257 function locateTags(text, tagList) { 258 tagList = tagList || []; 259 var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/im; 260 var selfClosing = /\/\s{0,}>$/m; 261 var locations = []; 262 var match, location; 263 264 while ((match = tags.exec(text)) !== null) { 265 if (tagList.length === 0 || tagList.indexOf(match[1]) !== -1) { 266 location = { 267 tag: match[0], 268 name: match[1], 269 selfClosing: selfClosing.test(match[0]), 270 start: match.index, 271 end: match.index + match[0].length - 1 272 }; 273 locations.push(location); 274 275 // Now remove this tag from the string 276 // so that each location will represent it in a string without any of the tags 277 text = text.slice(0, location.start) + text.slice(location.end + 1); 278 279 // Reset the regex 280 tags.lastIndex = 0; 281 } 282 } 283 284 return locations; 285 } 286 287 // Plugin default settings 288 $.fn.ticker.defaults = { 289 random: false, // Whether to display ticker items in a random order 290 itemSpeed: 3000, // The pause on each ticker item before being replaced 291 cursorSpeed: 10, // Speed at which the characters are typed 292 pauseOnHover: true, // Whether to pause when the mouse hovers over the ticker 293 finishOnHover: true, // Whether or not to complete the ticker item instantly when moused over 294 cursorOne: '_', // The symbol for the first part of the cursor 295 cursorTwo: '-', // The symbol for the second part of the cursor 296 fade: true, // Whether to fade between ticker items or not 297 fadeInSpeed: 600, // Speed of the fade-in animation 298 fadeOutSpeed: 300 // Speed of the fade-out animation 299 }; 300 301})(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.