iziToast.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. /*
  2. * iziToast | v1.3.0
  3. * http://izitoast.marcelodolce.com
  4. * by Marcelo Dolce.
  5. */
  6. (function (root, factory) {
  7. if(typeof define === 'function' && define.amd) {
  8. define([], factory(root));
  9. } else if(typeof exports === 'object') {
  10. module.exports = factory(root);
  11. } else {
  12. root.iziToast = factory(root);
  13. }
  14. })(typeof global !== 'undefined' ? global : window || this.window || this.global, function (root) {
  15. 'use strict';
  16. //
  17. // Variables
  18. //
  19. var $iziToast = {},
  20. PLUGIN_NAME = 'iziToast',
  21. BODY = document.querySelector('body'),
  22. ISMOBILE = (/Mobi/.test(navigator.userAgent)) ? true : false,
  23. ISCHROME = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor),
  24. ISFIREFOX = typeof InstallTrigger !== 'undefined',
  25. ACCEPTSTOUCH = 'ontouchstart' in document.documentElement,
  26. POSITIONS = ['bottomRight','bottomLeft','bottomCenter','topRight','topLeft','topCenter','center'],
  27. THEMES = {
  28. info: {
  29. color: 'blue',
  30. icon: 'ico-info'
  31. },
  32. success: {
  33. color: 'green',
  34. icon: 'ico-success'
  35. },
  36. warning: {
  37. color: 'orange',
  38. icon: 'ico-warning'
  39. },
  40. error: {
  41. color: 'red',
  42. icon: 'ico-error'
  43. },
  44. question: {
  45. color: 'yellow',
  46. icon: 'ico-question'
  47. }
  48. },
  49. MOBILEWIDTH = 568,
  50. CONFIG = {};
  51. $iziToast.children = {};
  52. // Default settings
  53. var defaults = {
  54. id: null,
  55. class: '',
  56. title: '',
  57. titleColor: '',
  58. titleSize: '',
  59. titleLineHeight: '',
  60. message: '',
  61. messageColor: '',
  62. messageSize: '',
  63. messageLineHeight: '',
  64. backgroundColor: '',
  65. theme: 'light', // dark
  66. color: '', // blue, red, green, yellow
  67. icon: '',
  68. iconText: '',
  69. iconColor: '',
  70. image: '',
  71. imageWidth: 50,
  72. maxWidth: null,
  73. zindex: null,
  74. layout: 1,
  75. balloon: false,
  76. close: true,
  77. closeOnEscape: false,
  78. closeOnClick: false,
  79. rtl: false,
  80. position: 'bottomRight', // bottomRight, bottomLeft, topRight, topLeft, topCenter, bottomCenter, center
  81. target: '',
  82. targetFirst: true,
  83. toastOnce: false,
  84. timeout: 5000,
  85. animateInside: true,
  86. drag: true,
  87. pauseOnHover: true,
  88. resetOnHover: false,
  89. progressBar: true,
  90. progressBarColor: '',
  91. progressBarEasing: 'linear',
  92. overlay: false,
  93. overlayClose: false,
  94. overlayColor: 'rgba(0, 0, 0, 0.6)',
  95. transitionIn: 'fadeInUp', // bounceInLeft, bounceInRight, bounceInUp, bounceInDown, fadeIn, fadeInDown, fadeInUp, fadeInLeft, fadeInRight, flipInX
  96. transitionOut: 'fadeOut', // fadeOut, fadeOutUp, fadeOutDown, fadeOutLeft, fadeOutRight, flipOutX
  97. transitionInMobile: 'fadeInUp',
  98. transitionOutMobile: 'fadeOutDown',
  99. buttons: {},
  100. inputs: {},
  101. onOpening: function () {},
  102. onOpened: function () {},
  103. onClosing: function () {},
  104. onClosed: function () {}
  105. };
  106. //
  107. // Methods
  108. //
  109. /**
  110. * Polyfill for remove() method
  111. */
  112. if(!('remove' in Element.prototype)) {
  113. Element.prototype.remove = function() {
  114. if(this.parentNode) {
  115. this.parentNode.removeChild(this);
  116. }
  117. };
  118. }
  119. /*
  120. * Polyfill for CustomEvent for IE >= 9
  121. * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
  122. */
  123. if(typeof window.CustomEvent !== 'function') {
  124. var CustomEventPolyfill = function (event, params) {
  125. params = params || { bubbles: false, cancelable: false, detail: undefined };
  126. var evt = document.createEvent('CustomEvent');
  127. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  128. return evt;
  129. };
  130. CustomEventPolyfill.prototype = window.Event.prototype;
  131. window.CustomEvent = CustomEventPolyfill;
  132. }
  133. /**
  134. * A simple forEach() implementation for Arrays, Objects and NodeLists
  135. * @private
  136. * @param {Array|Object|NodeList} collection Collection of items to iterate
  137. * @param {Function} callback Callback function for each iteration
  138. * @param {Array|Object|NodeList} scope Object/NodeList/Array that forEach is iterating over (aka `this`)
  139. */
  140. var forEach = function (collection, callback, scope) {
  141. if(Object.prototype.toString.call(collection) === '[object Object]') {
  142. for (var prop in collection) {
  143. if(Object.prototype.hasOwnProperty.call(collection, prop)) {
  144. callback.call(scope, collection[prop], prop, collection);
  145. }
  146. }
  147. } else {
  148. if(collection){
  149. for (var i = 0, len = collection.length; i < len; i++) {
  150. callback.call(scope, collection[i], i, collection);
  151. }
  152. }
  153. }
  154. };
  155. /**
  156. * Merge defaults with user options
  157. * @private
  158. * @param {Object} defaults Default settings
  159. * @param {Object} options User options
  160. * @returns {Object} Merged values of defaults and options
  161. */
  162. var extend = function (defaults, options) {
  163. var extended = {};
  164. forEach(defaults, function (value, prop) {
  165. extended[prop] = defaults[prop];
  166. });
  167. forEach(options, function (value, prop) {
  168. extended[prop] = options[prop];
  169. });
  170. return extended;
  171. };
  172. /**
  173. * Create a fragment DOM elements
  174. * @private
  175. */
  176. var createFragElem = function(htmlStr) {
  177. var frag = document.createDocumentFragment(),
  178. temp = document.createElement('div');
  179. temp.innerHTML = htmlStr;
  180. while (temp.firstChild) {
  181. frag.appendChild(temp.firstChild);
  182. }
  183. return frag;
  184. };
  185. /**
  186. * Check if is a color
  187. * @private
  188. */
  189. var isColor = function(color){
  190. if( color.substring(0,1) == '#' || color.substring(0,3) == 'rgb' || color.substring(0,3) == 'hsl' ){
  191. return true;
  192. } else {
  193. return false;
  194. }
  195. };
  196. /**
  197. * Check if is a Base64 string
  198. * @private
  199. */
  200. var isBase64 = function(str) {
  201. try {
  202. return btoa(atob(str)) == str;
  203. } catch (err) {
  204. return false;
  205. }
  206. };
  207. /**
  208. * Drag method of toasts
  209. * @private
  210. */
  211. var drag = function() {
  212. return {
  213. move: function(toast, instance, settings, xpos) {
  214. var opacity,
  215. opacityRange = 0.3,
  216. distance = 180;
  217. if(xpos !== 0){
  218. toast.classList.add(PLUGIN_NAME+'-dragged');
  219. toast.style.transform = 'translateX('+xpos + 'px)';
  220. if(xpos > 0){
  221. opacity = (distance-xpos) / distance;
  222. if(opacity < opacityRange){
  223. instance.hide(extend(settings, { transitionOut: 'fadeOutRight', transitionOutMobile: 'fadeOutRight' }), toast, 'drag');
  224. }
  225. } else {
  226. opacity = (distance+xpos) / distance;
  227. if(opacity < opacityRange){
  228. instance.hide(extend(settings, { transitionOut: 'fadeOutLeft', transitionOutMobile: 'fadeOutLeft' }), toast, 'drag');
  229. }
  230. }
  231. toast.style.opacity = opacity;
  232. if(opacity < opacityRange){
  233. if(ISCHROME || ISFIREFOX)
  234. toast.style.left = xpos+'px';
  235. toast.parentNode.style.opacity = opacityRange;
  236. this.stopMoving(toast, null);
  237. }
  238. }
  239. },
  240. startMoving: function(toast, instance, settings, e) {
  241. e = e || window.event;
  242. var posX = ((ACCEPTSTOUCH) ? e.touches[0].clientX : e.clientX),
  243. toastLeft = toast.style.transform.replace('px)', '');
  244. toastLeft = toastLeft.replace('translateX(', '');
  245. var offsetX = posX - toastLeft;
  246. toast.classList.remove(settings.transitionIn);
  247. toast.classList.remove(settings.transitionInMobile);
  248. toast.style.transition = '';
  249. if(ACCEPTSTOUCH) {
  250. document.ontouchmove = function(e) {
  251. e.preventDefault();
  252. e = e || window.event;
  253. var posX = e.touches[0].clientX,
  254. finalX = posX - offsetX;
  255. drag.move(toast, instance, settings, finalX);
  256. };
  257. } else {
  258. document.onmousemove = function(e) {
  259. e.preventDefault();
  260. e = e || window.event;
  261. var posX = e.clientX,
  262. finalX = posX - offsetX;
  263. drag.move(toast, instance, settings, finalX);
  264. };
  265. }
  266. },
  267. stopMoving: function(toast, e) {
  268. if(ACCEPTSTOUCH) {
  269. document.ontouchmove = function() {};
  270. } else {
  271. document.onmousemove = function() {};
  272. }
  273. toast.style.opacity = '';
  274. toast.style.transform = '';
  275. if(toast.classList.contains(PLUGIN_NAME+'-dragged')){
  276. toast.classList.remove(PLUGIN_NAME+'-dragged');
  277. toast.style.transition = 'transform 0.4s ease, opacity 0.4s ease';
  278. setTimeout(function() {
  279. toast.style.transition = '';
  280. }, 400);
  281. }
  282. }
  283. };
  284. }();
  285. $iziToast.setSetting = function (ref, option, value) {
  286. $iziToast.children[ref][option] = value;
  287. };
  288. $iziToast.getSetting = function (ref, option) {
  289. return $iziToast.children[ref][option];
  290. };
  291. /**
  292. * Destroy the current initialization.
  293. * @public
  294. */
  295. $iziToast.destroy = function () {
  296. forEach(document.querySelectorAll('.'+PLUGIN_NAME+'-wrapper'), function(element, index) {
  297. element.remove();
  298. });
  299. forEach(document.querySelectorAll('.'+PLUGIN_NAME), function(element, index) {
  300. element.remove();
  301. });
  302. // Remove event listeners
  303. document.removeEventListener(PLUGIN_NAME+'-opened', {}, false);
  304. document.removeEventListener(PLUGIN_NAME+'-opening', {}, false);
  305. document.removeEventListener(PLUGIN_NAME+'-closing', {}, false);
  306. document.removeEventListener(PLUGIN_NAME+'-closed', {}, false);
  307. document.removeEventListener('keyup', {}, false);
  308. // Reset variables
  309. CONFIG = {};
  310. };
  311. /**
  312. * Initialize Plugin
  313. * @public
  314. * @param {Object} options User settings
  315. */
  316. $iziToast.settings = function (options) {
  317. // Destroy any existing initializations
  318. $iziToast.destroy();
  319. CONFIG = options;
  320. defaults = extend(defaults, options || {});
  321. };
  322. /**
  323. * Building themes functions.
  324. * @public
  325. * @param {Object} options User settings
  326. */
  327. forEach(THEMES, function (theme, name) {
  328. $iziToast[name] = function (options) {
  329. var settings = extend(CONFIG, options || {});
  330. settings = extend(theme, settings || {});
  331. this.show(settings);
  332. };
  333. });
  334. /**
  335. * Do the calculation to move the progress bar
  336. * @private
  337. */
  338. $iziToast.progress = function (options, $toast, callback) {
  339. var that = this,
  340. ref = $toast.getAttribute('data-iziToast-ref'),
  341. settings = extend(this.children[ref], options || {}),
  342. $elem = $toast.querySelector('.'+PLUGIN_NAME+'-progressbar div');
  343. return {
  344. start: function() {
  345. if(typeof settings.time.REMAINING == 'undefined'){
  346. $toast.classList.remove(PLUGIN_NAME+'-reseted');
  347. if($elem !== null){
  348. $elem.style.transition = 'width '+ settings.timeout +'ms '+settings.progressBarEasing;
  349. $elem.style.width = '0%';
  350. }
  351. settings.time.START = new Date().getTime();
  352. settings.time.END = settings.time.START + settings.timeout;
  353. settings.time.TIMER = setTimeout(function() {
  354. clearTimeout(settings.time.TIMER);
  355. if(!$toast.classList.contains(PLUGIN_NAME+'-closing')){
  356. that.hide(settings, $toast, 'timeout');
  357. if(typeof callback === 'function'){
  358. callback.apply(that);
  359. }
  360. }
  361. }, settings.timeout);
  362. that.setSetting(ref, 'time', settings.time);
  363. }
  364. },
  365. pause: function() {
  366. if(typeof settings.time.START !== 'undefined' && !$toast.classList.contains(PLUGIN_NAME+'-paused') && !$toast.classList.contains(PLUGIN_NAME+'-reseted')){
  367. $toast.classList.add(PLUGIN_NAME+'-paused');
  368. settings.time.REMAINING = settings.time.END - new Date().getTime();
  369. clearTimeout(settings.time.TIMER);
  370. that.setSetting(ref, 'time', settings.time);
  371. if($elem !== null){
  372. var computedStyle = window.getComputedStyle($elem),
  373. propertyWidth = computedStyle.getPropertyValue('width');
  374. $elem.style.transition = 'none';
  375. $elem.style.width = propertyWidth;
  376. }
  377. if(typeof callback === 'function'){
  378. setTimeout(function() {
  379. callback.apply(that);
  380. }, 10);
  381. }
  382. }
  383. },
  384. resume: function() {
  385. if(typeof settings.time.REMAINING !== 'undefined'){
  386. $toast.classList.remove(PLUGIN_NAME+'-paused');
  387. if($elem !== null){
  388. $elem.style.transition = 'width '+ settings.time.REMAINING +'ms '+settings.progressBarEasing;
  389. $elem.style.width = '0%';
  390. }
  391. settings.time.END = new Date().getTime() + settings.time.REMAINING;
  392. settings.time.TIMER = setTimeout(function() {
  393. clearTimeout(settings.time.TIMER);
  394. if(!$toast.classList.contains(PLUGIN_NAME+'-closing')){
  395. that.hide(settings, $toast, 'timeout');
  396. if(typeof callback === 'function'){
  397. callback.apply(that);
  398. }
  399. }
  400. }, settings.time.REMAINING);
  401. that.setSetting(ref, 'time', settings.time);
  402. } else {
  403. this.start();
  404. }
  405. },
  406. reset: function(){
  407. clearTimeout(settings.time.TIMER);
  408. delete settings.time.REMAINING;
  409. that.setSetting(ref, 'time', settings.time);
  410. $toast.classList.add(PLUGIN_NAME+'-reseted');
  411. $toast.classList.remove(PLUGIN_NAME+'-paused');
  412. if($elem !== null){
  413. $elem.style.transition = 'none';
  414. $elem.style.width = '100%';
  415. }
  416. if(typeof callback === 'function'){
  417. setTimeout(function() {
  418. callback.apply(that);
  419. }, 10);
  420. }
  421. }
  422. };
  423. };
  424. /**
  425. * Close the specific Toast
  426. * @public
  427. * @param {Object} options User settings
  428. */
  429. $iziToast.hide = function (options, $toast, closedBy) {
  430. var that = this,
  431. settings = extend(this.children[$toast.getAttribute('data-iziToast-ref')], options || {});
  432. settings.closedBy = closedBy || null;
  433. delete settings.time.REMAINING;
  434. if(typeof $toast != 'object'){
  435. $toast = document.querySelector($toast);
  436. }
  437. $toast.classList.add(PLUGIN_NAME+'-closing');
  438. // Overlay
  439. (function(){
  440. var $overlay = document.querySelector('.'+PLUGIN_NAME+'-overlay');
  441. if($overlay !== null){
  442. var refs = $overlay.getAttribute('data-iziToast-ref');
  443. refs = refs.split(',');
  444. var index = refs.indexOf(String(settings.ref));
  445. if(index !== -1){
  446. refs.splice(index, 1);
  447. }
  448. $overlay.setAttribute('data-iziToast-ref', refs.join());
  449. if(refs.length === 0){
  450. $overlay.classList.remove('fadeIn');
  451. $overlay.classList.add('fadeOut');
  452. setTimeout(function() {
  453. $overlay.remove();
  454. }, 700);
  455. }
  456. }
  457. })();
  458. if(settings.transitionIn || settings.transitionInMobile){
  459. $toast.classList.remove(settings.transitionIn);
  460. $toast.classList.remove(settings.transitionInMobile);
  461. }
  462. if(ISMOBILE || window.innerWidth <= MOBILEWIDTH){
  463. if(settings.transitionOutMobile)
  464. $toast.classList.add(settings.transitionOutMobile);
  465. } else {
  466. if(settings.transitionOut)
  467. $toast.classList.add(settings.transitionOut);
  468. }
  469. var H = $toast.parentNode.offsetHeight;
  470. $toast.parentNode.style.height = H+'px';
  471. $toast.style.pointerEvents = 'none';
  472. if(!ISMOBILE || window.innerWidth > MOBILEWIDTH){
  473. $toast.parentNode.style.transitionDelay = '0.2s';
  474. }
  475. try {
  476. var event = new CustomEvent(PLUGIN_NAME+'-closing', {detail: settings, bubbles: true, cancelable: true});
  477. document.dispatchEvent(event);
  478. } catch(ex){
  479. console.warn(ex);
  480. }
  481. setTimeout(function() {
  482. $toast.parentNode.style.height = '0px';
  483. $toast.parentNode.style.overflow = '';
  484. setTimeout(function(){
  485. delete that.children[settings.ref];
  486. $toast.parentNode.remove();
  487. try {
  488. var event = new CustomEvent(PLUGIN_NAME+'-closed', {detail: settings, bubbles: true, cancelable: true});
  489. document.dispatchEvent(event);
  490. } catch(ex){
  491. console.warn(ex);
  492. }
  493. if(typeof settings.onClosed !== 'undefined'){
  494. settings.onClosed.apply(null, [settings, $toast, closedBy]);
  495. }
  496. }, 1000);
  497. }, 200);
  498. if(typeof settings.onClosing !== 'undefined'){
  499. settings.onClosing.apply(null, [settings, $toast, closedBy]);
  500. }
  501. };
  502. /**
  503. * Create and show the Toast
  504. * @public
  505. * @param {Object} options User settings
  506. */
  507. $iziToast.show = function (options) {
  508. var that = this;
  509. // Merge user options with defaults
  510. var settings = extend(CONFIG, options || {});
  511. settings = extend(defaults, settings);
  512. settings.time = {};
  513. if(settings.toastOnce && settings.id && document.querySelectorAll('.'+PLUGIN_NAME+'#'+settings.id).length > 0){
  514. return false;
  515. }
  516. settings.ref = new Date().getTime() + Math.floor((Math.random() * 10000000) + 1);
  517. $iziToast.children[settings.ref] = settings;
  518. var $DOM = {
  519. body: document.querySelector('body'),
  520. overlay: document.createElement('div'),
  521. toast: document.createElement('div'),
  522. toastBody: document.createElement('div'),
  523. toastTexts: document.createElement('div'),
  524. toastCapsule: document.createElement('div'),
  525. icon: document.createElement('i'),
  526. cover: document.createElement('div'),
  527. buttons: document.createElement('div'),
  528. inputs: document.createElement('div'),
  529. wrapper: null
  530. };
  531. $DOM.toast.setAttribute('data-iziToast-ref', settings.ref);
  532. $DOM.toast.appendChild($DOM.toastBody);
  533. $DOM.toastCapsule.appendChild($DOM.toast);
  534. // CSS Settings
  535. (function(){
  536. $DOM.toast.classList.add(PLUGIN_NAME);
  537. $DOM.toast.classList.add(PLUGIN_NAME+'-opening');
  538. $DOM.toastCapsule.classList.add(PLUGIN_NAME+'-capsule');
  539. $DOM.toastBody.classList.add(PLUGIN_NAME + '-body');
  540. $DOM.toastTexts.classList.add(PLUGIN_NAME + '-texts');
  541. if(ISMOBILE || window.innerWidth <= MOBILEWIDTH){
  542. if(settings.transitionInMobile)
  543. $DOM.toast.classList.add(settings.transitionInMobile);
  544. } else {
  545. if(settings.transitionIn)
  546. $DOM.toast.classList.add(settings.transitionIn);
  547. }
  548. if(settings.class){
  549. var classes = settings.class.split(' ');
  550. forEach(classes, function (value, index) {
  551. $DOM.toast.classList.add(value);
  552. });
  553. }
  554. if(settings.id){ $DOM.toast.id = settings.id; }
  555. if(settings.rtl){
  556. $DOM.toast.classList.add(PLUGIN_NAME + '-rtl');
  557. $DOM.toast.setAttribute('dir', 'rtl');
  558. }
  559. if(settings.layout > 1){ $DOM.toast.classList.add(PLUGIN_NAME+'-layout'+settings.layout); }
  560. if(settings.balloon){ $DOM.toast.classList.add(PLUGIN_NAME+'-balloon'); }
  561. if(settings.maxWidth){
  562. if( !isNaN(settings.maxWidth) ){
  563. $DOM.toast.style.maxWidth = settings.maxWidth+'px';
  564. } else {
  565. $DOM.toast.style.maxWidth = settings.maxWidth;
  566. }
  567. }
  568. if(settings.theme !== '' || settings.theme !== 'light') {
  569. $DOM.toast.classList.add(PLUGIN_NAME+'-theme-'+settings.theme);
  570. }
  571. if(settings.color) { //#, rgb, rgba, hsl
  572. if( isColor(settings.color) ){
  573. $DOM.toast.style.background = settings.color;
  574. } else {
  575. $DOM.toast.classList.add(PLUGIN_NAME+'-color-'+settings.color);
  576. }
  577. }
  578. if(settings.backgroundColor) {
  579. $DOM.toast.style.background = settings.backgroundColor;
  580. if(settings.balloon){
  581. $DOM.toast.style.borderColor = settings.backgroundColor;
  582. }
  583. }
  584. })();
  585. // Cover image
  586. (function(){
  587. if(settings.image) {
  588. $DOM.cover.classList.add(PLUGIN_NAME + '-cover');
  589. $DOM.cover.style.width = settings.imageWidth + 'px';
  590. if(isBase64(settings.image.replace(/ /g,''))){
  591. $DOM.cover.style.backgroundImage = 'url(data:image/png;base64,' + settings.image.replace(/ /g,'') + ')';
  592. } else {
  593. $DOM.cover.style.backgroundImage = 'url(' + settings.image + ')';
  594. }
  595. if(settings.rtl){
  596. $DOM.toastBody.style.marginRight = (settings.imageWidth + 10) + 'px';
  597. } else {
  598. $DOM.toastBody.style.marginLeft = (settings.imageWidth + 10) + 'px';
  599. }
  600. $DOM.toast.appendChild($DOM.cover);
  601. }
  602. })();
  603. // Button close
  604. (function(){
  605. if(settings.close){
  606. $DOM.buttonClose = document.createElement('button');
  607. $DOM.buttonClose.classList.add(PLUGIN_NAME + '-close');
  608. $DOM.buttonClose.addEventListener('click', function (e) {
  609. var button = e.target;
  610. that.hide(settings, $DOM.toast, 'button');
  611. });
  612. $DOM.toast.appendChild($DOM.buttonClose);
  613. } else {
  614. if(settings.rtl){
  615. $DOM.toast.style.paddingLeft = '18px';
  616. } else {
  617. $DOM.toast.style.paddingRight = '18px';
  618. }
  619. }
  620. })();
  621. // Progress Bar & Timeout
  622. (function(){
  623. if(settings.progressBar){
  624. $DOM.progressBar = document.createElement('div');
  625. $DOM.progressBarDiv = document.createElement('div');
  626. $DOM.progressBar.classList.add(PLUGIN_NAME + '-progressbar');
  627. $DOM.progressBarDiv.style.background = settings.progressBarColor;
  628. $DOM.progressBar.appendChild($DOM.progressBarDiv);
  629. $DOM.toast.appendChild($DOM.progressBar);
  630. }
  631. if(settings.timeout) {
  632. if(settings.pauseOnHover && !settings.resetOnHover){
  633. $DOM.toast.addEventListener('mouseenter', function (e) {
  634. that.progress(settings, $DOM.toast).pause();
  635. });
  636. $DOM.toast.addEventListener('mouseleave', function (e) {
  637. that.progress(settings, $DOM.toast).resume();
  638. });
  639. }
  640. if(settings.resetOnHover){
  641. $DOM.toast.addEventListener('mouseenter', function (e) {
  642. that.progress(settings, $DOM.toast).reset();
  643. });
  644. $DOM.toast.addEventListener('mouseleave', function (e) {
  645. that.progress(settings, $DOM.toast).start();
  646. });
  647. }
  648. }
  649. })();
  650. // Icon
  651. (function(){
  652. if(settings.icon) {
  653. $DOM.icon.setAttribute('class', PLUGIN_NAME + '-icon ' + settings.icon);
  654. if(settings.iconText){
  655. $DOM.icon.appendChild(document.createTextNode(settings.iconText));
  656. }
  657. if(settings.rtl){
  658. $DOM.toastBody.style.paddingRight = '33px';
  659. } else {
  660. $DOM.toastBody.style.paddingLeft = '33px';
  661. }
  662. if(settings.iconColor){
  663. $DOM.icon.style.color = settings.iconColor;
  664. }
  665. $DOM.toastBody.appendChild($DOM.icon);
  666. }
  667. })();
  668. // Title & Message
  669. (function(){
  670. if(settings.title.length > 0) {
  671. $DOM.strong = document.createElement('strong');
  672. $DOM.strong.classList.add(PLUGIN_NAME + '-title');
  673. $DOM.strong.appendChild(createFragElem(settings.title));
  674. $DOM.toastTexts.appendChild($DOM.strong);
  675. if(settings.titleColor) {
  676. $DOM.strong.style.color = settings.titleColor;
  677. }
  678. if(settings.titleSize) {
  679. if( !isNaN(settings.titleSize) ){
  680. $DOM.strong.style.fontSize = settings.titleSize+'px';
  681. } else {
  682. $DOM.strong.style.fontSize = settings.titleSize;
  683. }
  684. }
  685. if(settings.titleLineHeight) {
  686. if( !isNaN(settings.titleSize) ){
  687. $DOM.strong.style.lineHeight = settings.titleLineHeight+'px';
  688. } else {
  689. $DOM.strong.style.lineHeight = settings.titleLineHeight;
  690. }
  691. }
  692. }
  693. if(settings.message.length > 0) {
  694. $DOM.p = document.createElement('p');
  695. $DOM.p.classList.add(PLUGIN_NAME + '-message');
  696. $DOM.p.appendChild(createFragElem(settings.message));
  697. $DOM.toastTexts.appendChild($DOM.p);
  698. if(settings.messageColor) {
  699. $DOM.p.style.color = settings.messageColor;
  700. }
  701. if(settings.messageSize) {
  702. if( !isNaN(settings.titleSize) ){
  703. $DOM.p.style.fontSize = settings.messageSize+'px';
  704. } else {
  705. $DOM.p.style.fontSize = settings.messageSize;
  706. }
  707. }
  708. if(settings.messageLineHeight) {
  709. if( !isNaN(settings.titleSize) ){
  710. $DOM.p.style.lineHeight = settings.messageLineHeight+'px';
  711. } else {
  712. $DOM.p.style.lineHeight = settings.messageLineHeight;
  713. }
  714. }
  715. }
  716. if(settings.title.length > 0 && settings.message.length > 0) {
  717. if(settings.rtl){
  718. $DOM.strong.style.marginLeft = '10px';
  719. } else if(settings.layout !== 2 && !settings.rtl) {
  720. $DOM.strong.style.marginRight = '10px';
  721. }
  722. }
  723. })();
  724. $DOM.toastBody.appendChild($DOM.toastTexts);
  725. // Inputs
  726. var $inputs;
  727. (function(){
  728. if(settings.inputs.length > 0) {
  729. $DOM.inputs.classList.add(PLUGIN_NAME + '-inputs');
  730. forEach(settings.inputs, function (value, index) {
  731. $DOM.inputs.appendChild(createFragElem(value[0]));
  732. $inputs = $DOM.inputs.childNodes;
  733. $inputs[index].classList.add(PLUGIN_NAME + '-inputs-child');
  734. if(value[3]){
  735. setTimeout(function() {
  736. $inputs[index].focus();
  737. }, 300);
  738. }
  739. $inputs[index].addEventListener(value[1], function (e) {
  740. var ts = value[2];
  741. return ts(that, $DOM.toast, this, e);
  742. });
  743. });
  744. $DOM.toastBody.appendChild($DOM.inputs);
  745. }
  746. })();
  747. // Buttons
  748. (function(){
  749. if(settings.buttons.length > 0) {
  750. $DOM.buttons.classList.add(PLUGIN_NAME + '-buttons');
  751. forEach(settings.buttons, function (value, index) {
  752. $DOM.buttons.appendChild(createFragElem(value[0]));
  753. var $btns = $DOM.buttons.childNodes;
  754. $btns[index].classList.add(PLUGIN_NAME + '-buttons-child');
  755. if(value[2]){
  756. setTimeout(function() {
  757. $btns[index].focus();
  758. }, 300);
  759. }
  760. $btns[index].addEventListener('click', function (e) {
  761. e.preventDefault();
  762. var ts = value[1];
  763. return ts(that, $DOM.toast, this, e, $inputs);
  764. });
  765. });
  766. }
  767. $DOM.toastBody.appendChild($DOM.buttons);
  768. })();
  769. if(settings.message.length > 0 && (settings.inputs.length > 0 || settings.buttons.length > 0)) {
  770. $DOM.p.style.marginBottom = '0';
  771. }
  772. if(settings.inputs.length > 0 || settings.buttons.length > 0){
  773. if(settings.rtl){
  774. $DOM.toastTexts.style.marginLeft = '10px';
  775. } else {
  776. $DOM.toastTexts.style.marginRight = '10px';
  777. }
  778. if(settings.inputs.length > 0 && settings.buttons.length > 0){
  779. if(settings.rtl){
  780. $DOM.inputs.style.marginLeft = '8px';
  781. } else {
  782. $DOM.inputs.style.marginRight = '8px';
  783. }
  784. }
  785. }
  786. // Wrap
  787. (function(){
  788. $DOM.toastCapsule.style.visibility = 'hidden';
  789. setTimeout(function() {
  790. var H = $DOM.toast.offsetHeight;
  791. var style = $DOM.toast.currentStyle || window.getComputedStyle($DOM.toast);
  792. var marginTop = style.marginTop;
  793. marginTop = marginTop.split('px');
  794. marginTop = parseInt(marginTop[0]);
  795. var marginBottom = style.marginBottom;
  796. marginBottom = marginBottom.split('px');
  797. marginBottom = parseInt(marginBottom[0]);
  798. $DOM.toastCapsule.style.visibility = '';
  799. $DOM.toastCapsule.style.height = (H+marginBottom+marginTop)+'px';
  800. setTimeout(function() {
  801. $DOM.toastCapsule.style.height = 'auto';
  802. if(settings.target){
  803. $DOM.toastCapsule.style.overflow = 'visible';
  804. }
  805. }, 500);
  806. if(settings.timeout) {
  807. that.progress(settings, $DOM.toast).start();
  808. }
  809. }, 100);
  810. })();
  811. // Target
  812. (function(){
  813. var position = settings.position;
  814. if(settings.target){
  815. $DOM.wrapper = document.querySelector(settings.target);
  816. $DOM.wrapper.classList.add(PLUGIN_NAME + '-target');
  817. if(settings.targetFirst) {
  818. $DOM.wrapper.insertBefore($DOM.toastCapsule, $DOM.wrapper.firstChild);
  819. } else {
  820. $DOM.wrapper.appendChild($DOM.toastCapsule);
  821. }
  822. } else {
  823. if( POSITIONS.indexOf(settings.position) == -1 ){
  824. console.warn('['+PLUGIN_NAME+'] Incorrect position.\nIt can be › ' + POSITIONS);
  825. return;
  826. }
  827. if(ISMOBILE || window.innerWidth <= MOBILEWIDTH){
  828. if(settings.position == 'bottomLeft' || settings.position == 'bottomRight' || settings.position == 'bottomCenter'){
  829. position = PLUGIN_NAME+'-wrapper-bottomCenter';
  830. }
  831. else if(settings.position == 'topLeft' || settings.position == 'topRight' || settings.position == 'topCenter'){
  832. position = PLUGIN_NAME+'-wrapper-topCenter';
  833. }
  834. else {
  835. position = PLUGIN_NAME+'-wrapper-center';
  836. }
  837. } else {
  838. position = PLUGIN_NAME+'-wrapper-'+position;
  839. }
  840. $DOM.wrapper = document.querySelector('.' + PLUGIN_NAME + '-wrapper.'+position);
  841. if(!$DOM.wrapper) {
  842. $DOM.wrapper = document.createElement('div');
  843. $DOM.wrapper.classList.add(PLUGIN_NAME + '-wrapper');
  844. $DOM.wrapper.classList.add(position);
  845. document.body.appendChild($DOM.wrapper);
  846. }
  847. if(settings.position == 'topLeft' || settings.position == 'topCenter' || settings.position == 'topRight'){
  848. $DOM.wrapper.insertBefore($DOM.toastCapsule, $DOM.wrapper.firstChild);
  849. } else {
  850. $DOM.wrapper.appendChild($DOM.toastCapsule);
  851. }
  852. }
  853. if(!isNaN(settings.zindex)) {
  854. $DOM.wrapper.style.zIndex = settings.zindex;
  855. } else {
  856. console.warn('['+PLUGIN_NAME+'] Invalid zIndex.');
  857. }
  858. })();
  859. // Overlay
  860. (function(){
  861. if(settings.overlay) {
  862. if( document.querySelector('.'+PLUGIN_NAME+'-overlay.fadeIn') !== null ){
  863. $DOM.overlay = document.querySelector('.'+PLUGIN_NAME+'-overlay');
  864. $DOM.overlay.setAttribute('data-iziToast-ref', $DOM.overlay.getAttribute('data-iziToast-ref') + ',' + settings.ref);
  865. if(!isNaN(settings.zindex) && settings.zindex !== null) {
  866. $DOM.overlay.style.zIndex = settings.zindex-1;
  867. }
  868. } else {
  869. $DOM.overlay.classList.add(PLUGIN_NAME+'-overlay');
  870. $DOM.overlay.classList.add('fadeIn');
  871. $DOM.overlay.style.background = settings.overlayColor;
  872. $DOM.overlay.setAttribute('data-iziToast-ref', settings.ref);
  873. if(!isNaN(settings.zindex) && settings.zindex !== null) {
  874. $DOM.overlay.style.zIndex = settings.zindex-1;
  875. }
  876. document.querySelector('body').appendChild($DOM.overlay);
  877. }
  878. if(settings.overlayClose) {
  879. $DOM.overlay.removeEventListener('click', {});
  880. $DOM.overlay.addEventListener('click', function (e) {
  881. that.hide(settings, $DOM.toast, 'overlay');
  882. });
  883. } else {
  884. $DOM.overlay.removeEventListener('click', {});
  885. }
  886. }
  887. })();
  888. // Inside animations
  889. (function(){
  890. if(settings.animateInside){
  891. $DOM.toast.classList.add(PLUGIN_NAME+'-animateInside');
  892. var animationTimes = [200, 100, 300];
  893. if(settings.transitionIn == 'bounceInLeft' || settings.transitionIn == 'bounceInRight'){
  894. animationTimes = [400, 200, 400];
  895. }
  896. if(settings.title.length > 0) {
  897. setTimeout(function(){
  898. $DOM.strong.classList.add('slideIn');
  899. }, animationTimes[0]);
  900. }
  901. if(settings.message.length > 0) {
  902. setTimeout(function(){
  903. $DOM.p.classList.add('slideIn');
  904. }, animationTimes[1]);
  905. }
  906. if(settings.icon) {
  907. setTimeout(function(){
  908. $DOM.icon.classList.add('revealIn');
  909. }, animationTimes[2]);
  910. }
  911. var counter = 150;
  912. if(settings.buttons.length > 0 && $DOM.buttons) {
  913. setTimeout(function(){
  914. forEach($DOM.buttons.childNodes, function(element, index) {
  915. setTimeout(function(){
  916. element.classList.add('revealIn');
  917. }, counter);
  918. counter = counter + 150;
  919. });
  920. }, settings.inputs.length > 0 ? 150 : 0);
  921. }
  922. if(settings.inputs.length > 0 && $DOM.inputs) {
  923. counter = 150;
  924. forEach($DOM.inputs.childNodes, function(element, index) {
  925. setTimeout(function(){
  926. element.classList.add('revealIn');
  927. }, counter);
  928. counter = counter + 150;
  929. });
  930. }
  931. }
  932. })();
  933. settings.onOpening.apply(null, [settings, $DOM.toast]);
  934. try {
  935. var event = new CustomEvent(PLUGIN_NAME + '-opening', {detail: settings, bubbles: true, cancelable: true});
  936. document.dispatchEvent(event);
  937. } catch(ex){
  938. console.warn(ex);
  939. }
  940. setTimeout(function() {
  941. $DOM.toast.classList.remove(PLUGIN_NAME+'-opening');
  942. $DOM.toast.classList.add(PLUGIN_NAME+'-opened');
  943. try {
  944. var event = new CustomEvent(PLUGIN_NAME + '-opened', {detail: settings, bubbles: true, cancelable: true});
  945. document.dispatchEvent(event);
  946. } catch(ex){
  947. console.warn(ex);
  948. }
  949. settings.onOpened.apply(null, [settings, $DOM.toast]);
  950. }, 1000);
  951. if(settings.drag){
  952. if(ACCEPTSTOUCH) {
  953. $DOM.toast.addEventListener('touchstart', function(e) {
  954. drag.startMoving(this, that, settings, e);
  955. }, false);
  956. $DOM.toast.addEventListener('touchend', function(e) {
  957. drag.stopMoving(this, e);
  958. }, false);
  959. } else {
  960. $DOM.toast.addEventListener('mousedown', function(e) {
  961. e.preventDefault();
  962. drag.startMoving(this, that, settings, e);
  963. }, false);
  964. $DOM.toast.addEventListener('mouseup', function(e) {
  965. e.preventDefault();
  966. drag.stopMoving(this, e);
  967. }, false);
  968. }
  969. }
  970. if(settings.closeOnEscape) {
  971. document.addEventListener('keyup', function (evt) {
  972. evt = evt || window.event;
  973. if(evt.keyCode == 27) {
  974. that.hide(settings, $DOM.toast, 'esc');
  975. }
  976. });
  977. }
  978. if(settings.closeOnClick) {
  979. $DOM.toast.addEventListener('click', function (evt) {
  980. that.hide(settings, $DOM.toast, 'toast');
  981. });
  982. }
  983. that.toast = $DOM.toast;
  984. };
  985. return $iziToast;
  986. });