From 730eff79951bc9da334d752eae8f81f882730882 Mon Sep 17 00:00:00 2001 From: Peter Savchenko Date: Mon, 15 Oct 2018 22:06:01 +0300 Subject: [PATCH] Page showing, page edit, move API to /api/ (#10) --- public/dist/editor.bundle.js | 2 +- public/dist/main.bundle.js | 2 +- public/dist/main.css | 2 +- src/frontend/js/classes/editor.js | 5 +- src/frontend/js/modules/writing.js | 24 ++++- src/frontend/styles/components/page.pcss | 57 +++++++++++ src/frontend/styles/main.pcss | 1 + src/frontend/styles/vars.pcss | 3 +- src/models/page.js | 18 ++-- src/routes/api/index.js | 8 ++ src/routes/api/pages.js | 115 ++++++++++++++++++++++ src/routes/index.js | 2 + src/routes/pages.js | 119 +++++------------------ src/views/pages/blocks/header.twig | 3 + src/views/pages/blocks/paragraph.twig | 3 + src/views/pages/form.twig | 25 +++-- src/views/pages/page.twig | 38 ++++++++ test/rest/pages.js | 22 ++--- 18 files changed, 316 insertions(+), 133 deletions(-) create mode 100644 src/frontend/styles/components/page.pcss create mode 100644 src/routes/api/index.js create mode 100644 src/routes/api/pages.js create mode 100644 src/views/pages/blocks/header.twig create mode 100644 src/views/pages/blocks/paragraph.twig create mode 100644 src/views/pages/page.twig diff --git a/public/dist/editor.bundle.js b/public/dist/editor.bundle.js index 0c2964b..6f48b28 100644 --- a/public/dist/editor.bundle.js +++ b/public/dist/editor.bundle.js @@ -2141,4 +2141,4 @@ var n=function(){function e(o){var t=o.data,s=(o.config,o.api);!function(e,o){if * @license The MIT License (MIT) * @version 2.0.0 */ -var n=function(){function e(o){var t=o.data,s=o.config,n=o.api;!function(e,o){if(!(e instanceof o))throw new TypeError("Cannot call a class as a function")}(this,e),this.api=n,this._CSS={block:this.api.styles.block,settingsButton:this.api.styles.settingsButton,settingsButtonActive:this.api.styles.settingsButtonActive,wrapper:"ce-header"},this._settings=s,this._data=t||{},this.settingsButtons=[],this._element=this.getTag()}return s(e,null,[{key:"displayInToolbox",get:function(){return!0}}]),s(e,[{key:"render",value:function(){return this._element}},{key:"renderSettings",value:function(){var e=this,o=document.createElement("DIV");return this.levels.forEach(function(t){var s=document.createElement("SPAN");s.classList.add(e._CSS.settingsButton),e.currentLevel.number===t.number&&s.classList.add(e._CSS.settingsButtonActive),s.innerHTML=t.svg,s.dataset.level=t.number,s.addEventListener("click",function(){e.setLevel(t.number)}),o.appendChild(s),e.settingsButtons.push(s)}),o}},{key:"setLevel",value:function(e){var o=this;this.data={level:e},this.settingsButtons.forEach(function(t){t.classList.toggle(o._CSS.settingsButtonActive,parseInt(t.dataset.level)===e)})}},{key:"merge",value:function(e){var o={text:this.data.text+e.text,level:this.data.level};this.data=o}},{key:"validate",value:function(e){return""!==e.text.trim()}},{key:"save",value:function(e){return{text:e.innerHTML,level:this.currentLevel.number}}},{key:"getTag",value:function(){var e=document.createElement(this.currentLevel.tag);return e.innerHTML=this._data.text||"",e.classList.add(this._CSS.wrapper),e.contentEditable="true",e.dataset.placeholder=this._settings.placeholder||"",e}},{key:"data",get:function(){return this._data.text=this._element.innerHTML,this._data.level=this.currentLevel.number,this._data},set:function(e){if(this._data=e||{},void 0!==e.level&&this._element.parentNode){var o=this.getTag();o.innerHTML=this._element.innerHTML,this._element.parentNode.replaceChild(o,this._element),this._element=o}void 0!==e.text&&(this._element.innerHTML=this._data.text||"")}},{key:"currentLevel",get:function(){var e=this,o=this.levels.find(function(o){return o.number===e._data.level});return o||(o=this.levels[0]),o}},{key:"levels",get:function(){return[{number:2,tag:"H2",svg:''},{number:3,tag:"H3",svg:''},{number:4,tag:"H4",svg:''}]}}],[{key:"onPasteHandler",value:function(e){var o=4;switch(e.tagName){case"H1":case"H2":o=2;break;case"H3":o=3}return{level:o,text:e.innerHTML}}},{key:"onPaste",get:function(){return{handler:e.onPasteHandler,tags:["H1","H2","H3","H4","H5","H6"]}}},{key:"toolboxIcon",get:function(){return''}}]),e}();e.exports=n},function(e,o,t){var s=t(2);"string"==typeof s&&(s=[[e.i,s,""]]),t(4)(s,{hmr:!0,transform:void 0,insertInto:void 0}),s.locals&&(e.exports=s.locals)},function(e,o,t){(e.exports=t(3)(!1)).push([e.i,"/**\n * Plugin styles\n */\n.ce-header {\n padding: 1em 0;\n margin: 0;\n margin-bottom: -0.9em;\n line-height: 1.5em;\n outline: none;\n}\n\n.ce-header p,\n.ce-header div{\n padding: 0 !important;\n margin: 0 !important;\n}\n\n/**\n * Styles for Plugin icon in Toolbar\n */\n.ce-header__icon {}\n",""])},function(e,o){e.exports=function(e){var o=[];return o.toString=function(){return this.map(function(o){var t=function(e,o){var t=e[1]||"",s=e[3];if(!s)return t;if(o&&"function"==typeof btoa){var n=function(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}(s),r=s.sources.map(function(e){return"/*# sourceURL="+s.sourceRoot+e+" */"});return[t].concat(r).concat([n]).join("\n")}return[t].join("\n")}(o,e);return o[2]?"@media "+o[2]+"{"+t+"}":t}).join("")},o.i=function(e,t){"string"==typeof e&&(e=[[null,e,""]]);for(var s={},n=0;n=0&&i.splice(o,1)}function j(e){var o=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),_(o,e.attrs),m(e,o),o}function _(e,o){Object.keys(o).forEach(function(t){e.setAttribute(t,o[t])})}function p(e,o){var t,s,n,r;if(o.transform&&e.css){if(!(r=o.transform(e.css)))return function(){};e.css=r}if(o.singleton){var i=u++;t=l||(l=j(o)),s=b.bind(null,t,i,!1),n=b.bind(null,t,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=function(e){var o=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",_(o,e.attrs),m(e,o),o}(o),s=function(e,o,t){var s=t.css,n=t.sourceMap,r=void 0===o.convertToAbsoluteUrls&&n;(o.convertToAbsoluteUrls||r)&&(s=d(s)),n&&(s+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(n))))+" */");var l=new Blob([s],{type:"text/css"}),u=e.href;e.href=URL.createObjectURL(l),u&&URL.revokeObjectURL(u)}.bind(null,t,o),n=function(){f(t),t.href&&URL.revokeObjectURL(t.href)}):(t=j(o),s=function(e,o){var t=o.css,s=o.media;if(s&&e.setAttribute("media",s),e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}.bind(null,t),n=function(){f(t)});return s(e),function(o){if(o){if(o.css===e.css&&o.media===e.media&&o.sourceMap===e.sourceMap)return;s(e=o)}else n()}}e.exports=function(e,o){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(o=o||{}).attrs="object"==typeof o.attrs?o.attrs:{},o.singleton||"boolean"==typeof o.singleton||(o.singleton=n()),o.insertInto||(o.insertInto="head"),o.insertAt||(o.insertAt="bottom");var t=a(e,o);return c(t,o),function(e){for(var n=[],r=0;r'},{number:3,tag:"H3",svg:''},{number:4,tag:"H4",svg:''}]}}],[{key:"onPasteHandler",value:function(e){var o=4;switch(e.tagName){case"H1":case"H2":o=2;break;case"H3":o=3}return{level:o,text:e.innerHTML}}},{key:"onPaste",get:function(){return{handler:e.onPasteHandler,tags:["H1","H2","H3","H4","H5","H6"]}}},{key:"toolboxIcon",get:function(){return''}}]),e}();e.exports=n},function(e,o,t){var s=t(2);"string"==typeof s&&(s=[[e.i,s,""]]),t(4)(s,{hmr:!0,transform:void 0,insertInto:void 0}),s.locals&&(e.exports=s.locals)},function(e,o,t){(e.exports=t(3)(!1)).push([e.i,"/**\n * Plugin styles\n */\n.ce-header {\n padding: 1em 0;\n margin: 0;\n margin-bottom: -0.9em;\n line-height: 1.5em;\n outline: none;\n}\n\n.ce-header p,\n.ce-header div{\n padding: 0 !important;\n margin: 0 !important;\n}\n\n/**\n * Styles for Plugin icon in Toolbar\n */\n.ce-header__icon {}\n",""])},function(e,o){e.exports=function(e){var o=[];return o.toString=function(){return this.map(function(o){var t=function(e,o){var t=e[1]||"",s=e[3];if(!s)return t;if(o&&"function"==typeof btoa){var n=function(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}(s),r=s.sources.map(function(e){return"/*# sourceURL="+s.sourceRoot+e+" */"});return[t].concat(r).concat([n]).join("\n")}return[t].join("\n")}(o,e);return o[2]?"@media "+o[2]+"{"+t+"}":t}).join("")},o.i=function(e,t){"string"==typeof e&&(e=[[null,e,""]]);for(var s={},n=0;n=0&&i.splice(o,1)}function j(e){var o=document.createElement("style");return void 0===e.attrs.type&&(e.attrs.type="text/css"),_(o,e.attrs),m(e,o),o}function _(e,o){Object.keys(o).forEach(function(t){e.setAttribute(t,o[t])})}function p(e,o){var t,s,n,r;if(o.transform&&e.css){if(!(r=o.transform(e.css)))return function(){};e.css=r}if(o.singleton){var i=u++;t=l||(l=j(o)),s=b.bind(null,t,i,!1),n=b.bind(null,t,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=function(e){var o=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",_(o,e.attrs),m(e,o),o}(o),s=function(e,o,t){var s=t.css,n=t.sourceMap,r=void 0===o.convertToAbsoluteUrls&&n;(o.convertToAbsoluteUrls||r)&&(s=d(s)),n&&(s+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(n))))+" */");var l=new Blob([s],{type:"text/css"}),u=e.href;e.href=URL.createObjectURL(l),u&&URL.revokeObjectURL(u)}.bind(null,t,o),n=function(){f(t),t.href&&URL.revokeObjectURL(t.href)}):(t=j(o),s=function(e,o){var t=o.css,s=o.media;if(s&&e.setAttribute("media",s),e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}.bind(null,t),n=function(){f(t)});return s(e),function(o){if(o){if(o.css===e.css&&o.media===e.media&&o.sourceMap===e.sourceMap)return;s(e=o)}else n()}}e.exports=function(e,o){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(o=o||{}).attrs="object"==typeof o.attrs?o.attrs:{},o.singleton||"boolean"==typeof o.singleton||(o.singleton=n()),o.insertInto||(o.insertInto="head"),o.insertAt||(o.insertAt="bottom");var t=a(e,o);return c(t,o),function(e){for(var n=[],r=0;r=0;o--)e.push.apply(e,r(this.extractModulesData(n[o])));return e}},{key:"extractModulesData",value:function(t){var e=this,n=[],r=t.dataset.module;return(r=r.replace(/\s+/," ")).split(" ").forEach(function(r,o){var i=new a({name:r,element:t,settings:e.getModuleSettings(t,o,r),moduleClass:e.Library[r]});n.push(i)}),n}},{key:"getModuleSettings",value:function(t,e,n){var r=t.querySelector("module-settings"),o=void 0;if(!r)return null;try{o=r.textContent.trim(),o=JSON.parse(o)}catch(t){return console.warn("Can not parse Module «"+n+"» settings bacause of: "+t),console.groupCollapsed(n+" settings"),console.log(o),console.groupEnd(),null}return Array.isArray(o)?o[e]?o[e]:null:0===e?o:(console.warn("Wrong settings format. For several Modules use an array instead of object."),null)}},{key:"initModules",value:function(){console.groupCollapsed("ModuleDispatcher"),this.modules.forEach(function(t){t.init()}),console.groupEnd()}}]),t}();e.default=u}])},function(t,e,n){t.exports=!n(5)&&!n(13)(function(){return 7!=Object.defineProperty(n(14)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(4);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){},,function(t,e,n){"use strict";var r,o,i,a,u=n(18),c=n(0),s=n(7),f=n(19),l=n(11),h=n(4),p=n(8),d=n(31),v=n(32),y=n(38),m=n(21).set,g=n(41)(),w=n(22),x=n(42),b=n(43),_=n(44),j=c.TypeError,E=c.process,P=E&&E.versions,S=P&&P.v8||"",O=c.Promise,k="process"==f(E),L=function(){},M=o=w.f,T=!!function(){try{var t=O.resolve(1),e=(t.constructor={})[n(1)("species")]=function(t){t(L,L)};return(k||"function"==typeof PromiseRejectionEvent)&&t.then(L)instanceof e&&0!==S.indexOf("6.6")&&-1===b.indexOf("Chrome/66")}catch(t){}}(),C=function(t){var e;return!(!h(t)||"function"!=typeof(e=t.then))&&e},F=function(t,e){if(!t._n){t._n=!0;var n=t._c;g(function(){for(var r=t._v,o=1==t._s,i=0,a=function(e){var n,i,a,u=o?e.ok:e.fail,c=e.resolve,s=e.reject,f=e.domain;try{u?(o||(2==t._h&&R(t),t._h=1),!0===u?n=r:(f&&f.enter(),n=u(r),f&&(f.exit(),a=!0)),n===e.promise?s(j("Promise-chain cycle")):(i=C(n))?i.call(n,c,s):c(n)):s(r)}catch(t){f&&!a&&f.exit(),s(t)}};n.length>i;)a(n[i++]);t._c=[],t._n=!1,e&&!t._h&&A(t)})}},A=function(t){m.call(c,function(){var e,n,r,o=t._v,i=N(t);if(i&&(e=x(function(){k?E.emit("unhandledRejection",o,t):(n=c.onunhandledrejection)?n({promise:t,reason:o}):(r=c.console)&&r.error&&r.error("Unhandled promise rejection",o)}),t._h=k||N(t)?2:1),t._a=void 0,i&&e.e)throw e.v})},N=function(t){return 1!==t._h&&0===(t._a||t._c).length},R=function(t){m.call(c,function(){var e;k?E.emit("rejectionHandled",t):(e=c.onrejectionhandled)&&e({promise:t,reason:t._v})})},D=function(t){var e=this;e._d||(e._d=!0,(e=e._w||e)._v=t,e._s=2,e._a||(e._a=e._c.slice()),F(e,!0))},G=function(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw j("Promise can't be resolved itself");(e=C(t))?g(function(){var r={_w:n,_d:!1};try{e.call(t,s(G,r,1),s(D,r,1))}catch(t){D.call(r,t)}}):(n._v=t,n._s=1,F(n,!1))}catch(t){D.call({_w:n,_d:!1},t)}}};T||(O=function(t){d(this,O,"Promise","_h"),p(t),r.call(this);try{t(s(G,this,1),s(D,this,1))}catch(t){D.call(this,t)}},(r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=n(45)(O.prototype,{then:function(t,e){var n=M(y(this,O));return n.ok="function"!=typeof t||t,n.fail="function"==typeof e&&e,n.domain=k?E.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&F(this,!1),n.promise},catch:function(t){return this.then(void 0,t)}}),i=function(){var t=new r;this.promise=t,this.resolve=s(G,t,1),this.reject=s(D,t,1)},w.f=M=function(t){return t===O||t===a?new i(t):o(t)}),l(l.G+l.W+l.F*!T,{Promise:O}),n(46)(O,"Promise"),n(47)("Promise"),a=n(2).Promise,l(l.S+l.F*!T,"Promise",{reject:function(t){var e=M(this);return(0,e.reject)(t),e.promise}}),l(l.S+l.F*(u||!T),"Promise",{resolve:function(t){return _(u&&this===a?O:this,t)}}),l(l.S+l.F*!(T&&n(48)(function(t){O.all(t).catch(L)})),"Promise",{all:function(t){var e=this,n=M(e),r=n.resolve,o=n.reject,i=x(function(){var n=[],i=0,a=1;v(t,!1,function(t){var u=i++,c=!1;n.push(void 0),a++,e.resolve(t).then(function(t){c||(c=!0,n[u]=t,--a||r(n))},o)}),--a||r(n)});return i.e&&o(i.v),n.promise},race:function(t){var e=this,n=M(e),r=n.reject,o=x(function(){v(t,!1,function(t){e.resolve(t).then(n.resolve,r)})});return o.e&&r(o.v),n.promise}})},function(t,e,n){var r=n(2),o=n(0),i=o["__core-js_shared__"]||(o["__core-js_shared__"]={});(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n(18)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(t,e){t.exports=function(t,e,n,r){if(!(t instanceof e)||void 0!==r&&r in t)throw TypeError(n+": incorrect invocation!");return t}},function(t,e,n){var r=n(7),o=n(33),i=n(34),a=n(3),u=n(35),c=n(37),s={},f={};(e=t.exports=function(t,e,n,l,h){var p,d,v,y,m=h?function(){return t}:c(t),g=r(n,l,e?2:1),w=0;if("function"!=typeof m)throw TypeError(t+" is not iterable!");if(i(m)){for(p=u(t.length);p>w;w++)if((y=e?g(a(d=t[w])[0],d[1]):g(t[w]))===s||y===f)return y}else for(v=m.call(t);!(d=v.next()).done;)if((y=o(v,g,d.value,e))===s||y===f)return y}).BREAK=s,e.RETURN=f},function(t,e,n){var r=n(3);t.exports=function(t,e,n,o){try{return o?e(r(n)[0],n[1]):e(n)}catch(e){var i=t.return;throw void 0!==i&&r(i.call(t)),e}}},function(t,e,n){var r=n(20),o=n(1)("iterator"),i=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||i[o]===t)}},function(t,e,n){var r=n(36),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(19),o=n(1)("iterator"),i=n(20);t.exports=n(2).getIteratorMethod=function(t){if(void 0!=t)return t[o]||t["@@iterator"]||i[r(t)]}},function(t,e,n){var r=n(3),o=n(8),i=n(1)("species");t.exports=function(t,e){var n,a=r(t).constructor;return void 0===a||void 0==(n=r(a)[i])?e:o(n)}},function(t,e){t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},function(t,e,n){var r=n(0).document;t.exports=r&&r.documentElement},function(t,e,n){var r=n(0),o=n(21).set,i=r.MutationObserver||r.WebKitMutationObserver,a=r.process,u=r.Promise,c="process"==n(9)(a);t.exports=function(){var t,e,n,s=function(){var r,o;for(c&&(r=a.domain)&&r.exit();t;){o=t.fn,t=t.next;try{o()}catch(r){throw t?n():e=void 0,r}}e=void 0,r&&r.enter()};if(c)n=function(){a.nextTick(s)};else if(!i||r.navigator&&r.navigator.standalone)if(u&&u.resolve){var f=u.resolve(void 0);n=function(){f.then(s)}}else n=function(){o.call(r,s)};else{var l=!0,h=document.createTextNode("");new i(s).observe(h,{characterData:!0}),n=function(){h.data=l=!l}}return function(r){var o={fn:r,next:void 0};e&&(e.next=o),t||(t=o,n()),e=o}}},function(t,e){t.exports=function(t){try{return{e:!1,v:t()}}catch(t){return{e:!0,v:t}}}},function(t,e,n){var r=n(0).navigator;t.exports=r&&r.userAgent||""},function(t,e,n){var r=n(3),o=n(4),i=n(22);t.exports=function(t,e){if(r(t),o(e)&&e.constructor===t)return e;var n=i.f(t);return(0,n.resolve)(e),n.promise}},function(t,e,n){var r=n(15);t.exports=function(t,e,n){for(var o in e)r(t,o,e[o],n);return t}},function(t,e,n){var r=n(6).f,o=n(16),i=n(1)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},function(t,e,n){"use strict";var r=n(0),o=n(6),i=n(5),a=n(1)("species");t.exports=function(t){var e=r[t];i&&e&&!e[a]&&o.f(e,a,{configurable:!0,get:function(){return this}})}},function(t,e,n){var r=n(1)("iterator"),o=!1;try{var i=[7][r]();i.return=function(){o=!0},Array.from(i,function(){throw 2})}catch(t){}t.exports=function(t,e){if(!e&&!o)return!1;var n=!1;try{var i=[7],a=i[r]();a.next=function(){return{done:n=!0}},i[r]=function(){return a},t(i)}catch(t){}return n}},function(t,e){!function(e){"use strict";var n,r=Object.prototype,o=r.hasOwnProperty,i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",u=i.asyncIterator||"@@asyncIterator",c=i.toStringTag||"@@toStringTag",s="object"==typeof t,f=e.regeneratorRuntime;if(f)s&&(t.exports=f);else{(f=e.regeneratorRuntime=s?t.exports:{}).wrap=x;var l="suspendedStart",h="suspendedYield",p="executing",d="completed",v={},y={};y[a]=function(){return this};var m=Object.getPrototypeOf,g=m&&m(m(T([])));g&&g!==r&&o.call(g,a)&&(y=g);var w=E.prototype=_.prototype=Object.create(y);j.prototype=w.constructor=E,E.constructor=j,E[c]=j.displayName="GeneratorFunction",f.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===j||"GeneratorFunction"===(e.displayName||e.name))},f.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,E):(t.__proto__=E,c in t||(t[c]="GeneratorFunction")),t.prototype=Object.create(w),t},f.awrap=function(t){return{__await:t}},P(S.prototype),S.prototype[u]=function(){return this},f.AsyncIterator=S,f.async=function(t,e,n,r){var o=new S(x(t,e,n,r));return f.isGeneratorFunction(e)?o:o.next().then(function(t){return t.done?t.value:o.next()})},P(w),w[c]="Generator",w[a]=function(){return this},w.toString=function(){return"[object Generator]"},f.keys=function(t){var e=[];for(var n in t)e.push(n);return e.reverse(),function n(){for(;e.length;){var r=e.pop();if(r in t)return n.value=r,n.done=!1,n}return n.done=!0,n}},f.values=T,M.prototype={constructor:M,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=n,this.done=!1,this.delegate=null,this.method="next",this.arg=n,this.tryEntries.forEach(L),!t)for(var e in this)"t"===e.charAt(0)&&o.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=n)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function r(r,o){return u.type="throw",u.arg=t,e.next=r,o&&(e.method="next",e.arg=n),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],u=a.completion;if("root"===a.tryLoc)return r("end");if(a.tryLoc<=this.prev){var c=o.call(a,"catchLoc"),s=o.call(a,"finallyLoc");if(c&&s){if(this.prev=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),L(n),v}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var o=r.arg;L(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,r){return this.delegate={iterator:T(t),resultName:e,nextLoc:r},"next"===this.method&&(this.arg=n),v}}}function x(t,e,n,r){var o=e&&e.prototype instanceof _?e:_,i=Object.create(o.prototype),a=new M(r||[]);return i._invoke=function(t,e,n){var r=l;return function(o,i){if(r===p)throw new Error("Generator is already running");if(r===d){if("throw"===o)throw i;return C()}for(n.method=o,n.arg=i;;){var a=n.delegate;if(a){var u=O(a,n);if(u){if(u===v)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===l)throw r=d,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var c=b(t,e,n);if("normal"===c.type){if(r=n.done?d:h,c.arg===v)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(r=d,n.method="throw",n.arg=c.arg)}}}(t,n,a),i}function b(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}function _(){}function j(){}function E(){}function P(t){["next","throw","return"].forEach(function(e){t[e]=function(t){return this._invoke(e,t)}})}function S(t){var e;this._invoke=function(n,r){function i(){return new Promise(function(e,i){!function e(n,r,i,a){var u=b(t[n],t,r);if("throw"!==u.type){var c=u.arg,s=c.value;return s&&"object"==typeof s&&o.call(s,"__await")?Promise.resolve(s.__await).then(function(t){e("next",t,i,a)},function(t){e("throw",t,i,a)}):Promise.resolve(s).then(function(t){c.value=t,i(c)},a)}a(u.arg)}(n,r,e,i)})}return e=e?e.then(i,i):i()}}function O(t,e){var r=t.iterator[e.method];if(r===n){if(e.delegate=null,"throw"===e.method){if(t.iterator.return&&(e.method="return",e.arg=n,O(t,e),"throw"===e.method))return v;e.method="throw",e.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var o=b(r,t.iterator,e.arg);if("throw"===o.type)return e.method="throw",e.arg=o.arg,e.delegate=null,v;var i=o.arg;return i?i.done?(e[t.resultName]=i.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=n),e.delegate=null,v):i:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,v)}function k(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function L(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function M(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0)}function T(t){if(t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,i=function e(){for(;++r=0;o--)e.push.apply(e,r(this.extractModulesData(n[o])));return e}},{key:"extractModulesData",value:function(t){var e=this,n=[],r=t.dataset.module;return(r=r.replace(/\s+/," ")).split(" ").forEach(function(r,o){var i=new a({name:r,element:t,settings:e.getModuleSettings(t,o,r),moduleClass:e.Library[r]});n.push(i)}),n}},{key:"getModuleSettings",value:function(t,e,n){var r=t.querySelector("module-settings"),o=void 0;if(!r)return null;try{o=r.textContent.trim(),o=JSON.parse(o)}catch(t){return console.warn("Can not parse Module «"+n+"» settings bacause of: "+t),console.groupCollapsed(n+" settings"),console.log(o),console.groupEnd(),null}return Array.isArray(o)?o[e]?o[e]:null:0===e?o:(console.warn("Wrong settings format. For several Modules use an array instead of object."),null)}},{key:"initModules",value:function(){console.groupCollapsed("ModuleDispatcher"),this.modules.forEach(function(t){t.init()}),console.groupEnd()}}]),t}();e.default=u}])},function(t,e,n){t.exports=!n(5)&&!n(13)(function(){return 7!=Object.defineProperty(n(14)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(4);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){},,function(t,e,n){"use strict";var r,o,i,a,u=n(18),c=n(0),s=n(7),f=n(19),l=n(11),h=n(4),p=n(8),d=n(31),v=n(32),y=n(38),m=n(21).set,g=n(41)(),w=n(22),x=n(42),b=n(43),_=n(44),j=c.TypeError,E=c.process,P=E&&E.versions,S=P&&P.v8||"",O=c.Promise,k="process"==f(E),L=function(){},M=o=w.f,T=!!function(){try{var t=O.resolve(1),e=(t.constructor={})[n(1)("species")]=function(t){t(L,L)};return(k||"function"==typeof PromiseRejectionEvent)&&t.then(L)instanceof e&&0!==S.indexOf("6.6")&&-1===b.indexOf("Chrome/66")}catch(t){}}(),C=function(t){var e;return!(!h(t)||"function"!=typeof(e=t.then))&&e},F=function(t,e){if(!t._n){t._n=!0;var n=t._c;g(function(){for(var r=t._v,o=1==t._s,i=0,a=function(e){var n,i,a,u=o?e.ok:e.fail,c=e.resolve,s=e.reject,f=e.domain;try{u?(o||(2==t._h&&N(t),t._h=1),!0===u?n=r:(f&&f.enter(),n=u(r),f&&(f.exit(),a=!0)),n===e.promise?s(j("Promise-chain cycle")):(i=C(n))?i.call(n,c,s):c(n)):s(r)}catch(t){f&&!a&&f.exit(),s(t)}};n.length>i;)a(n[i++]);t._c=[],t._n=!1,e&&!t._h&&A(t)})}},A=function(t){m.call(c,function(){var e,n,r,o=t._v,i=D(t);if(i&&(e=x(function(){k?E.emit("unhandledRejection",o,t):(n=c.onunhandledrejection)?n({promise:t,reason:o}):(r=c.console)&&r.error&&r.error("Unhandled promise rejection",o)}),t._h=k||D(t)?2:1),t._a=void 0,i&&e.e)throw e.v})},D=function(t){return 1!==t._h&&0===(t._a||t._c).length},N=function(t){m.call(c,function(){var e;k?E.emit("rejectionHandled",t):(e=c.onrejectionhandled)&&e({promise:t,reason:t._v})})},R=function(t){var e=this;e._d||(e._d=!0,(e=e._w||e)._v=t,e._s=2,e._a||(e._a=e._c.slice()),F(e,!0))},G=function(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw j("Promise can't be resolved itself");(e=C(t))?g(function(){var r={_w:n,_d:!1};try{e.call(t,s(G,r,1),s(R,r,1))}catch(t){R.call(r,t)}}):(n._v=t,n._s=1,F(n,!1))}catch(t){R.call({_w:n,_d:!1},t)}}};T||(O=function(t){d(this,O,"Promise","_h"),p(t),r.call(this);try{t(s(G,this,1),s(R,this,1))}catch(t){R.call(this,t)}},(r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=n(45)(O.prototype,{then:function(t,e){var n=M(y(this,O));return n.ok="function"!=typeof t||t,n.fail="function"==typeof e&&e,n.domain=k?E.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&F(this,!1),n.promise},catch:function(t){return this.then(void 0,t)}}),i=function(){var t=new r;this.promise=t,this.resolve=s(G,t,1),this.reject=s(R,t,1)},w.f=M=function(t){return t===O||t===a?new i(t):o(t)}),l(l.G+l.W+l.F*!T,{Promise:O}),n(46)(O,"Promise"),n(47)("Promise"),a=n(2).Promise,l(l.S+l.F*!T,"Promise",{reject:function(t){var e=M(this);return(0,e.reject)(t),e.promise}}),l(l.S+l.F*(u||!T),"Promise",{resolve:function(t){return _(u&&this===a?O:this,t)}}),l(l.S+l.F*!(T&&n(48)(function(t){O.all(t).catch(L)})),"Promise",{all:function(t){var e=this,n=M(e),r=n.resolve,o=n.reject,i=x(function(){var n=[],i=0,a=1;v(t,!1,function(t){var u=i++,c=!1;n.push(void 0),a++,e.resolve(t).then(function(t){c||(c=!0,n[u]=t,--a||r(n))},o)}),--a||r(n)});return i.e&&o(i.v),n.promise},race:function(t){var e=this,n=M(e),r=n.reject,o=x(function(){v(t,!1,function(t){e.resolve(t).then(n.resolve,r)})});return o.e&&r(o.v),n.promise}})},function(t,e,n){var r=n(2),o=n(0),i=o["__core-js_shared__"]||(o["__core-js_shared__"]={});(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n(18)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(t,e){t.exports=function(t,e,n,r){if(!(t instanceof e)||void 0!==r&&r in t)throw TypeError(n+": incorrect invocation!");return t}},function(t,e,n){var r=n(7),o=n(33),i=n(34),a=n(3),u=n(35),c=n(37),s={},f={};(e=t.exports=function(t,e,n,l,h){var p,d,v,y,m=h?function(){return t}:c(t),g=r(n,l,e?2:1),w=0;if("function"!=typeof m)throw TypeError(t+" is not iterable!");if(i(m)){for(p=u(t.length);p>w;w++)if((y=e?g(a(d=t[w])[0],d[1]):g(t[w]))===s||y===f)return y}else for(v=m.call(t);!(d=v.next()).done;)if((y=o(v,g,d.value,e))===s||y===f)return y}).BREAK=s,e.RETURN=f},function(t,e,n){var r=n(3);t.exports=function(t,e,n,o){try{return o?e(r(n)[0],n[1]):e(n)}catch(e){var i=t.return;throw void 0!==i&&r(i.call(t)),e}}},function(t,e,n){var r=n(20),o=n(1)("iterator"),i=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||i[o]===t)}},function(t,e,n){var r=n(36),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(19),o=n(1)("iterator"),i=n(20);t.exports=n(2).getIteratorMethod=function(t){if(void 0!=t)return t[o]||t["@@iterator"]||i[r(t)]}},function(t,e,n){var r=n(3),o=n(8),i=n(1)("species");t.exports=function(t,e){var n,a=r(t).constructor;return void 0===a||void 0==(n=r(a)[i])?e:o(n)}},function(t,e){t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},function(t,e,n){var r=n(0).document;t.exports=r&&r.documentElement},function(t,e,n){var r=n(0),o=n(21).set,i=r.MutationObserver||r.WebKitMutationObserver,a=r.process,u=r.Promise,c="process"==n(9)(a);t.exports=function(){var t,e,n,s=function(){var r,o;for(c&&(r=a.domain)&&r.exit();t;){o=t.fn,t=t.next;try{o()}catch(r){throw t?n():e=void 0,r}}e=void 0,r&&r.enter()};if(c)n=function(){a.nextTick(s)};else if(!i||r.navigator&&r.navigator.standalone)if(u&&u.resolve){var f=u.resolve(void 0);n=function(){f.then(s)}}else n=function(){o.call(r,s)};else{var l=!0,h=document.createTextNode("");new i(s).observe(h,{characterData:!0}),n=function(){h.data=l=!l}}return function(r){var o={fn:r,next:void 0};e&&(e.next=o),t||(t=o,n()),e=o}}},function(t,e){t.exports=function(t){try{return{e:!1,v:t()}}catch(t){return{e:!0,v:t}}}},function(t,e,n){var r=n(0).navigator;t.exports=r&&r.userAgent||""},function(t,e,n){var r=n(3),o=n(4),i=n(22);t.exports=function(t,e){if(r(t),o(e)&&e.constructor===t)return e;var n=i.f(t);return(0,n.resolve)(e),n.promise}},function(t,e,n){var r=n(15);t.exports=function(t,e,n){for(var o in e)r(t,o,e[o],n);return t}},function(t,e,n){var r=n(6).f,o=n(16),i=n(1)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},function(t,e,n){"use strict";var r=n(0),o=n(6),i=n(5),a=n(1)("species");t.exports=function(t){var e=r[t];i&&e&&!e[a]&&o.f(e,a,{configurable:!0,get:function(){return this}})}},function(t,e,n){var r=n(1)("iterator"),o=!1;try{var i=[7][r]();i.return=function(){o=!0},Array.from(i,function(){throw 2})}catch(t){}t.exports=function(t,e){if(!e&&!o)return!1;var n=!1;try{var i=[7],a=i[r]();a.next=function(){return{done:n=!0}},i[r]=function(){return a},t(i)}catch(t){}return n}},function(t,e){!function(e){"use strict";var n,r=Object.prototype,o=r.hasOwnProperty,i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",u=i.asyncIterator||"@@asyncIterator",c=i.toStringTag||"@@toStringTag",s="object"==typeof t,f=e.regeneratorRuntime;if(f)s&&(t.exports=f);else{(f=e.regeneratorRuntime=s?t.exports:{}).wrap=x;var l="suspendedStart",h="suspendedYield",p="executing",d="completed",v={},y={};y[a]=function(){return this};var m=Object.getPrototypeOf,g=m&&m(m(T([])));g&&g!==r&&o.call(g,a)&&(y=g);var w=E.prototype=_.prototype=Object.create(y);j.prototype=w.constructor=E,E.constructor=j,E[c]=j.displayName="GeneratorFunction",f.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===j||"GeneratorFunction"===(e.displayName||e.name))},f.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,E):(t.__proto__=E,c in t||(t[c]="GeneratorFunction")),t.prototype=Object.create(w),t},f.awrap=function(t){return{__await:t}},P(S.prototype),S.prototype[u]=function(){return this},f.AsyncIterator=S,f.async=function(t,e,n,r){var o=new S(x(t,e,n,r));return f.isGeneratorFunction(e)?o:o.next().then(function(t){return t.done?t.value:o.next()})},P(w),w[c]="Generator",w[a]=function(){return this},w.toString=function(){return"[object Generator]"},f.keys=function(t){var e=[];for(var n in t)e.push(n);return e.reverse(),function n(){for(;e.length;){var r=e.pop();if(r in t)return n.value=r,n.done=!1,n}return n.done=!0,n}},f.values=T,M.prototype={constructor:M,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=n,this.done=!1,this.delegate=null,this.method="next",this.arg=n,this.tryEntries.forEach(L),!t)for(var e in this)"t"===e.charAt(0)&&o.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=n)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function r(r,o){return u.type="throw",u.arg=t,e.next=r,o&&(e.method="next",e.arg=n),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],u=a.completion;if("root"===a.tryLoc)return r("end");if(a.tryLoc<=this.prev){var c=o.call(a,"catchLoc"),s=o.call(a,"finallyLoc");if(c&&s){if(this.prev=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),L(n),v}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var o=r.arg;L(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,r){return this.delegate={iterator:T(t),resultName:e,nextLoc:r},"next"===this.method&&(this.arg=n),v}}}function x(t,e,n,r){var o=e&&e.prototype instanceof _?e:_,i=Object.create(o.prototype),a=new M(r||[]);return i._invoke=function(t,e,n){var r=l;return function(o,i){if(r===p)throw new Error("Generator is already running");if(r===d){if("throw"===o)throw i;return C()}for(n.method=o,n.arg=i;;){var a=n.delegate;if(a){var u=O(a,n);if(u){if(u===v)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===l)throw r=d,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var c=b(t,e,n);if("normal"===c.type){if(r=n.done?d:h,c.arg===v)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(r=d,n.method="throw",n.arg=c.arg)}}}(t,n,a),i}function b(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}function _(){}function j(){}function E(){}function P(t){["next","throw","return"].forEach(function(e){t[e]=function(t){return this._invoke(e,t)}})}function S(t){var e;this._invoke=function(n,r){function i(){return new Promise(function(e,i){!function e(n,r,i,a){var u=b(t[n],t,r);if("throw"!==u.type){var c=u.arg,s=c.value;return s&&"object"==typeof s&&o.call(s,"__await")?Promise.resolve(s.__await).then(function(t){e("next",t,i,a)},function(t){e("throw",t,i,a)}):Promise.resolve(s).then(function(t){c.value=t,i(c)},a)}a(u.arg)}(n,r,e,i)})}return e=e?e.then(i,i):i()}}function O(t,e){var r=t.iterator[e.method];if(r===n){if(e.delegate=null,"throw"===e.method){if(t.iterator.return&&(e.method="return",e.arg=n,O(t,e),"throw"===e.method))return v;e.method="throw",e.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var o=b(r,t.iterator,e.arg);if("throw"===o.type)return e.method="throw",e.arg=o.arg,e.delegate=null,v;var i=o.arg;return i?i.done?(e[t.resultName]=i.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=n),e.delegate=null,v):i:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,v)}function k(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function L(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function M(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0)}function T(t){if(t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,i=function e(){for(;++r0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;this.nodes.editorWrapper=document.createElement("div"),this.nodes.editorWrapper.id="codex-editor",n.appendChild(this.nodes.editorWrapper),e.page&&(this.page=e.page),this.loadEditor().then(function(e){t.editor=e}),this.nodes.saveButton=n.querySelector('[name="js-submit"]'),this.nodes.saveButton.addEventListener("click",function(){t.saveButtonClicked()}),this.nodes.parentIdSelector=n.querySelector('[name="parent"]')}},{key:"loadEditor",value:function(){var t=a(regeneratorRuntime.mark(function t(){var e,r;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,n.e(1).then(n.bind(null,53));case 2:return e=t.sent,r=e.default,t.abrupt("return",new r({initialData:this.page?this.page.body:null}));case 5:case"end":return t.stop()}},t,this)}));return function(){return t.apply(this,arguments)}}()},{key:"getData",value:function(){var t=a(regeneratorRuntime.mark(function t(){var e,n;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,this.editor.save();case 2:if(e=t.sent,n=e.blocks.length?e.blocks[0]:null,n&&"header"===n.type?n.data.text:null){t.next=7;break}throw new Error("Entry should start with Header");case 7:return t.abrupt("return",{parent:this.nodes.parentIdSelector.value,body:e});case 8:case"end":return t.stop()}},t,this)}));return function(){return t.apply(this,arguments)}}()},{key:"saveButtonClicked",value:function(){var t=a(regeneratorRuntime.mark(function t(){var e,n,r;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,t.next=3,this.getData();case 3:return e=t.sent,n=this.page?"/api/page/"+this.page._id:"/api/page",t.prev=5,t.next=8,fetch(n,{method:this.page?"POST":"PUT",headers:{"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(e)});case 8:return r=t.sent,t.next=11,r.json();case 11:(r=t.sent).success?document.location="/page/"+r.result._id:(alert(r.error),console.log("Validation failed:",r.error)),t.next=18;break;case 15:t.prev=15,t.t0=t.catch(5),console.log("Saving request failed:",t.t0);case 18:t.next=24;break;case 20:t.prev=20,t.t1=t.catch(0),alert(t.t1),console.log("Saving error: ",t.t1);case 24:case"end":return t.stop()}},t,this,[[0,20],[5,15]])}));return function(){return t.apply(this,arguments)}}()}]),t}();function s(t,e){for(var n=0;n { this.editor = editor; }); @@ -59,7 +70,9 @@ export default class Writing { async loadEditor() { const {default: Editor} = await import(/* webpackChunkName: "editor" */ './../classes/editor'); - return new Editor(); + return new Editor({ + initialData: this.page ? this.page.body : null + }); } /** @@ -88,10 +101,11 @@ export default class Writing { async saveButtonClicked() { try { const writingData = await this.getData(); + const endpoint = this.page ? '/api/page/' + this.page._id : '/api/page'; try { - let response = await fetch('/page', { - method: 'PUT', + let response = await fetch(endpoint, { + method: this.page ? 'POST' : 'PUT', headers: { 'Content-Type': 'application/json; charset=utf-8' }, diff --git a/src/frontend/styles/components/page.pcss b/src/frontend/styles/components/page.pcss new file mode 100644 index 0000000..5ed2058 --- /dev/null +++ b/src/frontend/styles/components/page.pcss @@ -0,0 +1,57 @@ +.page { + font-size: 16px; + line-height: 1.6; + + &__header { + display: flex; + color: var(--color-text-second); + + &-nav { + color: inherit; + text-decoration: none; + + &:hover { + color: var(--color-link-active); + } + + &:not(:last-of-type) { + &::after { + content: '»'; + margin: 0 0.7em 0 0.45em; + } + } + } + + &-time { + margin-left: auto; + } + + &-button { + @apply --button; + padding: 5px 10px; + font-size: 13px; + margin-left: 10px; + } + } + + &__title { + font-size: 26px; + font-weight: 700; + letter-spacing: -0.04px; + margin-bottom: -0.2em; + } +} + +.block-header { + margin: 1.5em 0 0.5em; + + &--2 { + font-size: 22px; + font-weight: 500; + } + + &--3 { + font-size: 18px; + font-weight: 500; + } +} diff --git a/src/frontend/styles/main.pcss b/src/frontend/styles/main.pcss index ad44985..205aba6 100644 --- a/src/frontend/styles/main.pcss +++ b/src/frontend/styles/main.pcss @@ -4,6 +4,7 @@ @import url('components/header.pcss'); @import url('components/aside.pcss'); @import url('components/writing.pcss'); +@import url('components/page.pcss'); body { font-family: system-ui, Helvetica, Arial, Verdana; diff --git a/src/frontend/styles/vars.pcss b/src/frontend/styles/vars.pcss index 2f42b05..59aaa4a 100644 --- a/src/frontend/styles/vars.pcss +++ b/src/frontend/styles/vars.pcss @@ -9,7 +9,7 @@ */ --layout-padding-horisontal: 40px; --layout-padding-vertical: 40px; - --layout-width-aside: 250px; + --layout-width-aside: 200px; --layout-width-main-col: 650px; --button { @@ -20,6 +20,7 @@ padding: 9px 15px; font-size: 14px; line-height: 1em; + text-decoration: none; svg { margin: 0 0.3em 0 -0.05em; diff --git a/src/models/page.js b/src/models/page.js index a961a02..a78cf87 100644 --- a/src/models/page.js +++ b/src/models/page.js @@ -1,4 +1,4 @@ -const {pages} = require('../utils/database/index'); +const {pages: db} = require('../utils/database/index'); /** * @typedef {Object} PageData @@ -25,7 +25,7 @@ class Page { * @returns {Promise} */ static async get(_id) { - const data = await pages.findOne({_id}); + const data = await db.findOne({_id}); return new Page(data); } @@ -37,7 +37,7 @@ class Page { * @returns {Promise} */ static async getAll(query = {}) { - const docs = await pages.find(query); + const docs = await db.find(query); return Promise.all(docs.map(doc => new Page(doc))); } @@ -52,8 +52,6 @@ class Page { data = {}; } - this.db = pages; - if (data._id) { this._id = data._id; } @@ -113,7 +111,7 @@ class Page { * @returns {Promise} */ get parent() { - return this.db.findOne({_id: this._parent}) + return db.findOne({_id: this._parent}) .then(data => new Page(data)); } @@ -123,7 +121,7 @@ class Page { * @returns {Promise} */ get children() { - return this.db.find({parent: this._id}) + return db.find({parent: this._id}) .then(data => data.map(page => new Page(page))); } @@ -134,11 +132,11 @@ class Page { */ async save() { if (!this._id) { - const insertedRow = await this.db.insert(this.data); + const insertedRow = await db.insert(this.data); this._id = insertedRow._id; } else { - await this.db.update({_id: this._id}, this.data); + await db.update({_id: this._id}, this.data); } return this; @@ -150,7 +148,7 @@ class Page { * @returns {Promise} */ async destroy() { - await this.db.remove({_id: this._id}); + await db.remove({_id: this._id}); delete this._id; diff --git a/src/routes/api/index.js b/src/routes/api/index.js new file mode 100644 index 0000000..f8e60dc --- /dev/null +++ b/src/routes/api/index.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); + +const pagesAPI = require('./pages'); + +router.use('/', pagesAPI); + +module.exports = router; diff --git a/src/routes/api/pages.js b/src/routes/api/pages.js new file mode 100644 index 0000000..cf315b5 --- /dev/null +++ b/src/routes/api/pages.js @@ -0,0 +1,115 @@ +const express = require('express'); +const router = express.Router(); +const multer = require('multer')(); +const Pages = require('../../controllers/pages'); + +/** + * GET /page/:id + * + * Return PageData of page with given id + */ +router.get('/page/:id', async (req, res) => { + try { + const page = await Pages.get(req.params.id); + + res.json({ + success: true, + result: page.data + }); + } catch (err) { + res.status(400).json({ + success: false, + error: err.message + }); + } +}); + +/** + * GET /pages + * + * Return PageData for all pages + */ +router.get('/pages', async (req, res) => { + try { + const pages = await Pages.getAll(); + + res.json({ + success: true, + result: pages + }); + } catch (err) { + res.status(400).json({ + success: false, + error: err.message + }); + } +}); + +/** + * PUT /page + * + * Create new page in the database + */ +router.put('/page', multer.any(), async (req, res) => { + try { + const {title, body, parent} = req.body; + const page = await Pages.insert({title, body, parent}); + + res.json({ + success: true, + result: page + }); + } catch (err) { + res.status(400).json({ + success: false, + error: err.message + }); + } +}); + +/** + * POST /page/:id + * + * Update page data in the database + */ +router.post('/page/:id', multer.any(), async (req, res) => { + const {id} = req.params; + + try { + const {title, body, parent} = req.body; + const page = await Pages.update(id, {title, body, parent}); + + res.json({ + success: true, + result: page + }); + } catch (err) { + res.status(400).json({ + success: false, + error: err.message + }); + } +}); + +/** + * DELETE /page/:id + * + * Remove page from the database + */ +router.delete('/page/:id', async (req, res) => { + try { + const page = await Pages.remove(req.params.id); + + res.json({ + success: true, + result: page + }); + } catch (err) { + res.status(400).json({ + success: false, + error: err.message + }); + } +}); + +module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js index 96fcd59..f2a1c2f 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -3,8 +3,10 @@ const router = express.Router(); const home = require('./home'); const pages = require('./pages'); +const api = require('./api'); router.use('/', home); router.use('/', pages); +router.use('/api', api); module.exports = router; diff --git a/src/routes/pages.js b/src/routes/pages.js index a9b9bae..0124d6b 100644 --- a/src/routes/pages.js +++ b/src/routes/pages.js @@ -1,6 +1,5 @@ const express = require('express'); const router = express.Router(); -const multer = require('multer')(); const Pages = require('../controllers/pages'); /** @@ -10,116 +9,46 @@ router.get('/page/new', async (req, res) => { let pagesAvailable = await Pages.getAll(); res.render('pages/form', { - pagesAvailable + pagesAvailable, + page: null }); }); /** - * GET /page/:id - * - * Return PageData of page with given id + * Edit page form */ -router.get('/page/:id', async (req, res) => { - try { - const page = await Pages.get(req.params.id); +router.get('/page/edit/:id', async (req, res, next) => { + const pageId = req.params.id; - res.json({ - success: true, - result: page.data - }); - } catch (err) { - res.status(400).json({ - success: false, - error: err.message + try { + let page = await Pages.get(pageId); + let pagesAvailable = await Pages.getAll(); + + res.render('pages/form', { + pagesAvailable, + page }); + } catch (error) { + res.status(404); + next(error); } }); /** - * GET /pages - * - * Return PageData for all pages + * View page */ -router.get('/pages', async (req, res) => { - try { - const pages = await Pages.getAll(); - - res.json({ - success: true, - result: pages - }); - } catch (err) { - res.status(400).json({ - success: false, - error: err.message - }); - } -}); - -/** - * PUT /page - * - * Create new page in the database - */ -router.put('/page', multer.any(), async (req, res) => { - try { - const {title, body, parent} = req.body; - const page = await Pages.insert({title, body, parent}); - - res.json({ - success: true, - result: page - }); - } catch (err) { - res.status(400).json({ - success: false, - error: err.message - }); - } -}); - -/** - * POST /page/:id - * - * Update page data in the database - */ -router.post('/page/:id', multer.any(), async (req, res) => { - const {id} = req.params; +router.get('/page/:id', async (req, res, next) => { + const pageId = req.params.id; try { - const {title, body, parent} = req.body; - const page = await Pages.update(id, {title, body, parent}); + let page = await Pages.get(pageId); - res.json({ - success: true, - result: page - }); - } catch (err) { - res.status(400).json({ - success: false, - error: err.message - }); - } -}); - -/** - * DELETE /page/:id - * - * Remove page from the database - */ -router.delete('/page/:id', async (req, res) => { - try { - const page = await Pages.remove(req.params.id); - - res.json({ - success: true, - result: page - }); - } catch (err) { - res.status(400).json({ - success: false, - error: err.message + res.render('pages/page', { + page }); + } catch (error) { + res.status(404); + next(error); } }); diff --git a/src/views/pages/blocks/header.twig b/src/views/pages/blocks/header.twig new file mode 100644 index 0000000..4578161 --- /dev/null +++ b/src/views/pages/blocks/header.twig @@ -0,0 +1,3 @@ + + {{ text }} + diff --git a/src/views/pages/blocks/paragraph.twig b/src/views/pages/blocks/paragraph.twig new file mode 100644 index 0000000..11d5fce --- /dev/null +++ b/src/views/pages/blocks/paragraph.twig @@ -0,0 +1,3 @@ +

+ {{ text }} +

diff --git a/src/views/pages/form.twig b/src/views/pages/form.twig index 543cad0..204e50e 100644 --- a/src/views/pages/form.twig +++ b/src/views/pages/form.twig @@ -7,15 +7,28 @@ }
+
New Page at the - + {% set currentPageId = 0 %} + {% if page is not empty %} + {% set currentPageId = page._id %} + {% endif %} + Save diff --git a/src/views/pages/page.twig b/src/views/pages/page.twig new file mode 100644 index 0000000..1e8bd74 --- /dev/null +++ b/src/views/pages/page.twig @@ -0,0 +1,38 @@ +{% extends 'layout.twig' %} + +{% block body %} +
+ +

