MDL-66828 core: Add toast-style notifications

Part of MDL-66074
This commit is contained in:
Andrew Nicols 2019-10-03 09:39:39 +08:00 committed by Mathew May
parent b253a4f21d
commit 224ea04e68
15 changed files with 135 additions and 1 deletions

2
lib/amd/build/toast.min.js vendored Normal file
View file

@ -0,0 +1,2 @@
define ("core/toast",["exports","core/templates","core/notification","core/pending"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.add=a.addToastRegion=void 0;b=e(b);c=e(c);d=e(d);function e(a){return a&&a.__esModule?a:{default:a}}function f(a){for(var b=1;b<arguments.length;b++){var c=null!=arguments[b]?arguments[b]:{},d=Object.keys(c);if("function"==typeof Object.getOwnPropertySymbols){d=d.concat(Object.getOwnPropertySymbols(c).filter(function(a){return Object.getOwnPropertyDescriptor(c,a).enumerable}))}d.forEach(function(b){g(a,b,c[b])})}return a}function g(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}function h(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function i(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function f(a){h(i,d,e,f,g,"next",a)}function g(a){h(i,d,e,f,g,"throw",a)}f(void 0)})}}var j=function(){var a=i(regeneratorRuntime.mark(function a(e){var f,g,h,i;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:f=new d.default("addToastRegion");a.prev=1;a.next=4;return b.default.renderForPromise("core/local/toast/wrapper",{});case 4:g=a.sent;h=g.html;i=g.js;b.default.prependNodeContents(e,h,i);a.next=13;break;case 10:a.prev=10;a.t0=a["catch"](1);c.default.exception(a.t0);case 13:f.resolve();case 14:case"end":return a.stop();}}},a,null,[[1,10]])}));return function(){return a.apply(this,arguments)}}();a.addToastRegion=j;var k=function(){var a=i(regeneratorRuntime.mark(function a(e,g){var h,i,j,k,m,n;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:h=new d.default("addToastRegion");g=f({closeButton:!1,autohide:!0,delay:4e3},g);i="core/local/toast/message";a.prev=3;a.next=6;return l();case 6:j=a.sent;a.next=9;return b.default.renderForPromise(i,f({message:e},g));case 9:k=a.sent;m=k.html;n=k.js;b.default.prependNodeContents(j,m,n);a.next=18;break;case 15:a.prev=15;a.t0=a["catch"](3);c.default.exception(a.t0);case 18:h.resolve();case 19:case"end":return a.stop();}}},a,null,[[3,15]])}));return function(){return a.apply(this,arguments)}}();a.add=k;var l=function(){var a=i(regeneratorRuntime.mark(function a(){var b;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:b=document.querySelector(".toast-wrapper");if(!b){a.next=3;break}return a.abrupt("return",b);case 3:a.next=5;return j(document.body,"fixed-bottom");case 5:return a.abrupt("return",l());case 6:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}()});
//# sourceMappingURL=toast.min.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":["../src/toast.js"],"names":["addToastRegion","parent","pendingPromise","Pending","Templates","renderForPromise","html","js","prependNodeContents","Notification","exception","resolve","add","message","configuration","closeButton","autohide","delay","templateName","getTargetNode","targetNode","region","document","querySelector","body"],"mappings":"mMAuBA,OACA,OACA,O,wzBAOO,GAAMA,CAAAA,CAAc,4CAAG,WAAMC,CAAN,+FACpBC,CADoB,CACH,GAAIC,UAAJ,CAAY,gBAAZ,CADG,yBAIGC,WAAUC,gBAAV,CAA2B,0BAA3B,CAAuD,EAAvD,CAJH,iBAIfC,CAJe,GAIfA,IAJe,CAITC,CAJS,GAITA,EAJS,CAKtBH,UAAUI,mBAAV,CAA8BP,CAA9B,CAAsCK,CAAtC,CAA4CC,CAA5C,EALsB,qDAOtBE,UAAaC,SAAb,OAPsB,QAU1BR,CAAc,CAACS,OAAf,GAV0B,uDAAH,uDAApB,C,mBAuBA,GAAMC,CAAAA,CAAG,4CAAG,WAAMC,CAAN,CAAeC,CAAf,mGACTZ,CADS,CACQ,GAAIC,UAAJ,CAAY,gBAAZ,CADR,CAEfW,CAAa,IACTC,WAAW,GADF,CAETC,QAAQ,GAFC,CAGTC,KAAK,CAAE,GAHE,EAINH,CAJM,CAAb,CAOMI,CATS,oDAWcC,CAAAA,CAAa,EAX3B,QAWLC,CAXK,uBAYchB,WAAUC,gBAAV,CAA2Ba,CAA3B,IACrBL,OAAO,CAAPA,CADqB,EAElBC,CAFkB,EAZd,iBAYJR,CAZI,GAYJA,IAZI,CAYEC,CAZF,GAYEA,EAZF,CAgBXH,UAAUI,mBAAV,CAA8BY,CAA9B,CAA0Cd,CAA1C,CAAgDC,CAAhD,EAhBW,qDAkBXE,UAAaC,SAAb,OAlBW,QAqBfR,CAAc,CAACS,OAAf,GArBe,uDAAH,uDAAT,C,QAwBP,GAAMQ,CAAAA,CAAa,4CAAG,oGACZE,CADY,CACHC,QAAQ,CAACC,aAAT,CAAuB,gBAAvB,CADG,KAGdF,CAHc,0CAIPA,CAJO,wBAOZrB,CAAAA,CAAc,CAACsB,QAAQ,CAACE,IAAV,CAAgB,cAAhB,CAPF,iCAQXL,CAAa,EARF,0CAAH,uD","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A system for displaying small snackbar notifications to users which disappear shortly after they are shown.\n *\n * @module core/toast\n * @package core\n * @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\n\n/**\n * Add a new region to place toasts in, taking in a parent element.\n *\n * @param {Element} parent\n */\nexport const addToastRegion = async(parent) => {\n const pendingPromise = new Pending('addToastRegion');\n\n try {\n const {html, js} = await Templates.renderForPromise('core/local/toast/wrapper', {});\n Templates.prependNodeContents(parent, html, js);\n } catch (e) {\n Notification.exception(e);\n }\n\n pendingPromise.resolve();\n};\n\n/**\n * Add a new toast or snackbar notification to the page.\n *\n * @param {String} message\n * @param {Object} configuration\n * @param {String} [configuration.title]\n * @param {String} [configuration.subtitle]\n * @param {Bool} [configuration.autohide=true]\n * @param {Number} [configuration.delay=4000]\n */\nexport const add = async(message, configuration) => {\n const pendingPromise = new Pending('addToastRegion');\n configuration = {\n closeButton: false,\n autohide: true,\n delay: 4000,\n ...configuration,\n };\n\n const templateName = `core/local/toast/message`;\n try {\n const targetNode = await getTargetNode();\n const {html, js} = await Templates.renderForPromise(templateName, {\n message,\n ...configuration\n });\n Templates.prependNodeContents(targetNode, html, js);\n } catch (e) {\n Notification.exception(e);\n }\n\n pendingPromise.resolve();\n};\n\nconst getTargetNode = async() => {\n const region = document.querySelector('.toast-wrapper');\n\n if (region) {\n return region;\n }\n\n await addToastRegion(document.body, 'fixed-bottom');\n return getTargetNode();\n};\n"],"file":"toast.min.js"}

89
lib/amd/src/toast.js Normal file
View file

@ -0,0 +1,89 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A system for displaying small snackbar notifications to users which disappear shortly after they are shown.
*
* @module core/toast
* @package core
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Templates from 'core/templates';
import Notification from 'core/notification';
import Pending from 'core/pending';
/**
* Add a new region to place toasts in, taking in a parent element.
*
* @param {Element} parent
*/
export const addToastRegion = async(parent) => {
const pendingPromise = new Pending('addToastRegion');
try {
const {html, js} = await Templates.renderForPromise('core/local/toast/wrapper', {});
Templates.prependNodeContents(parent, html, js);
} catch (e) {
Notification.exception(e);
}
pendingPromise.resolve();
};
/**
* Add a new toast or snackbar notification to the page.
*
* @param {String} message
* @param {Object} configuration
* @param {String} [configuration.title]
* @param {String} [configuration.subtitle]
* @param {Bool} [configuration.autohide=true]
* @param {Number} [configuration.delay=4000]
*/
export const add = async(message, configuration) => {
const pendingPromise = new Pending('addToastRegion');
configuration = {
closeButton: false,
autohide: true,
delay: 4000,
...configuration,
};
const templateName = `core/local/toast/message`;
try {
const targetNode = await getTargetNode();
const {html, js} = await Templates.renderForPromise(templateName, {
message,
...configuration
});
Templates.prependNodeContents(targetNode, html, js);
} catch (e) {
Notification.exception(e);
}
pendingPromise.resolve();
};
const getTargetNode = async() => {
const region = document.querySelector('.toast-wrapper');
if (region) {
return region;
}
await addToastRegion(document.body, 'fixed-bottom');
return getTargetNode();
};