From 7655aabfd58c9a7030fd234770a367b9387c50f7 Mon Sep 17 00:00:00 2001 From: Alex MacArthur Date: Sun, 1 Apr 2018 21:42:37 -0500 Subject: [PATCH] Fix bug causing incorrect handling of HTML vs. plain text. --- dist/typeit.es.js | 57 +- dist/typeit.js | 1331 ++++++++++++++++++++++---------------------- dist/typeit.min.js | 4 +- package.json | 8 +- sandbox.html | 7 +- src/instance.js | 52 +- yarn.lock | 1257 +++++++++++++++++++++++++++++------------ 7 files changed, 1641 insertions(+), 1075 deletions(-) diff --git a/dist/typeit.es.js b/dist/typeit.es.js index a3a6cbfb..b42b8368 100644 --- a/dist/typeit.es.js +++ b/dist/typeit.es.js @@ -2,7 +2,7 @@ * * typeit - The most versatile animated typing utility on the planet. * Author: Alex MacArthur (https://macarthur.me) - * Version: v5.6.0 + * Version: v5.6.1 * URL: https://typeitjs.com * License: GPL-2.0 * @@ -94,16 +94,6 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - - - - - - - - - - var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); @@ -149,11 +139,37 @@ var Instance = function () { } /** - * Based on options, set the before and after values for the delay that is inserted when typing new strings. + * If argument is passed, set to content according to `html` option. + * If not, just return the contents of the element, based on `html` option. + * @param {string | null} content */ createClass(Instance, [{ + key: "contents", + value: function contents() { + var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + //-- Just return the contents of the element. + if (content === null) { + return this.options.html ? this.elementContainer.innerHTML : this.elementContainer.innerText; + } + + //-- Reset the contents of the element. + if (this.options.html) { + this.elementContainer.innerHTML = content; + } else { + this.elementContainer.innerText = content; + } + + return content; + } + + /** + * Based on options, set the before and after values for the delay that is inserted when typing new strings. + */ + + }, { key: "setNextStringDelay", value: function setNextStringDelay() { var isArray = Array.isArray(this.options.nextStringDelay); @@ -372,8 +388,7 @@ var Instance = function () { this.elementContainer.insertAdjacentHTML("beforeend", content); } - //-- Split & rejoin to avoid odd spacing issues in some browsers. - this.elementContainer.innerHTML = this.elementContainer.innerHTML.split("").join(""); + this.contents(this.contents().split("").join("")); } /** @@ -520,7 +535,7 @@ var Instance = function () { this.timeouts[1] = setTimeout(function () { _this6.setPace(); - var textArray = _this6.elementContainer.innerHTML.split(""); + var textArray = _this6.contents().split(""); //-- Cut the array by a character. for (var n = textArray.length - 1; n > -1; n--) { @@ -560,8 +575,8 @@ var Instance = function () { } //-- If we've found an empty set of HTML tags... - if (_this6.elementContainer.innerHTML.indexOf("> -1) { - for (var i = _this6.elementContainer.innerHTML.indexOf(">= 0; i--) { + if (_this6.options.html && _this6.contents().indexOf("> -1) { + for (var i = _this6.contents().indexOf(">= 0; i--) { if (textArray[i] === "<") { textArray.splice(i, textArray.length - i); break; @@ -573,7 +588,7 @@ var Instance = function () { //-- We want do strip empty tags here and ONLY here because when we're //-- typing new content inside an HTML tag, there is momentarily an empty //-- tag we want to keep. - _this6.elementContainer.innerHTML = textArray.join("").replace(/<[^\/>][^>]*><\/[^>]+>/, ""); + _this6.contents(textArray.join("").replace(/<[^\/>][^>]*><\/[^>]+>/, "")); //-- Delete again! Don't call directly, to respect possible pauses. if (chars === null) { @@ -595,7 +610,7 @@ var Instance = function () { }, { key: "empty", value: function empty() { - this.elementContainer.innerHTML = ""; + this.contents(""); this.next(); } }, { @@ -639,11 +654,11 @@ var Instance = function () { } if (this.options.afterComplete) { - this.options.afterComplete(this.step, this.typeit); + this.options.afterComplete(this.typeit); } if (this.options.loop) { - this.queueDeletions(this.elementContainer.innerHTML); + this.queueDeletions(this.contents()); this.generateQueue([this.pause, this.options.loopDelay / 2]); setTimeout(function () { diff --git a/dist/typeit.js b/dist/typeit.js index 29ff56b5..c26f44ca 100644 --- a/dist/typeit.js +++ b/dist/typeit.js @@ -2,835 +2,850 @@ * * typeit - The most versatile animated typing utility on the planet. * Author: Alex MacArthur (https://macarthur.me) - * Version: v5.6.0 + * Version: v5.6.1 * URL: https://typeitjs.com * License: GPL-2.0 * */ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.TypeIt = factory()); + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.TypeIt = factory()); }(this, (function () { 'use strict'; -window.TypeItDefaults = { - strings: [], - speed: 100, - deleteSpeed: null, - lifeLike: true, - cursor: true, - cursorChar: "|", - cursorSpeed: 1000, - breakLines: true, - startDelay: 250, - startDelete: false, - nextStringDelay: 750, - loop: false, - loopDelay: 750, - html: true, - autoStart: true, - callback: false, - beforeString: false, - afterString: false, - beforeStep: false, - afterStep: false, - afterComplete: false -}; - -function isVisible(element) { - var coordinates = element.getBoundingClientRect(); - - //-- Element extends past bottom or right. - if (coordinates.right > window.innerWidth || coordinates.bottom > window.innerHeight) { - return false; - } + window.TypeItDefaults = { + strings: [], + speed: 100, + deleteSpeed: null, + lifeLike: true, + cursor: true, + cursorChar: "|", + cursorSpeed: 1000, + breakLines: true, + startDelay: 250, + startDelete: false, + nextStringDelay: 750, + loop: false, + loopDelay: 750, + html: true, + autoStart: true, + callback: false, + beforeString: false, + afterString: false, + beforeStep: false, + afterStep: false, + afterComplete: false + }; + + function isVisible(element) { + var coordinates = element.getBoundingClientRect(); + + //-- Element extends past bottom or right. + if (coordinates.right > window.innerWidth || coordinates.bottom > window.innerHeight) { + return false; + } + + //-- Element extends past top or left. + if (coordinates.top < 0 || coordinates.left < 0) { + return false; + } - //-- Element extends past top or left. - if (coordinates.top < 0 || coordinates.left < 0) { - return false; + return true; } - return true; -} + function randomInRange(value, range) { + return Math.abs(Math.random() * (value + range - (value - range)) + (value - range)); + } -function randomInRange(value, range) { - return Math.abs(Math.random() * (value + range - (value - range)) + (value - range)); -} + function removeComments(arrayOfStrings) { + return arrayOfStrings.map(function (string) { + return string.replace(/<\!--.*?-->/g, ""); + }); + } -function removeComments(arrayOfStrings) { - return arrayOfStrings.map(function (string) { - return string.replace(/<\!--.*?-->/g, ""); - }); -} + function startsWith(string, search) { + return string.indexOf(search) === 0; + } -function startsWith(string, search) { - return string.indexOf(search) === 0; -} + function toArray(string) { + return Array.isArray(string) ? string.slice(0) : string.split("
"); + } -function toArray(string) { - return Array.isArray(string) ? string.slice(0) : string.split("
"); -} + function groupHTMLTags(arr) { + var tPosition = []; + var tag = void 0; + var isEntity = false; -function groupHTMLTags(arr) { - var tPosition = []; - var tag = void 0; - var isEntity = false; + for (var j = 0; j < arr.length; j++) { + if (arr[j] === "<" || arr[j] === "&") { + tPosition[0] = j; + isEntity = arr[j] === "&"; + } - for (var j = 0; j < arr.length; j++) { - if (arr[j] === "<" || arr[j] === "&") { - tPosition[0] = j; - isEntity = arr[j] === "&"; + if (arr[j] === ">" || arr[j] === ";" && isEntity) { + tPosition[1] = j; + j = 0; + tag = arr.slice(tPosition[0], tPosition[1] + 1).join(""); + arr.splice(tPosition[0], tPosition[1] - tPosition[0] + 1, tag); + isEntity = false; + } } - if (arr[j] === ">" || arr[j] === ";" && isEntity) { - tPosition[1] = j; - j = 0; - tag = arr.slice(tPosition[0], tPosition[1] + 1).join(""); - arr.splice(tPosition[0], tPosition[1] - tPosition[0] + 1, tag); - isEntity = false; - } + return arr; } - return arr; -} + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; -} : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; -}; + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + var Instance = function () { + function Instance(element, id, options, typeit) { + classCallCheck(this, Instance); + + this.typeit = typeit; + this.timeouts = []; + this.id = id; + this.queue = []; + this.hasStarted = false; + this.isFrozen = false; + this.isComplete = false; + this.isInTag = false; + this.stringsToDelete = ""; + this.style = "display:inline;position:relative;font:inherit;color:inherit;"; + this.element = element; + this.setOptions(options, window.TypeItDefaults, false); + this.setNextStringDelay(); + this.init(); + } + /** + * If argument is passed, set to content according to `html` option. + * If not, just return the contents of the element, based on `html` option. + * @param {string | null} content + */ + createClass(Instance, [{ + key: "contents", + value: function contents() { + var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + //-- Just return the contents of the element. + if (content === null) { + return this.options.html ? this.elementContainer.innerHTML : this.elementContainer.innerText; + } + //-- Reset the contents of the element. + if (this.options.html) { + this.elementContainer.innerHTML = content; + } else { + this.elementContainer.innerText = content; + } + return content; + } + /** + * Based on options, set the before and after values for the delay that is inserted when typing new strings. + */ + }, { + key: "setNextStringDelay", + value: function setNextStringDelay() { + var isArray = Array.isArray(this.options.nextStringDelay); -var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -}; - -var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } + var halfDelay = !isArray ? this.options.nextStringDelay / 2 : null; - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; -}(); - -var Instance = function () { - function Instance(element, id, options, typeit) { - classCallCheck(this, Instance); - - this.typeit = typeit; - this.timeouts = []; - this.id = id; - this.queue = []; - this.hasStarted = false; - this.isFrozen = false; - this.isComplete = false; - this.isInTag = false; - this.stringsToDelete = ""; - this.style = "display:inline;position:relative;font:inherit;color:inherit;"; - this.element = element; - this.setOptions(options, window.TypeItDefaults, false); - this.setNextStringDelay(); - this.init(); - } + this.options.nextStringDelay = { + before: isArray ? this.options.nextStringDelay[0] : halfDelay, + after: isArray ? this.options.nextStringDelay[1] : halfDelay, + total: isArray ? this.options.nextStringDelay.reduce(function (accumulator, currentValue) { + return accumulator + currentValue; + }) : this.options.nextStringDelay + }; + } + }, { + key: "init", + value: function init() { + this.checkElement(); - /** - * Based on options, set the before and after values for the delay that is inserted when typing new strings. - */ + this.options.strings = toArray(this.options.strings); + this.options.strings = removeComments(this.options.strings); + //-- We don't have anything. Get out of here. + if (this.options.strings.length >= 1 && this.options.strings[0] === "") { + return; + } - createClass(Instance, [{ - key: "setNextStringDelay", - value: function setNextStringDelay() { - var isArray = Array.isArray(this.options.nextStringDelay); + this.element.innerHTML = "\n \n "; - var halfDelay = !isArray ? this.options.nextStringDelay / 2 : null; + this.element.setAttribute("data-typeitid", this.id); + this.elementContainer = this.element.querySelector("span"); - this.options.nextStringDelay = { - before: isArray ? this.options.nextStringDelay[0] : halfDelay, - after: isArray ? this.options.nextStringDelay[1] : halfDelay, - total: isArray ? this.options.nextStringDelay.reduce(function (accumulator, currentValue) { - return accumulator + currentValue; - }) : this.options.nextStringDelay - }; - } - }, { - key: "init", - value: function init() { - this.checkElement(); + if (this.options.startDelete) { + this.insert(this.stringsToDelete); + this.queue.push([this.delete]); + this.insertSplitPause(1); + } - this.options.strings = toArray(this.options.strings); - this.options.strings = removeComments(this.options.strings); + this.cursor(); + this.generateQueue(); - //-- We don't have anything. Get out of here. - if (this.options.strings.length >= 1 && this.options.strings[0] === "") { - return; + this.kickoff(); } + }, { + key: "generateQueue", + value: function generateQueue() { + var _this = this; - this.element.innerHTML = "\n \n "; + var initialStep = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - this.element.setAttribute("data-typeitid", this.id); - this.elementContainer = this.element.querySelector("span"); + initialStep = initialStep === null ? [this.pause, this.options.startDelay] : initialStep; - if (this.options.startDelete) { - this.insert(this.stringsToDelete); - this.queue.push([this.delete]); - this.insertSplitPause(1); - } + this.queue.push(initialStep); - this.cursor(); - this.generateQueue(); + this.options.strings.forEach(function (string, index) { + _this.queueString(string); - this.kickoff(); - } - }, { - key: "generateQueue", - value: function generateQueue() { - var _this = this; + //-- This is the last string. Get outta here. + if (index + 1 === _this.options.strings.length) return; - var initialStep = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + if (_this.options.breakLines) { + _this.queue.push([_this.break]); + _this.insertSplitPause(_this.queue.length); + return; + } - initialStep = initialStep === null ? [this.pause, this.options.startDelay] : initialStep; + _this.queueDeletions(string); + _this.insertSplitPause(_this.queue.length, string.length); + }); + } - this.queue.push(initialStep); + /** + * Delete each character from a string. + */ - this.options.strings.forEach(function (string, index) { - _this.queueString(string); + }, { + key: "queueDeletions", + value: function queueDeletions() { + var stringOrNumber = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - //-- This is the last string. Get outta here. - if (index + 1 === _this.options.strings.length) return; + var number = typeof stringOrNumber === "string" ? stringOrNumber.length : stringOrNumber; - if (_this.options.breakLines) { - _this.queue.push([_this.break]); - _this.insertSplitPause(_this.queue.length); - return; + for (var i = 0; i < number; i++) { + this.queue.push([this.delete, 1]); } + } - _this.queueDeletions(string); - _this.insertSplitPause(_this.queue.length, string.length); - }); - } + /** + * Add steps to the queue for each character in a given string. + */ - /** - * Delete each character from a string. - */ + }, { + key: "queueString", + value: function queueString(string) { + var rake = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - }, { - key: "queueDeletions", - value: function queueDeletions() { - var stringOrNumber = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + if (!string) return; - var number = typeof stringOrNumber === "string" ? stringOrNumber.length : stringOrNumber; + string = toArray(string); - for (var i = 0; i < number; i++) { - this.queue.push([this.delete, 1]); - } - } + var doc = document.implementation.createHTMLDocument(""); + doc.body.innerHTML = string; - /** - * Add steps to the queue for each character in a given string. - */ + //-- If it's designated, rake that bad boy for HTML tags and stuff. + if (rake) { + string = this.rake(string); + string = string[0]; + } - }, { - key: "queueString", - value: function queueString(string) { - var rake = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + //-- If an opening HTML tag is found and we're not already printing inside a tag + if (this.options.html && startsWith(string[0], "<") && !startsWith(string[0], "/); + var _doc = document.implementation.createHTMLDocument(""); + _doc.body.innerHTML = "<" + matches[1] + ">"; + + //-- Add to the queue. + this.queue.push([this.type, _doc.body.children[0]]); + } else { + this.queue.push([this.type, string[0]]); + } - if (!string) return; + //-- Shorten it by one character. + string.splice(0, 1); - string = toArray(string); + //-- If rake is true, this is the first time we've queued this string. + if (rake) { + this.queue[this.queue.length - 1].push("first-of-string"); + } - var doc = document.implementation.createHTMLDocument(""); - doc.body.innerHTML = string; + //-- If there's more to it, run again until fully printed. + if (string.length) { + this.queueString(string, false); + return; + } - //-- If it's designated, rake that bad boy for HTML tags and stuff. - if (rake) { - string = this.rake(string); - string = string[0]; + //-- End of string! + this.queue[this.queue.length - 1].push("last-of-string"); } - //-- If an opening HTML tag is found and we're not already printing inside a tag - if (this.options.html && startsWith(string[0], "<") && !startsWith(string[0], "/); - var _doc = document.implementation.createHTMLDocument(""); - _doc.body.innerHTML = "<" + matches[1] + ">"; - - //-- Add to the queue. - this.queue.push([this.type, _doc.body.children[0]]); - } else { - this.queue.push([this.type, string[0]]); + /** + * Insert a split pause around a range of queue items. + * + * @param {Number} startPosition The position at which to start wrapping. + * @param {Number} numberOfActionsToWrap The number of actions in the queue to wrap. + * @return {void} + */ + + }, { + key: "insertSplitPause", + value: function insertSplitPause(startPosition) { + var numberOfActionsToWrap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + this.queue.splice(startPosition, 0, [this.pause, this.options.nextStringDelay.before]); + this.queue.splice(startPosition - numberOfActionsToWrap, 0, [this.pause, this.options.nextStringDelay.after]); } + }, { + key: "kickoff", + value: function kickoff() { + if (this.options.autoStart) { + this.hasStarted = true; + this.next(); + return; + } - //-- Shorten it by one character. - string.splice(0, 1); + if (isVisible(this.element)) { + this.hasStarted = true; + this.next(); + return; + } - //-- If rake is true, this is the first time we've queued this string. - if (rake) { - this.queue[this.queue.length - 1].push("first-of-string"); - } + var that = this; - //-- If there's more to it, run again until fully printed. - if (string.length) { - this.queueString(string, false); - return; + window.addEventListener("scroll", function checkForStart(event) { + if (isVisible(that.element) && !that.hasStarted) { + that.hasStarted = true; + that.next(); + event.currentTarget.removeEventListener(event.type, checkForStart); + } + }); } + }, { + key: "cursor", + value: function cursor() { + var visibilityStyle = "visibility: hidden;"; - //-- End of string! - this.queue[this.queue.length - 1].push("last-of-string"); - } + if (this.options.cursor) { + var styleBlock = document.createElement("style"); - /** - * Insert a split pause around a range of queue items. - * - * @param {Number} startPosition The position at which to start wrapping. - * @param {Number} numberOfActionsToWrap The number of actions in the queue to wrap. - * @return {void} - */ + styleBlock.id = this.id; - }, { - key: "insertSplitPause", - value: function insertSplitPause(startPosition) { - var numberOfActionsToWrap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + var styles = "\n @keyframes blink-" + this.id + " {\n 0% {opacity: 0}\n 49% {opacity: 0}\n 50% {opacity: 1}\n }\n\n [data-typeitid='" + this.id + "'] .ti-cursor {\n animation: blink-" + this.id + " " + this.options.cursorSpeed / 1000 + "s infinite;\n }\n "; - this.queue.splice(startPosition, 0, [this.pause, this.options.nextStringDelay.before]); - this.queue.splice(startPosition - numberOfActionsToWrap, 0, [this.pause, this.options.nextStringDelay.after]); - } - }, { - key: "kickoff", - value: function kickoff() { - if (this.options.autoStart) { - this.hasStarted = true; - this.next(); - return; - } + styleBlock.appendChild(document.createTextNode(styles)); - if (isVisible(this.element)) { - this.hasStarted = true; - this.next(); - return; - } - - var that = this; + document.head.appendChild(styleBlock); - window.addEventListener("scroll", function checkForStart(event) { - if (isVisible(that.element) && !that.hasStarted) { - that.hasStarted = true; - that.next(); - event.currentTarget.removeEventListener(event.type, checkForStart); + visibilityStyle = ""; } - }); - } - }, { - key: "cursor", - value: function cursor() { - var visibilityStyle = "visibility: hidden;"; - - if (this.options.cursor) { - var styleBlock = document.createElement("style"); - - styleBlock.id = this.id; - - var styles = "\n @keyframes blink-" + this.id + " {\n 0% {opacity: 0}\n 49% {opacity: 0}\n 50% {opacity: 1}\n }\n\n [data-typeitid='" + this.id + "'] .ti-cursor {\n animation: blink-" + this.id + " " + this.options.cursorSpeed / 1000 + "s infinite;\n }\n "; - - styleBlock.appendChild(document.createTextNode(styles)); - document.head.appendChild(styleBlock); - - visibilityStyle = ""; + this.element.insertAdjacentHTML("beforeend", "" + this.options.cursorChar + ""); } - this.element.insertAdjacentHTML("beforeend", "" + this.options.cursorChar + ""); - } + /** + * Inserts string to element container. + */ - /** - * Inserts string to element container. - */ + }, { + key: "insert", + value: function insert(content) { + var toChildNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - }, { - key: "insert", - value: function insert(content) { - var toChildNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (toChildNode) { + this.elementContainer.lastChild.insertAdjacentHTML("beforeend", content); + } else { + this.elementContainer.insertAdjacentHTML("beforeend", content); + } - if (toChildNode) { - this.elementContainer.lastChild.insertAdjacentHTML("beforeend", content); - } else { - this.elementContainer.insertAdjacentHTML("beforeend", content); + this.contents(this.contents().split("").join("")); } - //-- Split & rejoin to avoid odd spacing issues in some browsers. - this.elementContainer.innerHTML = this.elementContainer.innerHTML.split("").join(""); - } + /** + * Depending on if we're starting by deleting an existing string or typing + * from nothing, set a specific variable to what's in the HTML. + */ - /** - * Depending on if we're starting by deleting an existing string or typing - * from nothing, set a specific variable to what's in the HTML. - */ + }, { + key: "checkElement", + value: function checkElement() { + var _this2 = this; - }, { - key: "checkElement", - value: function checkElement() { - var _this2 = this; + //-- If any of the existing children nodes have .ti-container, clear it out because this is a remnant of a previous instance. + [].slice.call(this.element.childNodes).forEach(function (node) { + if (node.classList === undefined) return; - //-- If any of the existing children nodes have .ti-container, clear it out because this is a remnant of a previous instance. - [].slice.call(this.element.childNodes).forEach(function (node) { - if (node.classList === undefined) return; + if (node.classList.contains("ti-container")) { + _this2.element.innerHTML = ""; + } + }); - if (node.classList.contains("ti-container")) { - _this2.element.innerHTML = ""; + //-- Set the hard-coded string as the string(s) we'll type. + if (!this.options.startDelete && this.element.innerHTML.length > 0) { + this.options.strings = this.element.innerHTML.trim(); + return; } - }); - //-- Set the hard-coded string as the string(s) we'll type. - if (!this.options.startDelete && this.element.innerHTML.length > 0) { - this.options.strings = this.element.innerHTML.trim(); - return; + this.stringsToDelete = this.element.innerHTML; + } + }, { + key: "break", + value: function _break() { + this.insert("
"); + this.next(); } + }, { + key: "pause", + value: function pause() { + var _this3 = this; - this.stringsToDelete = this.element.innerHTML; - } - }, { - key: "break", - value: function _break() { - this.insert("
"); - this.next(); - } - }, { - key: "pause", - value: function pause() { - var _this3 = this; + var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + setTimeout(function () { + _this3.next(); + }, time ? time : this.options.nextStringDelay.total); + } - setTimeout(function () { - _this3.next(); - }, time ? time : this.options.nextStringDelay.total); - } + /* + Convert each string in the array to a sub-array. While happening, search the subarrays for HTML tags. + When a complete tag is found, slice the subarray to get the complete tag, insert it at the correct index, + and delete the range of indexes where the indexed tag used to be. + */ - /* - Convert each string in the array to a sub-array. While happening, search the subarrays for HTML tags. - When a complete tag is found, slice the subarray to get the complete tag, insert it at the correct index, - and delete the range of indexes where the indexed tag used to be. - */ + }, { + key: "rake", + value: function rake(array) { + var _this4 = this; - }, { - key: "rake", - value: function rake(array) { - var _this4 = this; + return array.map(function (item) { + //-- Convert string to array. + item = item.split(""); - return array.map(function (item) { - //-- Convert string to array. - item = item.split(""); + //-- If we're parsing HTML, group tags into their own array items. + if (_this4.options.html) { + return groupHTMLTags(item); + } - //-- If we're parsing HTML, group tags into their own array items. - if (_this4.options.html) { - return groupHTMLTags(item); - } + return item; + }); + } + }, { + key: "type", + value: function type(character) { + var _this5 = this; + + this.setPace(); + + this.timeouts[0] = setTimeout(function () { + //-- We must have an HTML tag! + if (typeof character !== "string") { + character.innerHTML = ""; + _this5.elementContainer.appendChild(character); + _this5.isInTag = true; + _this5.next(); + return; + } - return item; - }); - } - }, { - key: "type", - value: function type(character) { - var _this5 = this; - - this.setPace(); - - this.timeouts[0] = setTimeout(function () { - //-- We must have an HTML tag! - if (typeof character !== "string") { - character.innerHTML = ""; - _this5.elementContainer.appendChild(character); - _this5.isInTag = true; - _this5.next(); - return; - } + //-- When we hit the end of the tag, turn it off! + if (startsWith(character, " 1 && arguments[1] !== undefined ? arguments[1] : null; + var autonext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; - _this5.insert(character, _this5.isInTag); + var mergedSettings = {}; - _this5.next(); - }, this.typePace); - } - }, { - key: "setOptions", - value: function setOptions(settings) { - var defaults$$1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - var autonext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + if (defaults$$1 === null) { + defaults$$1 = this.options; + } - var mergedSettings = {}; + for (var attrname in defaults$$1) { + mergedSettings[attrname] = defaults$$1[attrname]; + } - if (defaults$$1 === null) { - defaults$$1 = this.options; - } + for (var _attrname in settings) { + mergedSettings[_attrname] = settings[_attrname]; + } - for (var attrname in defaults$$1) { - mergedSettings[attrname] = defaults$$1[attrname]; - } + this.options = mergedSettings; - for (var _attrname in settings) { - mergedSettings[_attrname] = settings[_attrname]; + if (autonext) { + this.next(); + } } - - this.options = mergedSettings; - - if (autonext) { - this.next(); + }, { + key: "setPace", + value: function setPace() { + var typeSpeed = this.options.speed; + var deleteSpeed = this.options.deleteSpeed !== null ? this.options.deleteSpeed : this.options.speed / 3; + var typeRange = typeSpeed / 2; + var deleteRange = deleteSpeed / 2; + + this.typePace = this.options.lifeLike ? randomInRange(typeSpeed, typeRange) : typeSpeed; + this.deletePace = this.options.lifeLike ? randomInRange(deleteSpeed, deleteRange) : deleteSpeed; } - } - }, { - key: "setPace", - value: function setPace() { - var typeSpeed = this.options.speed; - var deleteSpeed = this.options.deleteSpeed !== null ? this.options.deleteSpeed : this.options.speed / 3; - var typeRange = typeSpeed / 2; - var deleteRange = deleteSpeed / 2; - - this.typePace = this.options.lifeLike ? randomInRange(typeSpeed, typeRange) : typeSpeed; - this.deletePace = this.options.lifeLike ? randomInRange(deleteSpeed, deleteRange) : deleteSpeed; - } - }, { - key: "delete", - value: function _delete() { - var _this6 = this; + }, { + key: "delete", + value: function _delete() { + var _this6 = this; - var chars = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var chars = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - this.timeouts[1] = setTimeout(function () { - _this6.setPace(); + this.timeouts[1] = setTimeout(function () { + _this6.setPace(); - var textArray = _this6.elementContainer.innerHTML.split(""); + var textArray = _this6.contents().split(""); - //-- Cut the array by a character. - for (var n = textArray.length - 1; n > -1; n--) { - if ((textArray[n] === ">" || textArray[n] === ";") && _this6.options.html) { - for (var o = n; o > -1; o--) { - if (textArray.slice(o - 3, o + 1).join("") === "
") { - textArray.splice(o - 3, 4); - break; - } + //-- Cut the array by a character. + for (var n = textArray.length - 1; n > -1; n--) { + if ((textArray[n] === ">" || textArray[n] === ";") && _this6.options.html) { + for (var o = n; o > -1; o--) { + if (textArray.slice(o - 3, o + 1).join("") === "
") { + textArray.splice(o - 3, 4); + break; + } - if (textArray[o] === "&") { - textArray.splice(o, n - o + 1); - break; - } + if (textArray[o] === "&") { + textArray.splice(o, n - o + 1); + break; + } - if (textArray[o] === "<") { - if (textArray[o - 1] !== ">") { - if (textArray[o - 1] === ";") { - for (var p = o - 1; p > -1; p--) { - if (textArray[p] === "&") { - textArray.splice(p, o - p); - break; + if (textArray[o] === "<") { + if (textArray[o - 1] !== ">") { + if (textArray[o - 1] === ";") { + for (var p = o - 1; p > -1; p--) { + if (textArray[p] === "&") { + textArray.splice(p, o - p); + break; + } } } - } - textArray.splice(o - 1, 1); - break; + textArray.splice(o - 1, 1); + break; + } } } + break; + } else { + textArray.pop(); + break; } - break; - } else { - textArray.pop(); - break; } - } - //-- If we've found an empty set of HTML tags... - if (_this6.elementContainer.innerHTML.indexOf("> -1) { - for (var i = _this6.elementContainer.innerHTML.indexOf(">= 0; i--) { - if (textArray[i] === "<") { - textArray.splice(i, textArray.length - i); - break; + //-- If we've found an empty set of HTML tags... + if (_this6.options.html && _this6.contents().indexOf("> -1) { + for (var i = _this6.contents().indexOf(">= 0; i--) { + if (textArray[i] === "<") { + textArray.splice(i, textArray.length - i); + break; + } } } - } - //-- Make the content a string again, AND strip out any empty HTML tags. - //-- We want do strip empty tags here and ONLY here because when we're - //-- typing new content inside an HTML tag, there is momentarily an empty - //-- tag we want to keep. - _this6.elementContainer.innerHTML = textArray.join("").replace(/<[^\/>][^>]*><\/[^>]+>/, ""); + //-- Make the content a string again, AND strip out any empty HTML tags. + //-- We want do strip empty tags here and ONLY here because when we're + //-- typing new content inside an HTML tag, there is momentarily an empty + //-- tag we want to keep. + _this6.contents(textArray.join("").replace(/<[^\/>][^>]*><\/[^>]+>/, "")); - //-- Delete again! Don't call directly, to respect possible pauses. - if (chars === null) { - _this6.queue.unshift([_this6.delete, textArray.length]); - } + //-- Delete again! Don't call directly, to respect possible pauses. + if (chars === null) { + _this6.queue.unshift([_this6.delete, textArray.length]); + } + + if (chars > 1) { + _this6.queue.unshift([_this6.delete, chars - 1]); + } + + _this6.next(); + }, this.deletePace); + } - if (chars > 1) { - _this6.queue.unshift([_this6.delete, chars - 1]); + /* + * Empty the existing text, clearing it instantly. + */ + + }, { + key: "empty", + value: function empty() { + this.contents(""); + this.next(); + } + }, { + key: "next", + value: function next() { + var _this7 = this; + + if (this.isFrozen) { + return; } - _this6.next(); - }, this.deletePace); - } + //-- We haven't reached the end of the queue, go again. + if (this.queue.length > 0) { + this.step = this.queue.shift(); - /* - * Empty the existing text, clearing it instantly. - */ + if (this.step[2] === "first-of-string" && this.options.beforeString) { + this.options.beforeString(this.step, this.queue, this.typeit); + } - }, { - key: "empty", - value: function empty() { - this.elementContainer.innerHTML = ""; - this.next(); - } - }, { - key: "next", - value: function next() { - var _this7 = this; + if (this.options.beforeStep) { + this.options.beforeStep(this.step, this.queue, this.typeit); + } - if (this.isFrozen) { - return; - } + //-- Execute this step! + this.step[0].call(this, this.step[1], this.step[2]); - //-- We haven't reached the end of the queue, go again. - if (this.queue.length > 0) { - this.step = this.queue.shift(); + if (this.step[2] === "last-of-string" && this.options.afterString) { + this.options.afterString(this.step, this.queue, this.typeit); + } - if (this.step[2] === "first-of-string" && this.options.beforeString) { - this.options.beforeString(this.step, this.queue, this.typeit); - } + if (this.options.afterStep) { + this.options.afterStep(this.step, this.queue, this.typeit); + } - if (this.options.beforeStep) { - this.options.beforeStep(this.step, this.queue, this.typeit); + return; } - //-- Execute this step! - this.step[0].call(this, this.step[1], this.step[2]); - - if (this.step[2] === "last-of-string" && this.options.afterString) { - this.options.afterString(this.step, this.queue, this.typeit); + //-- @todo: Remove in next major release. + if (this.options.callback) { + this.options.callback(); } - if (this.options.afterStep) { - this.options.afterStep(this.step, this.queue, this.typeit); + if (this.options.afterComplete) { + this.options.afterComplete(this.typeit); } - return; - } + if (this.options.loop) { + this.queueDeletions(this.contents()); + this.generateQueue([this.pause, this.options.loopDelay / 2]); - //-- @todo: Remove in next major release. - if (this.options.callback) { - this.options.callback(); - } + setTimeout(function () { + _this7.next(); + }, this.options.loopDelay / 2); - if (this.options.afterComplete) { - this.options.afterComplete(this.step, this.typeit); - } + return; + } - if (this.options.loop) { - this.queueDeletions(this.elementContainer.innerHTML); - this.generateQueue([this.pause, this.options.loopDelay / 2]); + this.isComplete = true; + } + }]); + return Instance; + }(); - setTimeout(function () { - _this7.next(); - }, this.options.loopDelay / 2); + var TypeIt = function () { + function TypeIt(element, args) { + classCallCheck(this, TypeIt); - return; + this.id = this.generateHash(); + this.instances = []; + this.elements = []; + this.args = args; + + if ((typeof element === "undefined" ? "undefined" : _typeof(element)) === "object") { + //-- There's only one! + if (element.length === undefined) { + this.elements.push(element); + } else { + //-- It's already an array! + this.elements = element; + } } - this.isComplete = true; - } - }]); - return Instance; -}(); - -var TypeIt = function () { - function TypeIt(element, args) { - classCallCheck(this, TypeIt); - - this.id = this.generateHash(); - this.instances = []; - this.elements = []; - this.args = args; - - if ((typeof element === "undefined" ? "undefined" : _typeof(element)) === "object") { - //-- There's only one! - if (element.length === undefined) { - this.elements.push(element); - } else { - //-- It's already an array! - this.elements = element; + //-- Convert to array of elements. + if (typeof element === "string") { + this.elements = document.querySelectorAll(element); } - } - //-- Convert to array of elements. - if (typeof element === "string") { - this.elements = document.querySelectorAll(element); + this.createInstances(); } - this.createInstances(); - } + createClass(TypeIt, [{ + key: "generateHash", + value: function generateHash() { + return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); + } + }, { + key: "createInstances", + value: function createInstances() { + var _this = this; - createClass(TypeIt, [{ - key: "generateHash", - value: function generateHash() { - return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - } - }, { - key: "createInstances", - value: function createInstances() { - var _this = this; - - [].slice.call(this.elements).forEach(function (element) { - _this.instances.push(new Instance(element, _this.id, _this.args, _this)); - }); - } - }, { - key: "pushAction", - value: function pushAction(func) { - var argument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + [].slice.call(this.elements).forEach(function (element) { + _this.instances.push(new Instance(element, _this.id, _this.args, _this)); + }); + } + }, { + key: "pushAction", + value: function pushAction(func) { + var argument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - this.instances.forEach(function (instance) { - instance.queue.push([instance[func], argument]); + this.instances.forEach(function (instance) { + instance.queue.push([instance[func], argument]); - if (instance.isComplete === true) { - instance.next(); - } - }); - } + if (instance.isComplete === true) { + instance.next(); + } + }); + } - /** - * If used after typing has started, will append strings to the end of the existing queue. If used when typing is paused, will restart it. - * - * @param {string} string The string to be typed. - * @return {object} TypeIt instance - */ + /** + * If used after typing has started, will append strings to the end of the existing queue. If used when typing is paused, will restart it. + * + * @param {string} string The string to be typed. + * @return {object} TypeIt instance + */ - }, { - key: "type", - value: function type() { - var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; + }, { + key: "type", + value: function type() { + var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; - this.instances.forEach(function (instance) { - //-- Queue up a string right off the bat. - instance.queueString(string); + this.instances.forEach(function (instance) { + //-- Queue up a string right off the bat. + instance.queueString(string); - if (instance.isComplete === true) { - instance.next(); - } - }); + if (instance.isComplete === true) { + instance.next(); + } + }); - return this; - } + return this; + } - /** - * If null is passed, will delete whatever's currently in the element. - * - * @param { number } numCharacters Number of characters to delete. - * @return { TypeIt } - */ + /** + * If null is passed, will delete whatever's currently in the element. + * + * @param { number } numCharacters Number of characters to delete. + * @return { TypeIt } + */ - }, { - key: "delete", - value: function _delete() { - var numCharacters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + }, { + key: "delete", + value: function _delete() { + var numCharacters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - this.pushAction("delete", numCharacters); - return this; - } - }, { - key: "freeze", - value: function freeze() { - this.instances.forEach(function (instance) { - instance.isFrozen = true; - }); - } - }, { - key: "unfreeze", - value: function unfreeze() { - this.instances.forEach(function (instance) { - if (!instance.isFrozen) return; - - instance.isFrozen = false; - instance.next(); - }); - } - }, { - key: "pause", - value: function pause() { - var ms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + this.pushAction("delete", numCharacters); + return this; + } + }, { + key: "freeze", + value: function freeze() { + this.instances.forEach(function (instance) { + instance.isFrozen = true; + }); + } + }, { + key: "unfreeze", + value: function unfreeze() { + this.instances.forEach(function (instance) { + if (!instance.isFrozen) return; - this.pushAction("pause", ms); - return this; - } - }, { - key: "destroy", - value: function destroy() { - var removeCursor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - this.instances.forEach(function (instance) { - instance.timeouts = instance.timeouts.map(function (timeout) { - clearTimeout(timeout); - return null; + instance.isFrozen = false; + instance.next(); }); + } + }, { + key: "pause", + value: function pause() { + var ms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - if (removeCursor) { - instance.element.removeChild(instance.element.querySelector(".ti-cursor")); - } - }); + this.pushAction("pause", ms); + return this; + } + }, { + key: "destroy", + value: function destroy() { + var removeCursor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + + this.instances.forEach(function (instance) { + instance.timeouts = instance.timeouts.map(function (timeout) { + clearTimeout(timeout); + return null; + }); + + if (removeCursor) { + instance.element.removeChild(instance.element.querySelector(".ti-cursor")); + } + }); - this.instances = []; - } - }, { - key: "empty", - value: function empty() { - this.pushAction("empty"); - return this; - } - }, { - key: "break", - value: function _break() { - this.pushAction("break"); - return this; - } - }, { - key: "options", - value: function options(_options) { - this.pushAction("setOptions", _options); - return this; - } - }, { - key: "isComplete", - get: function get$$1() { - if (!this.instances.length) return false; + this.instances = []; + } + }, { + key: "empty", + value: function empty() { + this.pushAction("empty"); + return this; + } + }, { + key: "break", + value: function _break() { + this.pushAction("break"); + return this; + } + }, { + key: "options", + value: function options(_options) { + this.pushAction("setOptions", _options); + return this; + } + }, { + key: "isComplete", + get: function get$$1() { + if (!this.instances.length) return false; - return this.instances[0].isComplete; - } - }]); - return TypeIt; -}(); + return this.instances[0].isComplete; + } + }]); + return TypeIt; + }(); -return TypeIt; + return TypeIt; }))); diff --git a/dist/typeit.min.js b/dist/typeit.min.js index a0233846..f8bbaf1c 100644 --- a/dist/typeit.min.js +++ b/dist/typeit.min.js @@ -2,9 +2,9 @@ * * typeit - The most versatile animated typing utility on the planet. * Author: Alex MacArthur (https://macarthur.me) - * Version: v5.6.0 + * Version: v5.6.1 * URL: https://typeitjs.com * License: GPL-2.0 * */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.TypeIt=e()}(this,function(){"use strict";function n(t){var e=t.getBoundingClientRect();return!(e.right>window.innerWidth||e.bottom>window.innerHeight)&&!(e.top<0||e.left<0)}function o(t,e){return Math.abs(Math.random()*(t+e-(t-e))+(t-e))}function r(t,e){return 0===t.indexOf(e)}function u(t){return Array.isArray(t)?t.slice(0):t.split("
")}window.TypeItDefaults={strings:[],speed:100,deleteSpeed:null,lifeLike:!0,cursor:!0,cursorChar:"|",cursorSpeed:1e3,breakLines:!0,startDelay:250,startDelete:!1,nextStringDelay:750,loop:!1,loopDelay:750,html:!0,autoStart:!0,callback:!1,beforeString:!1,afterString:!1,beforeStep:!1,afterStep:!1,afterComplete:!1};var s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},h=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},t=function(){function n(t,e){for(var i=0;i/g,"")}),1<=this.options.strings.length&&""===this.options.strings[0]||(this.element.innerHTML='\n \n ',this.element.setAttribute("data-typeitid",this.id),this.elementContainer=this.element.querySelector("span"),this.options.startDelete&&(this.insert(this.stringsToDelete),this.queue.push([this.delete]),this.insertSplitPause(1)),this.cursor(),this.generateQueue(),this.kickoff())}},{key:"generateQueue",value:function(){var i=this,t=0/),n=document.implementation.createHTMLDocument("");n.body.innerHTML="<"+i[1]+">",this.queue.push([this.type,n.body.children[0]])}else this.queue.push([this.type,t[0]]);t.splice(0,1),e&&this.queue[this.queue.length-1].push("first-of-string"),t.length?this.queueString(t,!1):this.queue[this.queue.length-1].push("last-of-string")}}},{key:"insertSplitPause",value:function(t){var e=1'+this.options.cursorChar+"")}},{key:"insert",value:function(t){1"),this.next()}},{key:"pause",value:function(){var t=this,e=0"===t[s]||";"===t[s]&&n)&&(e[1]=s,s=0,i=t.slice(e[0],e[1]+1).join(""),t.splice(e[0],e[1]-e[0]+1,i),n=!1);return t}(t):t})}},{key:"type",value:function(t){var e=this;this.setPace(),this.timeouts[0]=setTimeout(function(){return"string"!=typeof t?(t.innerHTML="",e.elementContainer.appendChild(t),e.isInTag=!0):r(t,""!==t[e]&&";"!==t[e]||!o.options.html){t.pop();break}for(var i=e;-1"===t.slice(i-3,i+1).join("")){t.splice(i-3,4);break}if("&"===t[i]){t.splice(i,e-i+1);break}if("<"===t[i]&&">"!==t[i-1]){if(";"===t[i-1])for(var n=i-1;-1][^>]*><\/[^>]+>/,""),null===r&&o.queue.unshift([o.delete,t.length]),1window.innerWidth||e.bottom>window.innerHeight)&&!(e.top<0||e.left<0)}function e(t,e){return Math.abs(Math.random()*(t+e-(t-e))+(t-e))}function i(t,e){return 0===t.indexOf(e)}function n(t){return Array.isArray(t)?t.slice(0):t.split("
")}window.TypeItDefaults={strings:[],speed:100,deleteSpeed:null,lifeLike:!0,cursor:!0,cursorChar:"|",cursorSpeed:1e3,breakLines:!0,startDelay:250,startDelete:!1,nextStringDelay:750,loop:!1,loopDelay:750,html:!0,autoStart:!0,callback:!1,beforeString:!1,afterString:!1,beforeStep:!1,afterStep:!1,afterComplete:!1};var s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},o=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},r=function(){function t(t,e){for(var i=0;i0&&void 0!==arguments[0]?arguments[0]:null;return null===t?this.options.html?this.elementContainer.innerHTML:this.elementContainer.innerText:(this.options.html?this.elementContainer.innerHTML=t:this.elementContainer.innerText=t,t)}},{key:"setNextStringDelay",value:function(){var t=Array.isArray(this.options.nextStringDelay),e=t?null:this.options.nextStringDelay/2;this.options.nextStringDelay={before:t?this.options.nextStringDelay[0]:e,after:t?this.options.nextStringDelay[1]:e,total:t?this.options.nextStringDelay.reduce(function(t,e){return t+e}):this.options.nextStringDelay}}},{key:"init",value:function(){this.checkElement(),this.options.strings=n(this.options.strings),this.options.strings=this.options.strings.map(function(t){return t.replace(/<\!--.*?-->/g,"")}),this.options.strings.length>=1&&""===this.options.strings[0]||(this.element.innerHTML='\n \n ',this.element.setAttribute("data-typeitid",this.id),this.elementContainer=this.element.querySelector("span"),this.options.startDelete&&(this.insert(this.stringsToDelete),this.queue.push([this.delete]),this.insertSplitPause(1)),this.cursor(),this.generateQueue(),this.kickoff())}},{key:"generateQueue",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;e=null===e?[this.pause,this.options.startDelay]:e,this.queue.push(e),this.options.strings.forEach(function(e,i){if(t.queueString(e),i+1!==t.options.strings.length){if(t.options.breakLines)return t.queue.push([t.break]),void t.insertSplitPause(t.queue.length);t.queueDeletions(e),t.insertSplitPause(t.queue.length,e.length)}})}},{key:"queueDeletions",value:function(){for(var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e="string"==typeof t?t.length:t,i=0;i1&&void 0!==arguments[1])||arguments[1];if(t){if(t=n(t),document.implementation.createHTMLDocument("").body.innerHTML=t,e&&(t=(t=this.rake(t))[0]),this.options.html&&i(t[0],"<")&&!i(t[0],"/),o=document.implementation.createHTMLDocument("");o.body.innerHTML="<"+s[1]+">",this.queue.push([this.type,o.body.children[0]])}else this.queue.push([this.type,t[0]]);t.splice(0,1),e&&this.queue[this.queue.length-1].push("first-of-string"),t.length?this.queueString(t,!1):this.queue[this.queue.length-1].push("last-of-string")}}},{key:"insertSplitPause",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;this.queue.splice(t,0,[this.pause,this.options.nextStringDelay.before]),this.queue.splice(t-e,0,[this.pause,this.options.nextStringDelay.after])}},{key:"kickoff",value:function(){if(this.options.autoStart)return this.hasStarted=!0,void this.next();if(t(this.element))return this.hasStarted=!0,void this.next();var e=this;window.addEventListener("scroll",function i(n){t(e.element)&&!e.hasStarted&&(e.hasStarted=!0,e.next(),n.currentTarget.removeEventListener(n.type,i))})}},{key:"cursor",value:function(){var t="visibility: hidden;";if(this.options.cursor){var e=document.createElement("style");e.id=this.id;var i="\n @keyframes blink-"+this.id+" {\n 0% {opacity: 0}\n 49% {opacity: 0}\n 50% {opacity: 1}\n }\n\n [data-typeitid='"+this.id+"'] .ti-cursor {\n animation: blink-"+this.id+" "+this.options.cursorSpeed/1e3+"s infinite;\n }\n ";e.appendChild(document.createTextNode(i)),document.head.appendChild(e),t=""}this.element.insertAdjacentHTML("beforeend",''+this.options.cursorChar+"")}},{key:"insert",value:function(t){arguments.length>1&&void 0!==arguments[1]&&arguments[1]?this.elementContainer.lastChild.insertAdjacentHTML("beforeend",t):this.elementContainer.insertAdjacentHTML("beforeend",t),this.contents(this.contents().split("").join(""))}},{key:"checkElement",value:function(){var t=this;[].slice.call(this.element.childNodes).forEach(function(e){void 0!==e.classList&&e.classList.contains("ti-container")&&(t.element.innerHTML="")}),!this.options.startDelete&&this.element.innerHTML.length>0?this.options.strings=this.element.innerHTML.trim():this.stringsToDelete=this.element.innerHTML}},{key:"break",value:function(){this.insert("
"),this.next()}},{key:"pause",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];setTimeout(function(){t.next()},e||this.options.nextStringDelay.total)}},{key:"rake",value:function(t){var e=this;return t.map(function(t){return t=t.split(""),e.options.html?function(t){for(var e=[],i=void 0,n=!1,s=0;s"===t[s]||";"===t[s]&&n)&&(e[1]=s,s=0,i=t.slice(e[0],e[1]+1).join(""),t.splice(e[0],e[1]-e[0]+1,i),n=!1);return t}(t):t})}},{key:"type",value:function(t){var e=this;this.setPace(),this.timeouts[0]=setTimeout(function(){return"string"!=typeof t?(t.innerHTML="",e.elementContainer.appendChild(t),e.isInTag=!0,void e.next()):i(t,"1&&void 0!==arguments[1]?arguments[1]:null,i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],n={};for(var s in null===e&&(e=this.options),e)n[s]=e[s];for(var o in t)n[o]=t[o];this.options=n,i&&this.next()}},{key:"setPace",value:function(){var t=this.options.speed,i=null!==this.options.deleteSpeed?this.options.deleteSpeed:this.options.speed/3,n=t/2,s=i/2;this.typePace=this.options.lifeLike?e(t,n):t,this.deletePace=this.options.lifeLike?e(i,s):i}},{key:"delete",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;this.timeouts[1]=setTimeout(function(){t.setPace();for(var i=t.contents().split(""),n=i.length-1;n>-1;n--){if(">"!==i[n]&&";"!==i[n]||!t.options.html){i.pop();break}for(var s=n;s>-1;s--){if("
"===i.slice(s-3,s+1).join("")){i.splice(s-3,4);break}if("&"===i[s]){i.splice(s,n-s+1);break}if("<"===i[s]&&">"!==i[s-1]){if(";"===i[s-1])for(var o=s-1;o>-1;o--)if("&"===i[o]){i.splice(o,s-o);break}i.splice(s-1,1);break}}break}if(t.options.html&&t.contents().indexOf(">-1)for(var r=t.contents().indexOf(">=0;r--)if("<"===i[r]){i.splice(r,i.length-r);break}t.contents(i.join("").replace(/<[^\/>][^>]*><\/[^>]+>/,"")),null===e&&t.queue.unshift([t.delete,i.length]),e>1&&t.queue.unshift([t.delete,e-1]),t.next()},this.deletePace)}},{key:"empty",value:function(){this.contents(""),this.next()}},{key:"next",value:function(){var t=this;if(!this.isFrozen){if(this.queue.length>0)return this.step=this.queue.shift(),"first-of-string"===this.step[2]&&this.options.beforeString&&this.options.beforeString(this.step,this.queue,this.typeit),this.options.beforeStep&&this.options.beforeStep(this.step,this.queue,this.typeit),this.step[0].call(this,this.step[1],this.step[2]),"last-of-string"===this.step[2]&&this.options.afterString&&this.options.afterString(this.step,this.queue,this.typeit),void(this.options.afterStep&&this.options.afterStep(this.step,this.queue,this.typeit));if(this.options.callback&&this.options.callback(),this.options.afterComplete&&this.options.afterComplete(this.typeit),this.options.loop)return this.queueDeletions(this.contents()),this.generateQueue([this.pause,this.options.loopDelay/2]),void setTimeout(function(){t.next()},this.options.loopDelay/2);this.isComplete=!0}}}]),s}();return function(){function t(e,i){o(this,t),this.id=this.generateHash(),this.instances=[],this.elements=[],this.args=i,"object"===(void 0===e?"undefined":s(e))&&(void 0===e.length?this.elements.push(e):this.elements=e),"string"==typeof e&&(this.elements=document.querySelectorAll(e)),this.createInstances()}return r(t,[{key:"generateHash",value:function(){return Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15)}},{key:"createInstances",value:function(){var t=this;[].slice.call(this.elements).forEach(function(e){t.instances.push(new h(e,t.id,t.args,t))})}},{key:"pushAction",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;this.instances.forEach(function(i){i.queue.push([i[t],e]),!0===i.isComplete&&i.next()})}},{key:"type",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return this.instances.forEach(function(e){e.queueString(t),!0===e.isComplete&&e.next()}),this}},{key:"delete",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return this.pushAction("delete",t),this}},{key:"freeze",value:function(){this.instances.forEach(function(t){t.isFrozen=!0})}},{key:"unfreeze",value:function(){this.instances.forEach(function(t){t.isFrozen&&(t.isFrozen=!1,t.next())})}},{key:"pause",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return this.pushAction("pause",t),this}},{key:"destroy",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.instances.forEach(function(e){e.timeouts=e.timeouts.map(function(t){return clearTimeout(t),null}),t&&e.element.removeChild(e.element.querySelector(".ti-cursor"))}),this.instances=[]}},{key:"empty",value:function(){return this.pushAction("empty"),this}},{key:"break",value:function(){return this.pushAction("break"),this}},{key:"options",value:function(t){return this.pushAction("setOptions",t),this}},{key:"isComplete",get:function(){return!!this.instances.length&&this.instances[0].isComplete}}]),t}()}); diff --git a/package.json b/package.json index 169d2fe8..500fa458 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typeit", - "version": "5.6.0", + "version": "5.6.1", "description": "The most versatile animated typing utility on the planet.", "author": "Alex MacArthur (https://macarthur.me)", "license": "GPL-2.0", @@ -44,9 +44,9 @@ "jest-cli": "^21.2.1", "prettier": "^1.8.2", "regenerator-runtime": "^0.11.0", - "rollup": "^0.52.0", - "rollup-plugin-babel": "^3.0.2", - "rollup-plugin-uglify": "^2.0.1" + "rollup": "^0.57.1", + "rollup-plugin-babel": "^3.0.3", + "rollup-plugin-uglify": "^3.0.0" }, "dependencies": { "jest": "^22.4.2" diff --git a/sandbox.html b/sandbox.html index 9068089f..3b8297f4 100644 --- a/sandbox.html +++ b/sandbox.html @@ -65,8 +65,7 @@