+ {{ page.title }} +

+
+ {% for block in page.body.blocks %} + {# Skip first header, because it is already showed as a Title #} + {% if not (loop.first and block.type == 'header') %} + {% if block.type in ['paragraph', 'header'] %} + {% include './blocks/' ~ block.type ~ '.twig' with block.data %} + {% endif %} + {% endif %} + {% endfor %} +
+ +
+ +{% endblock %} diff --git a/test/rest/pages.js b/test/rest/pages.js index 38c06e4..3e8bfe6 100644 --- a/test/rest/pages.js +++ b/test/rest/pages.js @@ -38,7 +38,7 @@ describe('Pages REST: ', () => { }; const res = await agent - .put('/page') + .put('/api/page') .send({body}); expect(res).to.have.status(200); @@ -63,7 +63,7 @@ describe('Pages REST: ', () => { it('Page data validation on create', async () => { const res = await agent - .put('/page') + .put('/api/page') .send({someField: 'Some text'}); expect(res).to.have.status(400); @@ -88,7 +88,7 @@ describe('Pages REST: ', () => { }; const put = await agent - .put('/page') + .put('/api/page') .send({body}); expect(put).to.have.status(200); @@ -96,7 +96,7 @@ describe('Pages REST: ', () => { const {result: {_id}} = put.body; - const get = await agent.get(`/page/${_id}`); + const get = await agent.get(`/api/page/${_id}`); expect(get).to.have.status(200); expect(get).to.be.json; @@ -115,7 +115,7 @@ describe('Pages REST: ', () => { }); it('Finding page with not existing id', async () => { - const res = await agent.get('/page/not-existing-id'); + const res = await agent.get('/api/page/not-existing-id'); expect(res).to.have.status(400); expect(res).to.be.json; @@ -139,7 +139,7 @@ describe('Pages REST: ', () => { }; let res = await agent - .put('/page') + .put('/api/page') .send({body}); expect(res).to.have.status(200); @@ -159,7 +159,7 @@ describe('Pages REST: ', () => { }; res = await agent - .post(`/page/${_id}`) + .post(`/api/page/${_id}`) .send({body: updatedBody}); expect(res).to.have.status(200); @@ -187,7 +187,7 @@ describe('Pages REST: ', () => { it('Updating page with not existing id', async () => { const res = await agent - .post('/page/not-existing-id') + .post('/api/page/not-existing-id') .send({body: { blocks: [ { @@ -221,7 +221,7 @@ describe('Pages REST: ', () => { }; let res = await agent - .put('/page') + .put('/api/page') .send({body}); expect(res).to.have.status(200); @@ -230,7 +230,7 @@ describe('Pages REST: ', () => { const {result: {_id}} = res.body; res = await agent - .delete(`/page/${_id}`); + .delete(`/api/page/${_id}`); expect(res).to.have.status(200); expect(res).to.be.json; @@ -249,7 +249,7 @@ describe('Pages REST: ', () => { it('Removing page with not existing id', async () => { const res = await agent - .delete('/page/not-existing-id'); + .delete('/api/page/not-existing-id'); expect(res).to.have.status(400); expect(res).to.be.json;