iziToast.js 33 KB

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