custom.js
1 year ago
folders.min.js
1 year ago
jquery.overlayscrollbars.min.js
1 year ago
jquery.star-rating-svg.min.js
1 year ago
jquery.ui.touch-punch.min.js
1 year ago
jstree.min.js
1 year ago
lottie-player.js
4 years ago
lottie-player.json
4 years ago
mailcheck.js
1 year ago
media.min.js
1 year ago
new-media.min.js
1 year ago
page-post-media.min.js
1 year ago
replace-file-name.js
1 year ago
replace-media.min.js
1 year ago
select2.min.js
1 year ago
simpledropit.min.js
1 year ago
slick.min.js
1 year ago
spectrum.min.js
2 years ago
mailcheck.js
528 lines
| 1 | /* globals define, module, jQuery */ |
| 2 | |
| 3 | /* |
| 4 | * Mailcheck https://github.com/mailcheck/mailcheck |
| 5 | * Author |
| 6 | * Derrick Ko (@derrickko) |
| 7 | * |
| 8 | * Released under the MIT License. |
| 9 | * |
| 10 | * v 1.1.2 |
| 11 | */ |
| 12 | |
| 13 | var Mailcheck = { |
| 14 | domainThreshold: 2, |
| 15 | secondLevelThreshold: 2, |
| 16 | topLevelThreshold: 2, |
| 17 | |
| 18 | defaultDomains: ['msn.com', 'bellsouth.net', |
| 19 | 'telus.net', 'comcast.net', 'optusnet.com.au', |
| 20 | 'earthlink.net', 'qq.com', 'sky.com', 'icloud.com', |
| 21 | 'mac.com', 'sympatico.ca', 'googlemail.com', |
| 22 | 'att.net', 'xtra.co.nz', 'web.de', |
| 23 | 'cox.net', 'gmail.com', 'ymail.com', |
| 24 | 'aim.com', 'rogers.com', 'verizon.net', |
| 25 | 'rocketmail.com', 'google.com', 'optonline.net', |
| 26 | 'sbcglobal.net', 'aol.com', 'me.com', 'btinternet.com', |
| 27 | 'charter.net', 'shaw.ca', 'protonmail.com'], |
| 28 | |
| 29 | defaultSecondLevelDomains: ["yahoo", "hotmail", "mail", "live", "outlook", "gmx", "ymail", "gmail", "protonmail"], |
| 30 | |
| 31 | defaultTopLevelDomains: ["com", "com.au", "com.tw", "ca", "co.nz", "co.uk", "de", |
| 32 | "fr", "it", "ru", "net", "org", "edu", "gov", "jp", "nl", "kr", "se", "eu", |
| 33 | "ie", "co.il", "us", "at", "be", "dk", "hk", "es", "gr", "ch", "no", "cz", |
| 34 | "in", "net", "net.au", "info", "biz", "mil", "co.jp", "sg", "hu", "uk", "io", "ai", "co.in"], |
| 35 | |
| 36 | run: function(opts) { |
| 37 | opts.domains = opts.domains || Mailcheck.defaultDomains; |
| 38 | opts.secondLevelDomains = opts.secondLevelDomains || Mailcheck.defaultSecondLevelDomains; |
| 39 | opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains; |
| 40 | opts.distanceFunction = opts.distanceFunction || Mailcheck.sift4Distance; |
| 41 | |
| 42 | var defaultCallback = function(result){ return result; }; |
| 43 | var suggestedCallback = opts.suggested || defaultCallback; |
| 44 | var emptyCallback = opts.empty || defaultCallback; |
| 45 | |
| 46 | var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.secondLevelDomains, opts.topLevelDomains, opts.distanceFunction); |
| 47 | |
| 48 | return result ? suggestedCallback(result) : emptyCallback(); |
| 49 | }, |
| 50 | |
| 51 | suggest: function(email, domains, secondLevelDomains, topLevelDomains, distanceFunction) { |
| 52 | email = email.toLowerCase(); |
| 53 | |
| 54 | var emailParts = this.splitEmail(email); |
| 55 | |
| 56 | if (secondLevelDomains && topLevelDomains) { |
| 57 | // If the email is a valid 2nd-level + top-level, do not suggest anything. |
| 58 | if (secondLevelDomains.indexOf(emailParts.secondLevelDomain) !== -1 && topLevelDomains.indexOf(emailParts.topLevelDomain) !== -1) { |
| 59 | return false; |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold); |
| 64 | |
| 65 | if (closestDomain) { |
| 66 | if (closestDomain == emailParts.domain) { |
| 67 | // The email address exactly matches one of the supplied domains; do not return a suggestion. |
| 68 | return false; |
| 69 | } else { |
| 70 | // The email address closely matches one of the supplied domains; return a suggestion |
| 71 | return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain }; |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | // The email address does not closely match one of the supplied domains |
| 76 | var closestSecondLevelDomain = this.findClosestDomain(emailParts.secondLevelDomain, secondLevelDomains, distanceFunction, this.secondLevelThreshold); |
| 77 | var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold); |
| 78 | |
| 79 | if (emailParts.domain) { |
| 80 | closestDomain = emailParts.domain; |
| 81 | var rtrn = false; |
| 82 | |
| 83 | if(closestSecondLevelDomain && closestSecondLevelDomain != emailParts.secondLevelDomain) { |
| 84 | // The email address may have a mispelled second-level domain; return a suggestion |
| 85 | closestDomain = closestDomain.replace(emailParts.secondLevelDomain, closestSecondLevelDomain); |
| 86 | rtrn = true; |
| 87 | } |
| 88 | |
| 89 | if(closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain && emailParts.secondLevelDomain !== '') { |
| 90 | // The email address may have a mispelled top-level domain; return a suggestion |
| 91 | closestDomain = closestDomain.replace(new RegExp(emailParts.topLevelDomain + "$"), closestTopLevelDomain); |
| 92 | rtrn = true; |
| 93 | } |
| 94 | |
| 95 | if (rtrn) { |
| 96 | return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain }; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | /* The email address exactly matches one of the supplied domains, does not closely |
| 101 | * match any domain and does not appear to simply have a mispelled top-level domain, |
| 102 | * or is an invalid email address; do not return a suggestion. |
| 103 | */ |
| 104 | return false; |
| 105 | }, |
| 106 | |
| 107 | findClosestDomain: function(domain, domains, distanceFunction, threshold) { |
| 108 | threshold = threshold || this.topLevelThreshold; |
| 109 | var dist; |
| 110 | var minDist = Infinity; |
| 111 | var closestDomain = null; |
| 112 | |
| 113 | if (!domain || !domains) { |
| 114 | return false; |
| 115 | } |
| 116 | if(!distanceFunction) { |
| 117 | distanceFunction = this.sift4Distance; |
| 118 | } |
| 119 | |
| 120 | for (var i = 0; i < domains.length; i++) { |
| 121 | if (domain === domains[i]) { |
| 122 | return domain; |
| 123 | } |
| 124 | dist = distanceFunction(domain, domains[i]); |
| 125 | if (dist < minDist) { |
| 126 | minDist = dist; |
| 127 | closestDomain = domains[i]; |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | if (minDist <= threshold && closestDomain !== null) { |
| 132 | return closestDomain; |
| 133 | } else { |
| 134 | return false; |
| 135 | } |
| 136 | }, |
| 137 | |
| 138 | sift4Distance: function(s1, s2, maxOffset) { |
| 139 | // sift4: https://siderite.blogspot.com/2014/11/super-fast-and-accurate-string-distance.html |
| 140 | if (maxOffset === undefined) { |
| 141 | maxOffset = 5; //default |
| 142 | } |
| 143 | |
| 144 | if (!s1||!s1.length) { |
| 145 | if (!s2) { |
| 146 | return 0; |
| 147 | } |
| 148 | return s2.length; |
| 149 | } |
| 150 | |
| 151 | if (!s2||!s2.length) { |
| 152 | return s1.length; |
| 153 | } |
| 154 | |
| 155 | var l1=s1.length; |
| 156 | var l2=s2.length; |
| 157 | |
| 158 | var c1 = 0; //cursor for string 1 |
| 159 | var c2 = 0; //cursor for string 2 |
| 160 | var lcss = 0; //largest common subsequence |
| 161 | var local_cs = 0; //local common substring |
| 162 | var trans = 0; //number of transpositions ('ab' vs 'ba') |
| 163 | var offset_arr=[]; //offset pair array, for computing the transpositions |
| 164 | |
| 165 | while ((c1 < l1) && (c2 < l2)) { |
| 166 | if (s1.charAt(c1) == s2.charAt(c2)) { |
| 167 | local_cs++; |
| 168 | var isTrans=false; |
| 169 | //see if current match is a transposition |
| 170 | var i=0; |
| 171 | while (i<offset_arr.length) { |
| 172 | var ofs=offset_arr[i]; |
| 173 | if (c1<=ofs.c1 || c2 <= ofs.c2) { |
| 174 | // when two matches cross, the one considered a transposition is the one with the largest difference in offsets |
| 175 | isTrans=Math.abs(c2-c1)>=Math.abs(ofs.c2-ofs.c1); |
| 176 | if (isTrans) |
| 177 | { |
| 178 | trans++; |
| 179 | } else |
| 180 | { |
| 181 | if (!ofs.trans) { |
| 182 | ofs.trans=true; |
| 183 | trans++; |
| 184 | } |
| 185 | } |
| 186 | break; |
| 187 | } else { |
| 188 | if (c1>ofs.c2 && c2>ofs.c1) { |
| 189 | offset_arr.splice(i,1); |
| 190 | } else { |
| 191 | i++; |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | offset_arr.push({ |
| 196 | c1:c1, |
| 197 | c2:c2, |
| 198 | trans:isTrans |
| 199 | }); |
| 200 | } else { |
| 201 | lcss+=local_cs; |
| 202 | local_cs=0; |
| 203 | if (c1!=c2) { |
| 204 | c1=c2=Math.min(c1,c2); //using min allows the computation of transpositions |
| 205 | } |
| 206 | //if matching characters are found, remove 1 from both cursors (they get incremented at the end of the loop) |
| 207 | //so that we can have only one code block handling matches |
| 208 | for (var j = 0; j < maxOffset && (c1+j<l1 || c2+j<l2); j++) { |
| 209 | if ((c1 + j < l1) && (s1.charAt(c1 + j) == s2.charAt(c2))) { |
| 210 | c1+= j-1; |
| 211 | c2--; |
| 212 | break; |
| 213 | } |
| 214 | if ((c2 + j < l2) && (s1.charAt(c1) == s2.charAt(c2 + j))) { |
| 215 | c1--; |
| 216 | c2+= j-1; |
| 217 | break; |
| 218 | } |
| 219 | } |
| 220 | } |
| 221 | c1++; |
| 222 | c2++; |
| 223 | // this covers the case where the last match is on the last token in list, so that it can compute transpositions correctly |
| 224 | if ((c1 >= l1) || (c2 >= l2)) { |
| 225 | lcss+=local_cs; |
| 226 | local_cs=0; |
| 227 | c1=c2=Math.min(c1,c2); |
| 228 | } |
| 229 | } |
| 230 | lcss+=local_cs; |
| 231 | return Math.round(Math.max(l1,l2)- lcss +trans); //add the cost of transpositions to the final result |
| 232 | }, |
| 233 | |
| 234 | splitEmail: function(email) { |
| 235 | email = email !== null ? (email.replace(/^\s*/, '').replace(/\s*$/, '')) : null; // trim() not exist in old IE! |
| 236 | var parts = email.split('@'); |
| 237 | |
| 238 | if (parts.length < 2) { |
| 239 | return false; |
| 240 | } |
| 241 | |
| 242 | for (var i = 0; i < parts.length; i++) { |
| 243 | if (parts[i] === '') { |
| 244 | return false; |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | var domain = parts.pop(); |
| 249 | var domainParts = domain.split('.'); |
| 250 | var sld = ''; |
| 251 | var tld = ''; |
| 252 | |
| 253 | if (domainParts.length === 0) { |
| 254 | // The address does not have a top-level domain |
| 255 | return false; |
| 256 | } else if (domainParts.length == 1) { |
| 257 | // The address has only a top-level domain (valid under RFC) |
| 258 | tld = domainParts[0]; |
| 259 | } else { |
| 260 | // The address has a domain and a top-level domain |
| 261 | sld = domainParts[0]; |
| 262 | for (var j = 1; j < domainParts.length; j++) { |
| 263 | tld += domainParts[j] + '.'; |
| 264 | } |
| 265 | tld = tld.substring(0, tld.length - 1); |
| 266 | } |
| 267 | |
| 268 | return { |
| 269 | topLevelDomain: tld, |
| 270 | secondLevelDomain: sld, |
| 271 | domain: domain, |
| 272 | address: parts.join('@') |
| 273 | }; |
| 274 | }, |
| 275 | |
| 276 | // Encode the email address to prevent XSS but leave in valid |
| 277 | // characters, following this official spec: |
| 278 | // http://en.wikipedia.org/wiki/Email_address#Syntax |
| 279 | encodeEmail: function(email) { |
| 280 | var result = encodeURI(email); |
| 281 | result = result.replace('%20', ' ').replace('%25', '%').replace('%5E', '^') |
| 282 | .replace('%60', '`').replace('%7B', '{').replace('%7C', '|') |
| 283 | .replace('%7D', '}'); |
| 284 | return result; |
| 285 | } |
| 286 | }; |
| 287 | |
| 288 | // Export the mailcheck object if we're in a CommonJS env (e.g. Node). |
| 289 | // Modeled off of Underscore.js. |
| 290 | if (typeof module !== 'undefined' && module.exports) { |
| 291 | module.exports = Mailcheck; |
| 292 | } |
| 293 | |
| 294 | // Support AMD style definitions |
| 295 | // Based on jQuery (see http://stackoverflow.com/a/17954882/1322410) |
| 296 | if (typeof define === "function" && define.amd) { |
| 297 | define("mailcheck", [], function() { |
| 298 | return Mailcheck; |
| 299 | }); |
| 300 | } |
| 301 | |
| 302 | if (typeof window !== 'undefined' && window.jQuery) { |
| 303 | (function($){ |
| 304 | $.fn.mailcheck = function(opts) { |
| 305 | var self = this; |
| 306 | if (opts.suggested) { |
| 307 | var oldSuggested = opts.suggested; |
| 308 | opts.suggested = function(result) { |
| 309 | oldSuggested(self, result); |
| 310 | }; |
| 311 | } |
| 312 | |
| 313 | if (opts.empty) { |
| 314 | var oldEmpty = opts.empty; |
| 315 | opts.empty = function() { |
| 316 | oldEmpty.call(null, self); |
| 317 | }; |
| 318 | } |
| 319 | |
| 320 | opts.email = this.val(); |
| 321 | Mailcheck.run(opts); |
| 322 | }; |
| 323 | })(jQuery); |
| 324 | } |
| 325 | |
| 326 | /* |
| 327 | * email-autocomplete - 0.1.3 |
| 328 | * jQuery plugin that displays in-place autocomplete suggestions for email input fields. |
| 329 | * |
| 330 | * |
| 331 | * Made by Low Yong Zhen <yz@stargate.io> |
| 332 | */ |
| 333 | "use strict"; |
| 334 | |
| 335 | (function ($, window, document, undefined) { |
| 336 | |
| 337 | var pluginName = "emailautocomplete"; |
| 338 | var defaults = { |
| 339 | suggClass: "eac-sugg", |
| 340 | domains: ["yahoo.com" ,"hotmail.com" ,"gmail.com" ,"me.com" ,"aol.com" ,"mac.com" ,"live.com" ,"comcast.net" ,"googlemail.com" ,"msn.com" ,"hotmail.co.uk" ,"yahoo.com" ,"facebook.com" ,"verizon.net" ,"sbcglobal.net" ,"att.net" ,"gmx.com" ,"outlook.com" ,"icloud.com", "premio.io", "protonmail.com"] |
| 341 | }; |
| 342 | |
| 343 | function EmailAutocomplete(elem, options) { |
| 344 | this.$field = $(elem); |
| 345 | this.options = $.extend(true, {}, defaults, options); //we want deep extend |
| 346 | this._defaults = defaults; |
| 347 | this._domains = this.options.domains; |
| 348 | this.init(); |
| 349 | } |
| 350 | |
| 351 | EmailAutocomplete.prototype = { |
| 352 | init: function () { |
| 353 | |
| 354 | //shim indexOf |
| 355 | if (!Array.prototype.indexOf) { |
| 356 | this.doIndexOf(); |
| 357 | } |
| 358 | |
| 359 | //this will be calculated upon keyup |
| 360 | this.fieldLeftOffset = null; |
| 361 | |
| 362 | //wrap our field |
| 363 | var $wrap = $("<div class='eac-input-wrap' />").css({ |
| 364 | display: this.$field.css("display"), |
| 365 | position: this.$field.css("position") === 'static' ? 'relative' : this.$field.css("position"), |
| 366 | fontSize: this.$field.css("fontSize") |
| 367 | }); |
| 368 | this.$field.wrap($wrap); |
| 369 | |
| 370 | //create container to test width of current val |
| 371 | this.$cval = $("<span class='eac-cval' />").css({ |
| 372 | visibility: "hidden", |
| 373 | position: "absolute", |
| 374 | display: "inline-block", |
| 375 | fontFamily: this.$field.css("fontFamily"), |
| 376 | fontWeight: this.$field.css("fontWeight"), |
| 377 | letterSpacing: this.$field.css("letterSpacing") |
| 378 | }).insertAfter(this.$field); |
| 379 | |
| 380 | //create the suggestion overlay |
| 381 | /* touchstart jquery 1.7+ */ |
| 382 | var heightPad = (this.$field.outerHeight(true) - this.$field.height()) / 2; //padding+border |
| 383 | this.$suggOverlay = $("<span class='"+this.options.suggClass+"' />").css({ |
| 384 | display: "block", |
| 385 | "box-sizing": "content-box", //standardize |
| 386 | lineHeight: this.$field.css('lineHeight'), |
| 387 | paddingTop: heightPad + "px", |
| 388 | paddingBottom: heightPad + "px", |
| 389 | fontFamily: this.$field.css("fontFamily"), |
| 390 | fontWeight: this.$field.css("fontWeight"), |
| 391 | letterSpacing: this.$field.css("letterSpacing"), |
| 392 | position: "absolute", |
| 393 | top: 0, |
| 394 | left: 0 |
| 395 | }).insertAfter(this.$field); |
| 396 | |
| 397 | //bind events and handlers |
| 398 | this.$field.on("keyup.eac", $.proxy(this.displaySuggestion, this)); |
| 399 | |
| 400 | this.$field.on("blur.eac", $.proxy(this.autocomplete, this)); |
| 401 | |
| 402 | this.$field.on("keydown.eac", $.proxy(function(e){ |
| 403 | if(e.which === 39 || e.which === 9 || e.which === 32 || e.which === 13){ |
| 404 | this.autocomplete(); |
| 405 | } |
| 406 | if ( e.which === 9 && !this.$field.hasClass('email-focus')) { |
| 407 | this.$field.addClass('email-focus'); |
| 408 | e.preventDefault(); |
| 409 | }else { |
| 410 | if ( e.which === 32 ){ |
| 411 | e.preventDefault(); |
| 412 | } |
| 413 | this.$field.removeClass('email-focus'); |
| 414 | } |
| 415 | }, this)); |
| 416 | this.$field.on("click", $.proxy(function(e){ |
| 417 | this.autocomplete(); |
| 418 | }, this)); |
| 419 | |
| 420 | this.$suggOverlay.on("mousedown.eac touchstart.eac", $.proxy(this.autocomplete, this)); |
| 421 | }, |
| 422 | |
| 423 | suggest: function (str) { |
| 424 | str = $.trim(str.toLowerCase()); |
| 425 | var str_arr = str.split("@"); |
| 426 | if (str_arr.length > 1) { |
| 427 | str = str_arr.pop(); |
| 428 | if (!str.length) { |
| 429 | return ""; |
| 430 | } |
| 431 | } else { |
| 432 | return ""; |
| 433 | } |
| 434 | var match = this._domains.filter(function (domain) { |
| 435 | return domain.indexOf(str) === 0; |
| 436 | }).shift() || ""; |
| 437 | |
| 438 | return match.replace(str, ""); |
| 439 | }, |
| 440 | |
| 441 | autocomplete: function () { |
| 442 | if(typeof this.suggestion === "undefined" || this.suggestion.length < 1){ |
| 443 | return false; |
| 444 | } |
| 445 | |
| 446 | this.$field.val(this.val + this.suggestion); |
| 447 | this.$suggOverlay.text(""); |
| 448 | this.$cval.text(""); |
| 449 | }, |
| 450 | |
| 451 | /** |
| 452 | * Displays the suggestion, handler for field keyup event |
| 453 | */ |
| 454 | displaySuggestion: function (e) { |
| 455 | this.val = this.$field.val(); |
| 456 | this.suggestion = this.suggest(this.val); |
| 457 | |
| 458 | if (!this.suggestion.length) { |
| 459 | this.$suggOverlay.text(""); |
| 460 | } else { |
| 461 | e.preventDefault(); |
| 462 | } |
| 463 | |
| 464 | //update with new suggestion |
| 465 | this.$suggOverlay.text(this.suggestion); |
| 466 | this.$cval.text(this.val); |
| 467 | |
| 468 | // get input padding, border and margin to offset text |
| 469 | if(this.fieldLeftOffset === null){ |
| 470 | this.fieldLeftOffset = (this.$field.outerWidth(true) - this.$field.width()) / 2; |
| 471 | } |
| 472 | |
| 473 | //find width of current input val so we can offset the suggestion text |
| 474 | var cvalWidth = this.$cval.width(); |
| 475 | |
| 476 | if(this.$field.outerWidth() > cvalWidth){ |
| 477 | //offset our suggestion container |
| 478 | this.$suggOverlay.css('left', this.fieldLeftOffset + cvalWidth + "px"); |
| 479 | } |
| 480 | }, |
| 481 | |
| 482 | /** |
| 483 | * indexof polyfill |
| 484 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Polyfill |
| 485 | */ |
| 486 | doIndexOf: function(){ |
| 487 | |
| 488 | Array.prototype.indexOf = function (searchElement, fromIndex) { |
| 489 | if ( this === undefined || this === null ) { |
| 490 | throw new TypeError( '"this" is null or not defined' ); |
| 491 | } |
| 492 | |
| 493 | var length = this.length >>> 0; // Hack to convert object.length to a UInt32 |
| 494 | |
| 495 | fromIndex = +fromIndex || 0; |
| 496 | |
| 497 | if (Math.abs(fromIndex) === Infinity) { |
| 498 | fromIndex = 0; |
| 499 | } |
| 500 | |
| 501 | if (fromIndex < 0) { |
| 502 | fromIndex += length; |
| 503 | if (fromIndex < 0) { |
| 504 | fromIndex = 0; |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | for (;fromIndex < length; fromIndex++) { |
| 509 | if (this[fromIndex] === searchElement) { |
| 510 | return fromIndex; |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | return -1; |
| 515 | }; |
| 516 | } |
| 517 | }; |
| 518 | |
| 519 | $.fn[pluginName] = function (options) { |
| 520 | return this.each(function () { |
| 521 | if (!$.data(this, "yz_" + pluginName)) { |
| 522 | $.data(this, "yz_" + pluginName, new EmailAutocomplete(this, options)); |
| 523 | } |
| 524 | }); |
| 525 | }; |
| 526 | |
| 527 | })(jQuery, window, document); |
| 528 |