toast.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /**
  2. * DevExtreme (ui/toast.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var $ = require("../core/renderer");
  11. var window = require("../core/utils/window").getWindow();
  12. var domAdapter = require("../core/dom_adapter");
  13. var eventsEngine = require("../events/core/events_engine");
  14. var ready = require("../core/utils/ready_callbacks").add;
  15. var commonUtils = require("../core/utils/common");
  16. var typeUtils = require("../core/utils/type");
  17. var extend = require("../core/utils/extend").extend;
  18. var inArray = require("../core/utils/array").inArray;
  19. var pointerEvents = require("../events/pointer");
  20. var registerComponent = require("../core/component_registrator");
  21. var Overlay = require("./overlay");
  22. var themes = require("./themes");
  23. var TOAST_CLASS = "dx-toast";
  24. var TOAST_CLASS_PREFIX = TOAST_CLASS + "-";
  25. var TOAST_WRAPPER_CLASS = TOAST_CLASS_PREFIX + "wrapper";
  26. var TOAST_CONTENT_CLASS = TOAST_CLASS_PREFIX + "content";
  27. var TOAST_MESSAGE_CLASS = TOAST_CLASS_PREFIX + "message";
  28. var TOAST_ICON_CLASS = TOAST_CLASS_PREFIX + "icon";
  29. var WIDGET_NAME = "dxToast";
  30. var toastTypes = ["info", "warning", "error", "success"];
  31. var TOAST_STACK = [];
  32. var FIRST_Z_INDEX_OFFSET = 8e3;
  33. var visibleToastInstance = null;
  34. var POSITION_ALIASES = {
  35. top: {
  36. my: "top",
  37. at: "top",
  38. of: null,
  39. offset: "0 0"
  40. },
  41. bottom: {
  42. my: "bottom",
  43. at: "bottom",
  44. of: null,
  45. offset: "0 -20"
  46. },
  47. center: {
  48. my: "center",
  49. at: "center",
  50. of: null,
  51. offset: "0 0"
  52. },
  53. right: {
  54. my: "center right",
  55. at: "center right",
  56. of: null,
  57. offset: "0 0"
  58. },
  59. left: {
  60. my: "center left",
  61. at: "center left",
  62. of: null,
  63. offset: "0 0"
  64. }
  65. };
  66. ready(function() {
  67. eventsEngine.subscribeGlobal(domAdapter.getDocument(), pointerEvents.down, function(e) {
  68. for (var i = TOAST_STACK.length - 1; i >= 0; i--) {
  69. if (!TOAST_STACK[i]._proxiedDocumentDownHandler(e)) {
  70. return
  71. }
  72. }
  73. })
  74. });
  75. var Toast = Overlay.inherit({
  76. _getDefaultOptions: function() {
  77. return extend(this.callBase(), {
  78. message: "",
  79. type: "info",
  80. displayTime: 2e3,
  81. position: "bottom center",
  82. animation: {
  83. show: {
  84. type: "fade",
  85. duration: 400,
  86. from: 0,
  87. to: 1
  88. },
  89. hide: {
  90. type: "fade",
  91. duration: 400,
  92. to: 0
  93. }
  94. },
  95. shading: false,
  96. height: "auto",
  97. closeOnBackButton: false,
  98. closeOnSwipe: true,
  99. closeOnClick: false,
  100. resizeEnabled: false
  101. })
  102. },
  103. _defaultOptionsRules: function() {
  104. return this.callBase().concat([{
  105. device: function(_device) {
  106. return "win" === _device.platform && _device.version && 8 === _device.version[0]
  107. },
  108. options: {
  109. position: "top center",
  110. width: function() {
  111. return $(window).width()
  112. }
  113. }
  114. }, {
  115. device: function(_device2) {
  116. return "win" === _device2.platform && _device2.version && 10 === _device2.version[0]
  117. },
  118. options: {
  119. position: "bottom right",
  120. width: "auto"
  121. }
  122. }, {
  123. device: {
  124. platform: "android"
  125. },
  126. options: {
  127. closeOnOutsideClick: true,
  128. width: "auto",
  129. position: {
  130. at: "bottom left",
  131. my: "bottom left",
  132. offset: "20 -20"
  133. },
  134. animation: {
  135. show: {
  136. type: "slide",
  137. duration: 200,
  138. from: {
  139. position: {
  140. my: "top",
  141. at: "bottom",
  142. of: window
  143. }
  144. }
  145. },
  146. hide: {
  147. type: "slide",
  148. duration: 200,
  149. to: {
  150. position: {
  151. my: "top",
  152. at: "bottom",
  153. of: window
  154. }
  155. }
  156. }
  157. }
  158. }
  159. }, {
  160. device: function(_device3) {
  161. var isPhone = "phone" === _device3.deviceType;
  162. var isAndroid = "android" === _device3.platform;
  163. var isWin10 = "win" === _device3.platform && _device3.version && 10 === _device3.version[0];
  164. return isPhone && (isAndroid || isWin10)
  165. },
  166. options: {
  167. width: function() {
  168. return $(window).width()
  169. },
  170. position: {
  171. at: "bottom center",
  172. my: "bottom center",
  173. offset: "0 0"
  174. }
  175. }
  176. }, {
  177. device: function() {
  178. return themes.isMaterial()
  179. },
  180. options: {
  181. minWidth: 344,
  182. maxWidth: 568,
  183. displayTime: 4e3
  184. }
  185. }])
  186. },
  187. _init: function() {
  188. this.callBase();
  189. this._posStringToObject()
  190. },
  191. _renderContentImpl: function() {
  192. if (this.option("message")) {
  193. this._message = $("<div>").addClass(TOAST_MESSAGE_CLASS).text(this.option("message")).appendTo(this.$content())
  194. }
  195. this.setAria("role", "alert", this._message);
  196. if (inArray(this.option("type").toLowerCase(), toastTypes) > -1) {
  197. this.$content().prepend($("<div>").addClass(TOAST_ICON_CLASS))
  198. }
  199. this.callBase()
  200. },
  201. _render: function() {
  202. this.callBase();
  203. this.$element().addClass(TOAST_CLASS);
  204. this._wrapper().addClass(TOAST_WRAPPER_CLASS);
  205. this._$content.addClass(TOAST_CLASS_PREFIX + String(this.option("type")).toLowerCase());
  206. this.$content().addClass(TOAST_CONTENT_CLASS);
  207. this._toggleCloseEvents("Swipe");
  208. this._toggleCloseEvents("Click")
  209. },
  210. _renderScrollTerminator: commonUtils.noop,
  211. _toggleCloseEvents: function(event) {
  212. var dxEvent = "dx" + event.toLowerCase();
  213. eventsEngine.off(this._$content, dxEvent);
  214. this.option("closeOn" + event) && eventsEngine.on(this._$content, dxEvent, this.hide.bind(this))
  215. },
  216. _posStringToObject: function() {
  217. if (!typeUtils.isString(this.option("position"))) {
  218. return
  219. }
  220. var verticalPosition = this.option("position").split(" ")[0];
  221. var horizontalPosition = this.option("position").split(" ")[1];
  222. this.option("position", extend({}, POSITION_ALIASES[verticalPosition]));
  223. switch (horizontalPosition) {
  224. case "center":
  225. case "left":
  226. case "right":
  227. this.option("position").at += " " + horizontalPosition;
  228. this.option("position").my += " " + horizontalPosition
  229. }
  230. },
  231. _show: function() {
  232. if (visibleToastInstance && visibleToastInstance !== this) {
  233. clearTimeout(visibleToastInstance._hideTimeout);
  234. visibleToastInstance.hide()
  235. }
  236. visibleToastInstance = this;
  237. return this.callBase.apply(this, arguments).done(function() {
  238. clearTimeout(this._hideTimeout);
  239. this._hideTimeout = setTimeout(this.hide.bind(this), this.option("displayTime"))
  240. }.bind(this))
  241. },
  242. _hide: function() {
  243. visibleToastInstance = null;
  244. return this.callBase.apply(this, arguments)
  245. },
  246. _overlayStack: function() {
  247. return TOAST_STACK
  248. },
  249. _zIndexInitValue: function() {
  250. return this.callBase() + FIRST_Z_INDEX_OFFSET
  251. },
  252. _dispose: function() {
  253. clearTimeout(this._hideTimeout);
  254. visibleToastInstance = null;
  255. this.callBase()
  256. },
  257. _optionChanged: function(args) {
  258. switch (args.name) {
  259. case "type":
  260. this._$content.removeClass(TOAST_CLASS_PREFIX + args.previousValue);
  261. this._$content.addClass(TOAST_CLASS_PREFIX + String(args.value).toLowerCase());
  262. break;
  263. case "message":
  264. if (this._message) {
  265. this._message.text(args.value)
  266. }
  267. break;
  268. case "closeOnSwipe":
  269. this._toggleCloseEvents("Swipe");
  270. break;
  271. case "closeOnClick":
  272. this._toggleCloseEvents("Click");
  273. break;
  274. case "displayTime":
  275. case "position":
  276. break;
  277. default:
  278. this.callBase(args)
  279. }
  280. }
  281. });
  282. registerComponent(WIDGET_NAME, Toast);
  283. module.exports = Toast;
  284. module.exports.default = module.exports;