PluginProbe ʕ •ᴥ•ʔ
My Sticky Bar – Floating Notification Bar & Sticky Header (formerly myStickymenu) / 2.7.6
My Sticky Bar – Floating Notification Bar & Sticky Header (formerly myStickymenu) v2.7.6
2.9.1 2.9.0 2.8.9 2.8.8 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 2.0 2.0.1 2.0.3 2.0.4 2.0.5 2.0.6 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.6.6 2.6.7 2.6.8 2.6.9 2.7 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7
mystickymenu / js / mailcheck.js
mystickymenu / js Last commit date
morphext 2 years ago detectmobilebrowser.js 2 years ago iris-script.js 2 years ago jquery.email-autocomplete.js 1 year ago jquery.star-rating-svg.min.js 3 years ago mailcheck.js 1 year ago mystickymenu-admin.js 1 year ago mystickymenu.js 1 year ago mystickymenu.min.js 5 years ago select2.min.js 2 years ago slick.min.js 2 years ago welcomebar-front.js 1 year ago
mailcheck.js
313 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: ['gmail.com'],
19
20 defaultSecondLevelDomains: ["gmail"],
21
22 defaultTopLevelDomains: ["com"],
23
24 run: function(opts) {
25 opts.domains = opts.domains || Mailcheck.defaultDomains;
26 opts.secondLevelDomains = opts.secondLevelDomains || Mailcheck.defaultSecondLevelDomains;
27 opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains;
28 opts.distanceFunction = opts.distanceFunction || Mailcheck.sift4Distance;
29
30 var defaultCallback = function(result){ return result; };
31 var suggestedCallback = opts.suggested || defaultCallback;
32 var emptyCallback = opts.empty || defaultCallback;
33
34 var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.secondLevelDomains, opts.topLevelDomains, opts.distanceFunction);
35
36 return result ? suggestedCallback(result) : emptyCallback();
37 },
38
39 suggest: function(email, domains, secondLevelDomains, topLevelDomains, distanceFunction) {
40 email = email.toLowerCase();
41
42 var emailParts = this.splitEmail(email);
43
44 if (secondLevelDomains && topLevelDomains) {
45 // If the email is a valid 2nd-level + top-level, do not suggest anything.
46 if (secondLevelDomains.indexOf(emailParts.secondLevelDomain) !== -1 && topLevelDomains.indexOf(emailParts.topLevelDomain) !== -1) {
47 return false;
48 }
49 }
50
51 var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold);
52
53 if (closestDomain) {
54 if (closestDomain == emailParts.domain) {
55 // The email address exactly matches one of the supplied domains; do not return a suggestion.
56 return false;
57 } else {
58 // The email address closely matches one of the supplied domains; return a suggestion
59 return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
60 }
61 }
62
63 // The email address does not closely match one of the supplied domains
64 var closestSecondLevelDomain = this.findClosestDomain(emailParts.secondLevelDomain, secondLevelDomains, distanceFunction, this.secondLevelThreshold);
65 var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold);
66
67 if (emailParts.domain) {
68 closestDomain = emailParts.domain;
69 var rtrn = false;
70
71 if(closestSecondLevelDomain && closestSecondLevelDomain != emailParts.secondLevelDomain) {
72 // The email address may have a mispelled second-level domain; return a suggestion
73 closestDomain = closestDomain.replace(emailParts.secondLevelDomain, closestSecondLevelDomain);
74 rtrn = true;
75 }
76
77 if(closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain && emailParts.secondLevelDomain !== '') {
78 // The email address may have a mispelled top-level domain; return a suggestion
79 closestDomain = closestDomain.replace(new RegExp(emailParts.topLevelDomain + "$"), closestTopLevelDomain);
80 rtrn = true;
81 }
82
83 if (rtrn) {
84 return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
85 }
86 }
87
88 /* The email address exactly matches one of the supplied domains, does not closely
89 * match any domain and does not appear to simply have a mispelled top-level domain,
90 * or is an invalid email address; do not return a suggestion.
91 */
92 return false;
93 },
94
95 findClosestDomain: function(domain, domains, distanceFunction, threshold) {
96 threshold = threshold || this.topLevelThreshold;
97 var dist;
98 var minDist = Infinity;
99 var closestDomain = null;
100
101 if (!domain || !domains) {
102 return false;
103 }
104 if(!distanceFunction) {
105 distanceFunction = this.sift4Distance;
106 }
107
108 for (var i = 0; i < domains.length; i++) {
109 if (domain === domains[i]) {
110 return domain;
111 }
112 dist = distanceFunction(domain, domains[i]);
113 if (dist < minDist) {
114 minDist = dist;
115 closestDomain = domains[i];
116 }
117 }
118
119 if (minDist <= threshold && closestDomain !== null) {
120 return closestDomain;
121 } else {
122 return false;
123 }
124 },
125
126 sift4Distance: function(s1, s2, maxOffset) {
127 // sift4: https://siderite.blogspot.com/2014/11/super-fast-and-accurate-string-distance.html
128 if (maxOffset === undefined) {
129 maxOffset = 5; //default
130 }
131
132 if (!s1||!s1.length) {
133 if (!s2) {
134 return 0;
135 }
136 return s2.length;
137 }
138
139 if (!s2||!s2.length) {
140 return s1.length;
141 }
142
143 var l1=s1.length;
144 var l2=s2.length;
145
146 var c1 = 0; //cursor for string 1
147 var c2 = 0; //cursor for string 2
148 var lcss = 0; //largest common subsequence
149 var local_cs = 0; //local common substring
150 var trans = 0; //number of transpositions ('ab' vs 'ba')
151 var offset_arr=[]; //offset pair array, for computing the transpositions
152
153 while ((c1 < l1) && (c2 < l2)) {
154 if (s1.charAt(c1) == s2.charAt(c2)) {
155 local_cs++;
156 var isTrans=false;
157 //see if current match is a transposition
158 var i=0;
159 while (i<offset_arr.length) {
160 var ofs=offset_arr[i];
161 if (c1<=ofs.c1 || c2 <= ofs.c2) {
162 // when two matches cross, the one considered a transposition is the one with the largest difference in offsets
163 isTrans=Math.abs(c2-c1)>=Math.abs(ofs.c2-ofs.c1);
164 if (isTrans)
165 {
166 trans++;
167 } else
168 {
169 if (!ofs.trans) {
170 ofs.trans=true;
171 trans++;
172 }
173 }
174 break;
175 } else {
176 if (c1>ofs.c2 && c2>ofs.c1) {
177 offset_arr.splice(i,1);
178 } else {
179 i++;
180 }
181 }
182 }
183 offset_arr.push({
184 c1:c1,
185 c2:c2,
186 trans:isTrans
187 });
188 } else {
189 lcss+=local_cs;
190 local_cs=0;
191 if (c1!=c2) {
192 c1=c2=Math.min(c1,c2); //using min allows the computation of transpositions
193 }
194 //if matching characters are found, remove 1 from both cursors (they get incremented at the end of the loop)
195 //so that we can have only one code block handling matches
196 for (var j = 0; j < maxOffset && (c1+j<l1 || c2+j<l2); j++) {
197 if ((c1 + j < l1) && (s1.charAt(c1 + j) == s2.charAt(c2))) {
198 c1+= j-1;
199 c2--;
200 break;
201 }
202 if ((c2 + j < l2) && (s1.charAt(c1) == s2.charAt(c2 + j))) {
203 c1--;
204 c2+= j-1;
205 break;
206 }
207 }
208 }
209 c1++;
210 c2++;
211 // this covers the case where the last match is on the last token in list, so that it can compute transpositions correctly
212 if ((c1 >= l1) || (c2 >= l2)) {
213 lcss+=local_cs;
214 local_cs=0;
215 c1=c2=Math.min(c1,c2);
216 }
217 }
218 lcss+=local_cs;
219 return Math.round(Math.max(l1,l2)- lcss +trans); //add the cost of transpositions to the final result
220 },
221
222 splitEmail: function(email) {
223 email = email !== null ? (email.replace(/^\s*/, '').replace(/\s*$/, '')) : null; // trim() not exist in old IE!
224 var parts = email.split('@');
225
226 if (parts.length < 2) {
227 return false;
228 }
229
230 for (var i = 0; i < parts.length; i++) {
231 if (parts[i] === '') {
232 return false;
233 }
234 }
235
236 var domain = parts.pop();
237 var domainParts = domain.split('.');
238 var sld = '';
239 var tld = '';
240
241 if (domainParts.length === 0) {
242 // The address does not have a top-level domain
243 return false;
244 } else if (domainParts.length == 1) {
245 // The address has only a top-level domain (valid under RFC)
246 tld = domainParts[0];
247 } else {
248 // The address has a domain and a top-level domain
249 sld = domainParts[0];
250 for (var j = 1; j < domainParts.length; j++) {
251 tld += domainParts[j] + '.';
252 }
253 tld = tld.substring(0, tld.length - 1);
254 }
255
256 return {
257 topLevelDomain: tld,
258 secondLevelDomain: sld,
259 domain: domain,
260 address: parts.join('@')
261 };
262 },
263
264 // Encode the email address to prevent XSS but leave in valid
265 // characters, following this official spec:
266 // http://en.wikipedia.org/wiki/Email_address#Syntax
267 encodeEmail: function(email) {
268 var result = encodeURI(email);
269 result = result.replace('%20', ' ').replace('%25', '%').replace('%5E', '^')
270 .replace('%60', '`').replace('%7B', '{').replace('%7C', '|')
271 .replace('%7D', '}');
272 return result;
273 }
274 };
275
276 // Export the mailcheck object if we're in a CommonJS env (e.g. Node).
277 // Modeled off of Underscore.js.
278 if (typeof module !== 'undefined' && module.exports) {
279 module.exports = Mailcheck;
280 }
281
282 // Support AMD style definitions
283 // Based on jQuery (see http://stackoverflow.com/a/17954882/1322410)
284 if (typeof define === "function" && define.amd) {
285 define("mailcheck", [], function() {
286 return Mailcheck;
287 });
288 }
289
290 if (typeof window !== 'undefined' && window.jQuery) {
291 (function($){
292 $.fn.mailcheck = function(opts) {
293 var self = this;
294 if (opts.suggested) {
295 var oldSuggested = opts.suggested;
296 opts.suggested = function(result) {
297 oldSuggested(self, result);
298 };
299 }
300
301 if (opts.empty) {
302 var oldEmpty = opts.empty;
303 opts.empty = function() {
304 oldEmpty.call(null, self);
305 };
306 }
307
308 opts.email = this.val();
309 Mailcheck.run(opts);
310 };
311 })(jQuery);
312 }
313