PageSourceSearch

https://mentaleap.com/wp-content/themes/appilo/js/typeit.js?ver=6.2.1

js mentaleap.com collected 2026-10-02 16:03:19 UTC 14,225 bytes, 469 lines download raw bytes

1/**
2 * jQuery TypeIt
3 * @author Alex MacArthur (http://macarthur.me)
4 * @version 4.2.3
5 * @copyright 2016 Alex MacArthur
6 * @description Types out a given string or strings.
7 */
8
9 /* jslint browser: true */
10 /* globals jQuery:false */
11
12 (function($, undefined) {
13
14    'use strict';
15  
16    var $doc = $(document);
17  
18    $.fn.typeIt = function(opt) {
19      return this.each(function() {
20        var $t = $(this);
21        $t.data('typeit', new $.typeIt($t, opt));
22      });
23    };
24  
25    $.typeIt = function(el, opt) {
26      this.d = {
27        strings: [],
28        speed: 100,
29        deleteSpeed: undefined,
30        lifeLike: true,
31        cursor: true,
32        cursorSpeed: 1000,
33        breakLines: true,
34        breakDelay: 750,
35        startDelay: 250,
36        startDelete: false,
37        loop: false,
38        loopDelay: 750,
39        html: true,
40        autoStart: true,
41        callback: function() {}
42      };
43  
44      this.queue = [];
45      this.queueIndex = 0;
46      this.hasStarted = false;
47      this.inTag = false;
48      this.stringsToDelete = '';
49      this.style = 'style="display:inline;position:relative;font:inherit;color:inherit;"';
50      this.s = $.extend({}, this.d, opt);
51      this.el = el;
52      this._init();
53    };
54  
55    $.typeIt.prototype = {
56  
57      _init: function() {
58        this.el.find('.ti-container, .ti-cursor, .ti-placeholder').remove();
59        this._elCheck();
60        this.s.strings = this._toArray(this.s.strings);
61        this.el.html('<i class="ti-placeholder" style="display:inline-block;width:0;line-height:0;overflow:hidden;">.</i><span ' + this.style + ' class="ti-container"></span>');
62        this.tel = this.el.find('span');
63  
64        this.insert = function(c) {
65          this.tel.append(c);
66        };
67  
68        if (this.s.startDelete) {
69          this.tel.html(this.stringsToDelete);
70          this.queue.push([this.delete]);
71        }
72  
73        this._generateQueue();
74        this._kickoff();
75      },
76  
77      _kickoff: function() {
78        this._cursor();
79  
80        if (this.s.autoStart) {
81          this._startQueue();
82        } else {
83          if (this._isVisible()) {
84            this.hasStarted = true;
85            this._startQueue();
86          } else {
87            $doc.on('scroll', function() {
88              if (this._isVisible() && !this.hasStarted) {
89                this.hasStarted = true;
90                this._startQueue();
91              }
92            }.bind(this));
93          }
94        }
95      },
96  
97      _generateQueue: function() {
98        for (var i = 0; i < this.s.strings.length; i++) {
99  
100          this.queue.push([this.type, this.s.strings[i]]);
101  
102          if (i < (this.s.strings.length - 1)) {
103            var curPos = this.queue.length;
104            this.queue.push([this.s.breakLines ? this.break : this.delete]);
105  
106            if (this.s.breakLines) {
107              this.queue.splice(curPos, 0, [this.pause, this.s.breakDelay / 2]);
108              this.queue.splice(curPos + 2, 0, [this.pause, this.s.breakDelay / 2]);
109            }
110          }
111        }
112      },
113  
114      _startQueue: function() {
115        this._to(function() {
116          this._executeQueue();
117        }.bind(this), this.s.startDelay);
118      },
119  
120      /*
121        Pass in a string, and loop over that string until empty. Then return true.
122      */
123      type: function(string, rake) {
124  
125        // set default 'rake' value
126        rake = typeof rake === 'undefined' ? true : rake;
127  
128        // convert to array
129        string = this._toArray(string);
130  
131        // if it's designated, rake that bad boy for HTML tags and stuff
132        if (rake) {
133          string = this._rake(string);
134          string = string[0];
135        }
136  
137        // do the work that matters
138        this.tTO = setTimeout(function() {
139  
140          // randomize the timeout each time, if that's your thing
141          this._setPace(this);
142  
143          // "_print" the character
144          // if an opening HTML tag is found and we're not already pringing inside a tag
145          if (this.s.html && (string[0].indexOf('<') !== -1 && str
145ing[0].indexOf('</') === -1) && (!this.inTag)) {
146  
147            // loop the string to find where the tag ends
148            for (var i = string.length - 1; i >= 0; i--) {
149              if (string[i].indexOf('</') !== -1) {
150                this.tagCount = 1;
151                this.tagDuration = i;
152              }
153            }
154  
155            this._makeNode(string[0]);
156          } else {
157            this._print(string[0]);
158          }
159  
160          // shorten it
161          string.splice(0, 1);
162  
163          // if there's more to it, run again until fully printed
164          if (string.length) {
165            this.type(string, false);
166          } else {
167            this._executeQueue();
168          }
169  
170        }.bind(this), this.typePace);
171      },
172  
173      pause: function(time) {
174        time = time === undefined ? this.s.breakDelay : time;
175        this._to(function() {
176          this._executeQueue();
177        }.bind(this), time);
178      },
179  
180      break: function() {
181        this.insert('<br>');
182        this._executeQueue();
183      },
184  
185      mergeSet: function(s) {
186        this.s = $.extend({}, this.s, s);
187        this._executeQueue();
188      },
189  
190      _print: function(chr) {
191        if (this.inTag) {
192          $(this.tag, this.el).last().append(chr);
193          if (this.tagCount < this.tagDuration) {
194            this.tagCount++;
195          } else {
196            this.inTag = false;
197          }
198        } else {
199          this.insert(chr);
200        }
201      },
202  
203      /*
204      If show cursor is enabled, move array starting point for the for loop back one,
205      so that the loop will not find the closing tag and delete the cursor.
206    */
207      delete: function(chars) {
208  
209        this.dTO = setTimeout(function() {
210  
211          this._setPace();
212  
213          var a = this.tel.html().split("");
214  
215          var amount = chars === undefined || chars === null ? a.length - 1 : chars + 1;
216  
217          // cut the array by a character
218          for (var n = a.length - 1; n > -1; n--) {
219  
220            if ((a[n] === '>' || a[n] === ';') && this.s.html) {
221              for (var o = n; o > -1; o--) {
222  
223                if (a.slice(o - 3, o + 1).join('') === '<br>') {
224                  a.splice(o - 3, 4);
225                  break;
226                }
227  
228                if (a[o] === '&') {
229                  a.splice(o, n - o + 1);
230                  break;
231                }
232  
233                if (a[o] === '<') {
234                  if (a[o - 1] !== '>') {
235                    if (a[o - 1] === ';') {
236                      for (var p = o - 1; p > -1; p--) {
237                        if (a[p] === '&') {
238                          a.splice(p, o - p);
239                          break;
240                        }
241                      }
242                    }
243  
244                    a.splice(o - 1, 1);
245                    break;
246                  }
247                }
248              }
249              break;
250            } else {
251              a.pop();
252              break;
253            }
254  
255          }
256  
257          // if we've found an empty set of HTML tags...
258          if (this.tel.html().indexOf('></') > -1) {
259            for (var i = this.tel.html().indexOf('></') - 2; i >= 0; i--) {
260              if (a[i] === '<') {
261                a.splice(i, a.length - i);
262                break;
263              }
264            }
265          }
266  
267          this.tel.html(a.join(''));
268  
269          // characters still in the string.
270          if (amount > (chars === undefined ? 0 : 2)) {
271            this.delete(chars === undefined ? undefined : chars - 1);
272          } else {
273            this._executeQueue();
274          }
275        }.bind(this), this.deletePace);
276      },
277  
278      _isVisible: function() {
279        var win = $(window);
280  
281        var viewport = {
282          top: win.scrollTop(),
283          left: win.scrollLeft()
284        };
285        viewport.right = viewport.left + win.width();
286        viewport.bottom = viewport.top + win.height();
287  
288        var height = this.el.outerHeight();
289        var width = this.el.outerWidth();
290  
291        if (!width || !height) {
292          return false;
293        }
294  
295        var bounds = this.el.offset();
296        bounds.right = bounds.left + width;
297        bounds.bottom = bounds.top + height;
298  
299        var visible = (!(viewport.right < bounds.left || viewport.left >
299 bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
300  
301        if (!visible) {
302          return false;
303        }
304  
305        var deltas = {
306          top: Math.min(1, (bounds.bottom - viewport.top) / height),
307          bottom: Math.min(1, (viewport.bottom - bounds.top) / height),
308          left: Math.min(1, (bounds.right - viewport.left) / width),
309          right: Math.min(1, (viewport.right - bounds.left) / width)
310        };
311  
312        return (deltas.left * deltas.right) >= 1 && (deltas.top * deltas.bottom) >= 1;
313      },
314  
315      /* 
316        Advance the function queue to execute the next function after the previous one has finished.
317      */
318      _executeQueue: function() {
319        if (this.queueIndex < this.queue.length) {
320          var thisFunc = this.queue[this.queueIndex];
321          this.queueIndex++;
322  
323          // delay execution if looping back to the beginning of the queue.
324          if (this.isLooping && this.queueIndex === 1) {
325            this._to(function() {
326              thisFunc[0].bind(this)(thisFunc[1]);
327            }.bind(this), this.s.loopDelay / 2);
328          } else {
329            thisFunc[0].bind(this)(thisFunc[1]);
330          }
331        } else {
332          if (this.s.loop) {
333            this.queueIndex = 0;
334            this.isLooping = true;
335            this._to(function() {
336              this.delete();
337            }.bind(this), this.s.loopDelay / 2);
338          } else {
339            this.s.callback();
340          }
341        }
342      },
343  
344      _to: function(fn, time) {
345        setTimeout(function() {
346          fn();
347        }.bind(this), time);
348      },
349  
350      _elCheck: function() {
351        if (!this.s.startDelete && this.el.html().length > 0) {
352          this.s.strings = this.el.html().trim();
353        } else if (this.s.startDelete) {
354          this.stringsToDelete = this.el.html();
355        }
356      },
357  
358      _toArray: function(str) {
359        return str.constructor === Array ? str.slice(0) : str.split('<br>');
360      },
361  
362      _cursor: function() {
363        if (this.s.cursor) {
364          this.el.append('<span ' + this.style + 'class="ti-cursor">|</span>');
365          var s = this.s.cursorSpeed;
366          var t = this;
367          (function loop() {
368            t.el.find('.ti-cursor').fadeTo(s / 2, 0).fadeTo(s / 2, 1);
369            t._to(loop, s);
370          })();
371        }
372      },
373  
374      _setPace: function() {
375        var typeSpeed = this.s.speed;
376        var deleteSpeed = this.s.deleteSpeed !== undefined ? this.s.deleteSpeed : this.s.speed / 3;
377        var typeRange = typeSpeed / 2;
378        var deleteRange = deleteSpeed / 2;
379  
380        this.typePace = this.s.lifeLike ? this._randomInRange(typeSpeed, typeRange) : typeSpeed;
381        this.deletePace = this.s.lifeLike ? this._randomInRange(deleteSpeed, deleteRange) : deleteSpeed;
382      },
383  
384      _randomInRange: function(value, range) {
385        return Math.abs(Math.random() * ((value + range) - (value - range)) + (value - range));
386      },
387  
388      /*
389      Convert each string in the array to a sub-array. While happening, search the subarrays for HTML tags. 
390      When a complete tag is found, slice the subarray to get the complete tag, insert it at the correct index, 
391      and delete the range of indexes where the indexed tag used to be.
392      */
393      _rake: function(array) {
394        for (var i = 0; i < array.length; i++) {
395          array[i] = array[i].split('');
396  
397          if (this.s.html) {
398            this.tPos = [];
399            var p = this.tPos;
400            var tag;
401            var en = false;
402            for (var j = 0; j < array[i].length; j++) {
403  
404              if (array[i][j] === '<' || array[i][j] === '&') {
405                p[0] = j;
406                en = array[i][j] === '&' ? true : false;
407              }
408  
409              if (array[i][j] === '>' || (array[i][j] === ';' && en)) {
410                p[1] = j;
411                j = 0;
412                tag = (array[i].slice(p[0], p[1] + 1)).join('');
413                array[i].splice(p[0], (p[1] - p[0] + 1), tag);
414                en = false;
415              }
416            }
417          }
418        }
419  
420        return array;
421      },
422  
423      /*
424        Get the start & ending positions of the string inside HTML opening & closing angle brackets, 
425        and then create a DOM element of that string/tag name.
426      */
427      _makeNode: function(char) {
428        this.tag = $($.parseHTML(char));
429        this._print(this.tag);
430        this.inTag = true;
431      }
432    };
433  
434    $.fn.tiType = function(str) {
435      var i = $(this).data('typeit');
436      if (i === undefined) return $doc;
437      i.queue.push([i.type, str]);
438      return this;
439    };
440  
441    $.fn.tiDelete = function(num) {
442      var i = $(this).data('typeit');
443      if (i === undefined) return $doc;
444      i.queue.push([i.delete, num]);
445      return this;
446    };
447  
448    $.fn.tiPause = function(time) {
449      var i = $(this).data('typeit');
450      if (i === undefined) return $doc;
451      i.queue.push([i.pause, time]);
452      return this;
453    };
454  
455    $.fn.tiBreak = function() {
456      var i = $(this).data('typeit');
457      if (i === undefined) return $doc;
458      i.queue.push([i.break]);
459      return this;
460    };
461  
462    $.fn.tiSettings = function(settings) {
463      var i = $(this).data('typeit');
464      if (i === undefined) return $doc;
465      i.queue.push([i.mergeSet, settings]);
466      return this;
467    };
468  
469  }(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.