1/*! 2Name: Reading Time 3Dependencies: jQuery 4Author: Michael Lynch 5Author URL: http://michaelynch.com 6Date Created: August 14, 2013 7Date Updated: April 30, 2018 8Licensed under the MIT license 9*/ 10 11;(function($) { 12 13 $.fn.readingTime = function(options) { 14 15 // define default parameters 16 const defaults = { 17 readingTimeTarget: '.eta', 18 readingTimeAsNumber: false, 19 wordCountTarget: null, 20 wordsPerMinute: 270, 21 round: true, 22 lang: 'en', 23 lessThanAMinuteString: '', 24 prependTimeString: '', 25 prependWordString: '', 26 remotePath: null, 27 remoteTarget: null, 28 success: function() {}, 29 error: function() {} 30 }; 31 32 const plugin = this; 33 const el = $(this); 34 35 let wordsPerSecond; 36 let lessThanAMinute; 37 let minShortForm; 38 39 let totalWords; 40 let totalReadingTimeSeconds; 41 42 let readingTimeMinutes; 43 let readingTimeSeconds; 44 let readingTime; 45 let readingTimeObj; 46 47 // merge defaults and options 48 plugin.settings = $.extend({}, defaults, options); 49 50 // define vars 51 const s = plugin.settings; 52 53 const setTime = function(o) { 54 55 if(o.text !== '') { 56 if (s.lang == "zh") { 57 let text = o.text.trim(); 58 // step 1: count the number of Chinese characters 59 const charArray = text.match(/[\u4e00-\u9fa5]/g);
60 let charCount = 0; 61 if (charArray != null) { 62 charCount = charArray.length; 63 } 64 // step 2: replace all the Chinese characters with blank 65 text = text.replace(/[\u4e00-\u9fa5]/g, " "); 66 // step 3:replace newlines with blank 67 text = text.replace(/[\r\n]/g, " "); 68 // step 4:replace special characters with blank 69 text = text.replace(/\W+/g, " "); 70 // step 5: count the number of total English words 71 const totalEnWords = text.trim().split(/\s+/g).length; 72 totalWords = totalEnWords + charCount; 73 } else { 74 //split text by spaces to define total words 75 totalWords = o.text.trim().split(/\s+/g).length; 76 } 77 78 //define words per second based on words per minute (s.wordsPerMinute) 79 wordsPerSecond = s.wordsPerMinute / 60; 80 81 //define total reading time in seconds 82 totalReadingTimeSeconds = totalWords / wordsPerSecond; 83 84 // define reading time 85 readingTimeMinutes = Math.floor(totalReadingTimeSeconds / 60); 86 87 // define remaining reading time seconds 88 readingTimeSeconds = Math.round(totalReadingTimeSeconds - (readingTimeMinutes * 60)); 89 90 // format reading time 91 readingTime = `${readingTimeMinutes}:${readingTimeSeconds}`; 92 // if s.round 93 if(s.round) { 94 95 // if minutes are greater than 0 96 if(readingTimeMinutes > 0) { 97 98 // set reading time by the minute 99 $(s.readingTimeTarget).text(s.prependTimeString + readingTimeMinutes + ((!s.readingTimeAsNumber) ? ' ' + minShortForm : '')); 100 101 } else { 102 103 // set reading time as less than a minute 104 $(s.readingTimeTarget).text((!s.readingTimeAsNumber) ? s.prependTimeString + lessThanAMinute : readingTimeMinutes); 105 } 106 107 } else { 108 109 // set reading time in minutes and seconds 110 $(s.readingTimeTarget).text(s.prependTimeString + readingTime); 111 } 112 113 // if word count container isn't blank or undefined 114 if(s.wordCountTarget !== '' && s.wordCountTarget !== undefined) { 115 116 // set word count 117 $(s.wordCountTarget).text(s.prependWordString + totalWords); 118 } 119 120 readingTimeObj = { 121 wpm: s.wordsPerMinute, 122 words: totalWords, 123 eta: { 124 time: readingTime, 125 minutes: readingTimeMinutes, 126 seconds: totalReadingTimeSeconds 127 } 128 }; 129 130 // run success callback 131 s.success.call(this, readingTimeObj); 132 133 } else { 134 135 // run error callback 136 s.error.call(this, { 137 error: 'The element does not contain any text' 138 }); 139 } 140 }; 141 142 // if no element was bound 143 if(!this.length) { 144 145 // run error callback 146 s.error.call(this, { 147 error: 'The element could not be found' 148 }); 149 150 // return so chained events can continue 151 return this; 152 } 153 154 // Use switch instead of ifs 155 switch (s.lang) { 156 // if s.lang is Arabic 157 case 'ar': 158 lessThanAMinute = s.lessThanAMinuteString || "Ø£Ù٠٠٠دÙÙÙØ©"; 159 minShortForm = 'دÙÙÙØ©'; 160 break; 161 // if s.lang is Czech 162 case 'cz': 163 lessThanAMinute = s.lessThanAMinuteString || "MénÄ než minutu"; 164 minShortForm = 'min'; 165 break; 166 // if s.lang is Danish 167 case 'da': 168 lessThanAMinute = s.lessThanAMinuteString || "Mindre end et minut"; 169 minShortForm = 'min'; 170 break; 171 // if s.lang is German 172 case 'de': 173 lessThanAMinute = s.lessThanAMinuteString || "Weniger als eine Minute"; 174 minShortForm = 'min'; 175 break; 176 // if s.lang is Spanish 177 case 'es': 178 lessThanAMinute = s.lessThanAMinuteString || "Menos de un minuto"; 179 minShortForm = 'min'; 180 break; 181 // if s.lang is French 182 case 'fr': 183 lessThanAMinute = s.lessThanAMinuteString || "Moins d'une minute"; 184 minShortForm = 'min'; 185 break; 186 // if s.lang is Hungarian 187 case 'hu': 188 lessThanAMinute = s.lessThanAMinuteString || "Kevesebb mint egy perc"; 189 minShortForm = 'perc'; 190 break; 191 // if s.lang is Icelandic 192 case 'is': 193 lessThanAMinute = s.lessThanAMinuteString || "Minna en eina mÃnútu"; 194 minShortForm = 'min'; 195 break; 196 // if s.lang is Italian 197 case 'it': 198 lessThanAMinute = s.lessThanAMinuteString || "Meno di un minuto"; 199 minShortForm = 'min'; 200 break; 201 // if s.lang is Dutch 202 case 'nl': 203 lessThanAMinute = s.lessThanAMinuteString || "Minder dan een minuut"; 204 minShortForm = 'min'; 205 break;
206 // if s.lang is Norwegian 207 case 'no': 208 lessThanAMinute = s.lessThanAMinuteString || "Mindre enn ett minutt"; 209 minShortForm = 'min'; 210 break; 211 // if s.lang is Polish 212 case 'pl': 213 lessThanAMinute = s.lessThanAMinuteString || "Mniej niż minutÄ"; 214 minShortForm = 'min'; 215 break; 216 // if s.lang is Russian 217 case 'ru': 218 lessThanAMinute = s.lessThanAMinuteString || "ÐенÑÑе минÑÑÑ"; 219 minShortForm = 'мин'; 220 break; 221 // if s.lang is Slovak 222 case 'sk': 223 lessThanAMinute = s.lessThanAMinuteString || "Menej než minútu"; 224 minShortForm = 'min'; 225 break; 226 // if s.lang is Swedish 227 case 'sv': 228 lessThanAMinute = s.lessThanAMinuteString || "Mindre än en minut"; 229 minShortForm = 'min'; 230 break; 231 // if s.lang is Turkish 232 case 'tr': 233 lessThanAMinute = s.lessThanAMinuteString || "Bir dakikadan az"; 234 minShortForm = 'dk'; 235 break; 236 // if s.lang is Ukrainian 237 case 'uk': 238 lessThanAMinute = s.lessThanAMinuteString || "ÐенÑе Ñ Ð²Ð¸Ð»Ð¸Ð½Ð¸"; 239 minShortForm = 'Ñ Ð²'; 240 break; 241 // if s.lang is Greek 242 case 'el': 243 lessThanAMinute = s.lessThanAMinuteString || 'ÎιγÏÏεÏο αÏÏ Î»ÎµÏÏÏ'; 244 minShortForm = 'λεÏÏά'; 245 break; 246 // if s.lang is Portuguese 247 case 'pt-BR': 248 lessThanAMinute = s.lessThanAMinuteString || 'Menos de um minuto'; 249 minShortForm = 'min'; 250 break; 251 // if s.lang is Korean 252 case 'kr': 253 lessThanAMinute = s.lessThanAMinuteString || '1ë¶ ì´í'; 254 minShortForm = 'ë¶'; 255 break; 256 // default s.lang in english 257 default: 258 lessThanAMinute = s.lessThanAMinuteString || 'Less than a minute'; 259 minShortForm = 'min'; 260 } 261 262 // for each element 263 el.each(function(index) { 264 265 // if s.remotePath and s.remoteTarget aren't null 266 if(s.remotePath != null && s.remoteTarget != null) { 267 268 // get contents of remote file 269 $.get(s.remotePath, function(data) { 270 let wrapper = document.createElement('div'); 271 272 wrapper.innerHTML = data; 273 274 // set time using the remote target found in the remote file 275 setTime({ 276 text: $(wrapper).find(s.remoteTarget).text() 277 }); 278 }); 279 280 } else { 281 282 // set time using the targeted element 283 setTime({ 284 text: el.text() 285 }); 286 } 287 }); 288 289 return true; 290 } 291})(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.