simplyview 3.0.3 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,13 +7,15 @@
7
7
  constructor(options = {}) {
8
8
  this.root = options.root || "/";
9
9
  this.app = options.app;
10
+ this.addMissingSlash = !!options.addMissingSlash;
11
+ this.matchExact = !!options.matchExact;
10
12
  this.clear();
11
13
  if (options.routes) {
12
14
  this.load(options.routes);
13
15
  }
14
16
  }
15
17
  load(routes2) {
16
- parseRoutes(routes2, this.routeInfo);
18
+ parseRoutes(routes2, this.routeInfo, this.matchExact);
17
19
  }
18
20
  clear() {
19
21
  this.routeInfo = [];
@@ -41,6 +43,15 @@
41
43
  path = getPath(path);
42
44
  for (let route of this.routeInfo) {
43
45
  matches = route.match.exec(path);
46
+ if (this.addMissingSlash && !matches?.length) {
47
+ if (path && path[path.length - 1] != "/") {
48
+ matches = route.match.exec(path + "/");
49
+ if (matches) {
50
+ path += "/";
51
+ history.replaceState({}, "", getURL(path));
52
+ }
53
+ }
54
+ }
44
55
  if (matches && matches.length) {
45
56
  var params = {};
46
57
  route.params.forEach((key, i2) => {
@@ -59,11 +70,6 @@
59
70
  return args.result;
60
71
  }
61
72
  }
62
- if (path && path[path.length - 1] != "/") {
63
- return this.match(path + "/", options);
64
- }
65
- console.log(path, this.routeInfo);
66
- process.exit();
67
73
  return false;
68
74
  }
69
75
  runListeners(action, params) {
@@ -90,7 +96,7 @@
90
96
  this.match(getPath(document.location.pathname, this.root));
91
97
  }
92
98
  });
93
- globalThis.document.addEventListener("click", (evt) => {
99
+ this.app.container.addEventListener("click", (evt) => {
94
100
  if (evt.ctrlKey) {
95
101
  return;
96
102
  }
@@ -109,10 +115,11 @@
109
115
  if (this.has(path)) {
110
116
  let params = this.runListeners("goto", { path });
111
117
  if (params.path) {
112
- this.goto(params.path);
118
+ if (this.goto(params.path)) {
119
+ evt.preventDefault();
120
+ return false;
121
+ }
113
122
  }
114
- evt.preventDefault();
115
- return false;
116
123
  }
117
124
  }
118
125
  });
@@ -173,10 +180,13 @@
173
180
  }
174
181
  return root + path;
175
182
  }
176
- function getRegexpFromRoute(route) {
183
+ function getRegexpFromRoute(route, exact = false) {
184
+ if (exact) {
185
+ return new RegExp("^" + route.replace(/:\w+/g, "([^/]+)").replace(/:\*/, "(.*)") + "(\\?|$)");
186
+ }
177
187
  return new RegExp("^" + route.replace(/:\w+/g, "([^/]+)").replace(/:\*/, "(.*)"));
178
188
  }
179
- function parseRoutes(routes2, routeInfo) {
189
+ function parseRoutes(routes2, routeInfo, exact = false) {
180
190
  const paths = Object.keys(routes2);
181
191
  const matchParams = /:(\w+|\*)/g;
182
192
  for (let path of paths) {
@@ -189,7 +199,7 @@
189
199
  }
190
200
  } while (matches);
191
201
  routeInfo.push({
192
- match: getRegexpFromRoute(path),
202
+ match: getRegexpFromRoute(path, exact),
193
203
  params,
194
204
  action: routes2[path]
195
205
  });
@@ -451,20 +461,28 @@
451
461
  var SimplyApp = class {
452
462
  constructor(options = {}) {
453
463
  this.container = options.container || document.body;
454
- if (options.commands) {
455
- this.commands = commands({ app: this, container: this.container, commands: options.commands });
456
- }
457
- if (options.keys) {
458
- this.keys = keys({ app: this, keys: options.keys });
459
- }
460
- if (options.routes) {
461
- this.routes = routes({ app: this, routes: options.routes });
462
- }
463
- if (options.actions) {
464
- this.actions = actions({ app: this, actions: options.actions });
465
- }
466
- if (options.view) {
467
- this.view = view({ app: this, view: options.view });
464
+ for (let key in options) {
465
+ switch (key) {
466
+ case "commands":
467
+ this.commands = commands({ app: this, container: this.container, commands: options.commands });
468
+ break;
469
+ case "keys":
470
+ case "keyboard":
471
+ this.keys = keys({ app: this, keys: options.keys });
472
+ break;
473
+ case "routes":
474
+ this.routes = routes({ app: this, routes: options.routes });
475
+ break;
476
+ case "actions":
477
+ this.actions = actions({ app: this, actions: options.actions });
478
+ break;
479
+ case "view":
480
+ this.view = view({ app: this, view: options.view });
481
+ break;
482
+ default:
483
+ this[key] = options[key];
484
+ break;
485
+ }
468
486
  }
469
487
  }
470
488
  };
@@ -1,2 +1,2 @@
1
- (()=>{function k(t){return new p(t)}var p=class{constructor(e={}){this.root=e.root||"/",this.app=e.app,this.clear(),e.routes&&this.load(e.routes)}load(e){A(e,this.routeInfo)}clear(){this.routeInfo=[],this.listeners={match:{},call:{},finish:{}}}match(e,r){let n={path:e,options:r};n=this.runListeners("match",n),e=n.path?n.path:e;let a;if(!e)return this.match(document.location.pathname+document.location.hash)?!0:this.match(document.location.pathname);e=h(e);for(let c of this.routeInfo)if(a=c.match.exec(e),a&&a.length){var s={};return c.params.forEach((l,u)=>{l=="*"&&(l="remainder"),s[l]=a[u+1]}),Object.assign(s,r),n.route=c,n.params=s,n=this.runListeners("call",n),s=n.params?n.params:s,n.result=c.action.call(c,s),this.runListeners("finish",n),n.result}return e&&e[e.length-1]!="/"?this.match(e+"/",r):(console.log(e,this.routeInfo),process.exit(),!1)}runListeners(e,r){if(Object.keys(this.listeners[e]))return Object.keys(this.listeners[e]).forEach(n=>{var a=v(n);if(a.exec(r.path)){var s;for(let c of this.listeners[e][n])s=c.call(this.app,r),s&&(r=s)}}),r}handleEvents(){globalThis.addEventListener("popstate",()=>{this.match(h(document.location.pathname+document.location.hash,this.root))===!1&&this.match(h(document.location.pathname,this.root))}),globalThis.document.addEventListener("click",e=>{if(!e.ctrlKey&&e.which==1){for(var r=e.target;r&&r.tagName!="A";)r=r.parentElement;if(r&&r.pathname&&r.hostname==globalThis.location.hostname&&!r.link&&!r.dataset.simplyCommand){let n=h(r.pathname+r.hash,this.root);if(this.has(n)||(n=h(r.pathname,this.root)),this.has(n)){let a=this.runListeners("goto",{path:n});return a.path&&this.goto(a.path),e.preventDefault(),!1}}}})}goto(e){return history.pushState({},"",j(e)),this.match(e)}has(e){e=h(e,this.root);for(let n of this.routeInfo){var r=n.match.exec(e);if(r&&r.length)return!0}return!1}addListener(e,r,n){if(["goto","match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][r]||(this.listeners[e][r]=[]),this.listeners[e][r].push(n)}removeListener(e,r,n){if(["match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][r]&&(this.listeners[e][r]=this.listeners[e][r].filter(a=>a!=n))}init(e){e.root&&(this.root=e.root)}};function h(t,e="/"){return(t.substring(0,e.length)==e||e[e.length-1]=="/"&&t.length==e.length-1&&t==e.substring(0,t.length))&&(t=t.substring(e.length)),t[0]!="/"&&t[0]!="#"&&(t="/"+t),t}function j(t,e){return t=h(t,e),e[e.length-1]==="/"&&t[0]==="/"&&(t=t.substring(1)),e+t}function v(t){return new RegExp("^"+t.replace(/:\w+/g,"([^/]+)").replace(/:\*/,"(.*)"))}function A(t,e){let r=Object.keys(t),n=/:(\w+|\*)/g;for(let a of r){let s=[],c=[];do s=n.exec(a),s&&c.push(s[1]);while(s);e.push({match:v(a),params:c,action:t[a]})}return e}var y=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),this.$handlers=e.handlers||D,e.commands&&Object.assign(this,e.commands);let r=n=>{let a=T(n,this.$handlers);if(!a)return;if(!this[a.name]){console.error("simply.command: undefined command "+a.name,a.source);return}if(this[a.name].call(e.app,a.source,a.value)!==!0)return n.preventDefault(),n.stopPropagation(),!1};e.app.container.addEventListener("click",r),e.app.container.addEventListener("submit",r),e.app.container.addEventListener("change",r),e.app.container.addEventListener("input",r)}};function w(t={}){return new y(t)}function T(t,e){var r=t.target.closest("[data-simply-command]");if(r){for(let n of e)if(r.matches(n.match))return n.check(r,t)?{name:r.dataset.simplyCommand,source:r,value:n.get(r)}:null}return null}var D=[{match:"input,select,textarea",get:function(t){if(t.tagName==="SELECT"&&t.multiple){let e=[];for(let r of t.options)r.selected&&e.push(r.value);return e}return t.dataset.simplyValue||t.value},check:function(t,e){return e.type=="change"||t.dataset.simplyImmediate&&e.type=="input"}},{match:"a,button",get:function(t){return t.dataset.simplyValue||t.href||t.value},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}},{match:"form",get:function(t){let e={};for(let r of Array.from(t.elements)){if(r.tagName=="INPUT"&&(r.type=="checkbox"||r.type=="radio")&&!r.checked)return;e[r.name]&&!Array.isArray(e[r.name])&&(e[r.name]=[e[r.name]]),Array.isArray(e[r.name])?e[r.name].push(r.value):e[r.name]=r.value}return e},check:function(t,e){return e.type=="submit"}},{match:"*",get:function(t){return t.dataset.simplyValue},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}}];function E(t){if(t.app){let e={get:(r,n)=>r[n].bind(t.app)};return new Proxy(t.actions,e)}else return t}var m=Object.freeze({Compose:229,Control:17,Meta:224,Alt:18,Shift:16}),g=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),Object.assign(this,e.keys);let r=n=>{if(n.isComposing||n.keyCode===m.Compose||n.defaultPrevented||!n.target)return;let a="default";n.target.closest("[data-simply-keyboard]")&&(a=n.target.closest("[data-simply-keyboard]").dataset.simplyKeyboard);let s=[];n.ctrlKey&&n.keyCode!=m.Control&&s.push("Control"),n.metaKey&&n.keyCode!=m.Meta&&s.push("Meta"),n.altKey&&n.keyCode!=m.Alt&&s.push("Alt"),n.shiftKey&&n.keyCode!=m.Shift&&s.push("Shift"),s.push(n.key.toLowerCase());let c=[],l=event.target.closest("[data-simply-keyboard]");for(;l;)c.push(l.dataset.simplyKeyboard),l=l.parentNode.closest("[data-simply-keyboard]");c.push("");let u,o,L=["+","-"];for(i in c){u=c[i],u==""?o="default":(o=u,u+=".");for(let K of L){let f=s.join(K);if(this[o]&&typeof this[o][f]=="function"&&!this[o][f].call(this[o],n)){n.preventDefault();return}if(typeof this[o+f]=="function"&&!this[o+f].call(this,n)){n.preventDefault();return}if(this[a]&&this[a][f]){let d=e.app.container.querySelectorAll('[data-simply-accesskey="'+u+f+'"]');d.length&&(d.forEach(O=>O.click()),n.preventDefault())}}}};e.app.container.addEventListener("keydown",r)}};function x(t={}){return new g(t)}function C(t){if(t.app){t.app.view=t.view||{};let e=()=>{let r=t.app.view,n=globalThis.editor.data.getDataPath(t.app.container||document.body);t.app.view=globalThis.editor.currentData[n],Object.assign(t.app.view,r)};return globalThis.editor&&globalThis.editor.currentData?e():document.addEventListener("simply-content-loaded",e),t.app.view}else return t.view}var b=class{constructor(e={}){this.container=e.container||document.body,e.commands&&(this.commands=w({app:this,container:this.container,commands:e.commands})),e.keys&&(this.keys=x({app:this,keys:e.keys})),e.routes&&(this.routes=k({app:this,routes:e.routes})),e.actions&&(this.actions=E({app:this,actions:e.actions})),e.view&&(this.view=C({app:this,view:e.view}))}};function $(t={}){return new b(t)}})();
1
+ (()=>{function w(t){return new p(t)}var p=class{constructor(e={}){this.root=e.root||"/",this.app=e.app,this.addMissingSlash=!!e.addMissingSlash,this.matchExact=!!e.matchExact,this.clear(),e.routes&&this.load(e.routes)}load(e){A(e,this.routeInfo,this.matchExact)}clear(){this.routeInfo=[],this.listeners={match:{},call:{},finish:{}}}match(e,a){let r={path:e,options:a};r=this.runListeners("match",r),e=r.path?r.path:e;let n;if(!e)return this.match(document.location.pathname+document.location.hash)?!0:this.match(document.location.pathname);e=h(e);for(let c of this.routeInfo)if(n=c.match.exec(e),this.addMissingSlash&&!n?.length&&e&&e[e.length-1]!="/"&&(n=c.match.exec(e+"/"),n&&(e+="/",history.replaceState({},"",b(e)))),n&&n.length){var s={};return c.params.forEach((l,u)=>{l=="*"&&(l="remainder"),s[l]=n[u+1]}),Object.assign(s,a),r.route=c,r.params=s,r=this.runListeners("call",r),s=r.params?r.params:s,r.result=c.action.call(c,s),this.runListeners("finish",r),r.result}return!1}runListeners(e,a){if(Object.keys(this.listeners[e]))return Object.keys(this.listeners[e]).forEach(r=>{var n=v(r);if(n.exec(a.path)){var s;for(let c of this.listeners[e][r])s=c.call(this.app,a),s&&(a=s)}}),a}handleEvents(){globalThis.addEventListener("popstate",()=>{this.match(h(document.location.pathname+document.location.hash,this.root))===!1&&this.match(h(document.location.pathname,this.root))}),this.app.container.addEventListener("click",e=>{if(!e.ctrlKey&&e.which==1){for(var a=e.target;a&&a.tagName!="A";)a=a.parentElement;if(a&&a.pathname&&a.hostname==globalThis.location.hostname&&!a.link&&!a.dataset.simplyCommand){let r=h(a.pathname+a.hash,this.root);if(this.has(r)||(r=h(a.pathname,this.root)),this.has(r)){let n=this.runListeners("goto",{path:r});if(n.path&&this.goto(n.path))return e.preventDefault(),!1}}}})}goto(e){return history.pushState({},"",b(e)),this.match(e)}has(e){e=h(e,this.root);for(let r of this.routeInfo){var a=r.match.exec(e);if(a&&a.length)return!0}return!1}addListener(e,a,r){if(["goto","match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][a]||(this.listeners[e][a]=[]),this.listeners[e][a].push(r)}removeListener(e,a,r){if(["match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][a]&&(this.listeners[e][a]=this.listeners[e][a].filter(n=>n!=r))}init(e){e.root&&(this.root=e.root)}};function h(t,e="/"){return(t.substring(0,e.length)==e||e[e.length-1]=="/"&&t.length==e.length-1&&t==e.substring(0,t.length))&&(t=t.substring(e.length)),t[0]!="/"&&t[0]!="#"&&(t="/"+t),t}function b(t,e){return t=h(t,e),e[e.length-1]==="/"&&t[0]==="/"&&(t=t.substring(1)),e+t}function v(t,e=!1){return e?new RegExp("^"+t.replace(/:\w+/g,"([^/]+)").replace(/:\*/,"(.*)")+"(\\?|$)"):new RegExp("^"+t.replace(/:\w+/g,"([^/]+)").replace(/:\*/,"(.*)"))}function A(t,e,a=!1){let r=Object.keys(t),n=/:(\w+|\*)/g;for(let s of r){let c=[],l=[];do c=n.exec(s),c&&l.push(c[1]);while(c);e.push({match:v(s,a),params:l,action:t[s]})}return e}var y=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),this.$handlers=e.handlers||T,e.commands&&Object.assign(this,e.commands);let a=r=>{let n=D(r,this.$handlers);if(!n)return;if(!this[n.name]){console.error("simply.command: undefined command "+n.name,n.source);return}if(this[n.name].call(e.app,n.source,n.value)!==!0)return r.preventDefault(),r.stopPropagation(),!1};e.app.container.addEventListener("click",a),e.app.container.addEventListener("submit",a),e.app.container.addEventListener("change",a),e.app.container.addEventListener("input",a)}};function E(t={}){return new y(t)}function D(t,e){var a=t.target.closest("[data-simply-command]");if(a){for(let r of e)if(a.matches(r.match))return r.check(a,t)?{name:a.dataset.simplyCommand,source:a,value:r.get(a)}:null}return null}var T=[{match:"input,select,textarea",get:function(t){if(t.tagName==="SELECT"&&t.multiple){let e=[];for(let a of t.options)a.selected&&e.push(a.value);return e}return t.dataset.simplyValue||t.value},check:function(t,e){return e.type=="change"||t.dataset.simplyImmediate&&e.type=="input"}},{match:"a,button",get:function(t){return t.dataset.simplyValue||t.href||t.value},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}},{match:"form",get:function(t){let e={};for(let a of Array.from(t.elements)){if(a.tagName=="INPUT"&&(a.type=="checkbox"||a.type=="radio")&&!a.checked)return;e[a.name]&&!Array.isArray(e[a.name])&&(e[a.name]=[e[a.name]]),Array.isArray(e[a.name])?e[a.name].push(a.value):e[a.name]=a.value}return e},check:function(t,e){return e.type=="submit"}},{match:"*",get:function(t){return t.dataset.simplyValue},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}}];function x(t){if(t.app){let e={get:(a,r)=>a[r].bind(t.app)};return new Proxy(t.actions,e)}else return t}var m=Object.freeze({Compose:229,Control:17,Meta:224,Alt:18,Shift:16}),g=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),Object.assign(this,e.keys);let a=r=>{if(r.isComposing||r.keyCode===m.Compose||r.defaultPrevented||!r.target)return;let n="default";r.target.closest("[data-simply-keyboard]")&&(n=r.target.closest("[data-simply-keyboard]").dataset.simplyKeyboard);let s=[];r.ctrlKey&&r.keyCode!=m.Control&&s.push("Control"),r.metaKey&&r.keyCode!=m.Meta&&s.push("Meta"),r.altKey&&r.keyCode!=m.Alt&&s.push("Alt"),r.shiftKey&&r.keyCode!=m.Shift&&s.push("Shift"),s.push(r.key.toLowerCase());let c=[],l=event.target.closest("[data-simply-keyboard]");for(;l;)c.push(l.dataset.simplyKeyboard),l=l.parentNode.closest("[data-simply-keyboard]");c.push("");let u,o,K=["+","-"];for(i in c){u=c[i],u==""?o="default":(o=u,u+=".");for(let O of K){let f=s.join(O);if(this[o]&&typeof this[o][f]=="function"&&!this[o][f].call(this[o],r)){r.preventDefault();return}if(typeof this[o+f]=="function"&&!this[o+f].call(this,r)){r.preventDefault();return}if(this[n]&&this[n][f]){let d=e.app.container.querySelectorAll('[data-simply-accesskey="'+u+f+'"]');d.length&&(d.forEach(j=>j.click()),r.preventDefault())}}}};e.app.container.addEventListener("keydown",a)}};function C(t={}){return new g(t)}function L(t){if(t.app){t.app.view=t.view||{};let e=()=>{let a=t.app.view,r=globalThis.editor.data.getDataPath(t.app.container||document.body);t.app.view=globalThis.editor.currentData[r],Object.assign(t.app.view,a)};return globalThis.editor&&globalThis.editor.currentData?e():document.addEventListener("simply-content-loaded",e),t.app.view}else return t.view}var k=class{constructor(e={}){this.container=e.container||document.body;for(let a in e)switch(a){case"commands":this.commands=E({app:this,container:this.container,commands:e.commands});break;case"keys":case"keyboard":this.keys=C({app:this,keys:e.keys});break;case"routes":this.routes=w({app:this,routes:e.routes});break;case"actions":this.actions=x({app:this,actions:e.actions});break;case"view":this.view=L({app:this,view:e.view});break;default:this[a]=e[a];break}}};function $(t={}){return new k(t)}})();
2
2
  //# sourceMappingURL=simply.app.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/route.mjs", "../src/command.mjs", "../src/action.mjs", "../src/key.mjs", "../src/view.mjs", "../src/app.mjs"],
4
- "sourcesContent": ["export function routes(options) {\n\treturn new SimplyRoute(options)\n}\n\nclass SimplyRoute {\n\tconstructor(options={}) {\n\t\tthis.root = options.root || '/'\n this.app = options.app\n\t\tthis.clear()\n\t\tif (options.routes) {\n\t\t\tthis.load(options.routes)\n\t\t}\n\t}\n\n\tload(routes) {\n\t\tparseRoutes(routes, this.routeInfo)\n\t}\n\n\tclear() {\n\t\tthis.routeInfo = []\n\t\tthis.listeners = {\n\t\t\tmatch: {},\n\t\t\tcall: {},\n\t\t\tfinish: {}\n\t\t}\n\t}\n\n\tmatch(path, options) {\n\t\tlet args = {\n path,\n options\n }\n args = this.runListeners('match',args)\n path = args.path ? args.path : path;\n\n let matches;\n if (!path) {\n if (this.match(document.location.pathname+document.location.hash)) {\n return true;\n } else {\n return this.match(document.location.pathname);\n }\n }\n path = getPath(path);\n for ( let route of this.routeInfo) {\n matches = route.match.exec(path)\n if (matches && matches.length) {\n var params = {};\n route.params.forEach((key, i) => {\n if (key=='*') {\n key = 'remainder'\n }\n params[key] = matches[i+1]\n })\n Object.assign(params, options)\n args.route = route\n args.params = params\n args = this.runListeners('call', args)\n params = args.params ? args.params : params\n args.result = route.action.call(route, params)\n this.runListeners('finish', args)\n return args.result\n }\n }\n if (path && path[path.length-1]!='/') {\n \treturn this.match(path+'/', options)\n }\n console.log(path, this.routeInfo)\n process.exit()\n return false\n\t}\n\n\trunListeners(action, params) {\n if (!Object.keys(this.listeners[action])) {\n return\n }\n Object.keys(this.listeners[action]).forEach((route) => {\n var routeRe = getRegexpFromRoute(route);\n if (routeRe.exec(params.path)) {\n var result;\n for (let callback of this.listeners[action][route]) {\n result = callback.call(this.app, params)\n if (result) {\n params = result\n }\n }\n }\n })\n return params\n }\n\n handleEvents() {\n globalThis.addEventListener('popstate', () => {\n if (this.match(getPath(document.location.pathname + document.location.hash, this.root)) === false) {\n this.match(getPath(document.location.pathname, this.root))\n }\n })\n globalThis.document.addEventListener('click', (evt) => {\n\t if (evt.ctrlKey) {\n\t return;\n\t }\n\t if (evt.which != 1) {\n\t return; // not a 'left' mouse click\n\t }\n\t var link = evt.target;\n\t while (link && link.tagName!='A') {\n\t link = link.parentElement;\n\t }\n\t if (link \n\t && link.pathname \n\t && link.hostname==globalThis.location.hostname \n\t && !link.link\n\t && !link.dataset.simplyCommand\n\t ) {\n\t let path = getPath(link.pathname+link.hash, this.root);\n\t if ( !this.has(path) ) {\n\t path = getPath(link.pathname, this.root);\n\t }\n\t if ( this.has(path) ) {\n\t let params = this.runListeners('goto', { path: path});\n\t if (params.path) {\n\t this.goto(params.path);\n\t }\n\t evt.preventDefault();\n\t return false;\n\t }\n\t }\n\t })\n }\n\n goto(path) {\n history.pushState({},'',getURL(path))\n return this.match(path)\n }\n\n has(path) {\n \tpath = getPath(path, this.root)\n \tfor (let route of this.routeInfo) {\n var matches = route.match.exec(path)\n if (matches && matches.length) {\n return true\n }\n }\n return false\n }\n\n addListener(action, route, callback) {\n if (['goto','match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n this.listeners[action][route] = []\n }\n this.listeners[action][route].push(callback)\n }\n\n removeListener(action, route, callback) {\n if (['match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n return\n }\n this.listeners[action][route] = this.listeners[action][route].filter((listener) => {\n return listener != callback\n })\n }\n\n init(options) {\n \tif (options.root) {\n \t\tthis.root = options.root\n \t}\n }\n}\n\nfunction getPath(path, root='/') {\n if (path.substring(0,root.length)==root\n ||\n ( root[root.length-1]=='/' \n && path.length==(root.length-1)\n && path == root.substring(0,path.length)\n )\n ) {\n path = path.substring(root.length)\n }\n if (path[0]!='/' && path[0]!='#') {\n path = '/'+path\n }\n return path\n}\n\nfunction getURL(path, root) {\n path = getPath(path, root)\n if (root[root.length-1]==='/' && path[0]==='/') {\n path = path.substring(1)\n }\n return root + path;\n}\n\nfunction getRegexpFromRoute(route) {\n return new RegExp('^'+route.replace(/:\\w+/g, '([^/]+)').replace(/:\\*/, '(.*)'));\n}\n\nfunction parseRoutes(routes, routeInfo) {\n const paths = Object.keys(routes)\n const matchParams = /:(\\w+|\\*)/g\n for (let path of paths) {\n let matches = []\n let params = []\n do {\n matches = matchParams.exec(path)\n if (matches) {\n params.push(matches[1])\n }\n } while(matches)\n routeInfo.push({\n match: getRegexpFromRoute(path),\n params: params,\n action: routes[path]\n })\n }\n return routeInfo\n}\n", "class SimplyCommands {\n\tconstructor(options={}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tthis.$handlers = options.handlers || defaultHandlers\n if (options.commands) {\n \t\tObject.assign(this, options.commands)\n }\n\n\t\tconst commandHandler = (evt) => {\n\t\t\tconst command = getCommand(evt, this.$handlers)\n\t\t\tif (!command) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!this[command.name]) {\n console.error('simply.command: undefined command '+command.name, command.source);\n return\n\t\t\t}\n const shouldContinue = this[command.name].call(options.app, command.source, command.value)\n if (shouldContinue!==true) {\n evt.preventDefault()\n evt.stopPropagation()\n return false\n }\n\t\t}\n\n options.app.container.addEventListener('click', commandHandler)\n options.app.container.addEventListener('submit', commandHandler)\n options.app.container.addEventListener('change', commandHandler)\n options.app.container.addEventListener('input', commandHandler)\n\t}\n}\n\nexport function commands(options={}) {\n\treturn new SimplyCommands(options)\n}\n\nfunction getCommand(evt, handlers) {\n var el = evt.target.closest('[data-simply-command]')\n if (el) {\n for (let handler of handlers) {\n if (el.matches(handler.match)) {\n if (handler.check(el, evt)) {\n return {\n name: el.dataset.simplyCommand,\n source: el,\n value: handler.get(el)\n }\n }\n return null\n }\n }\n }\n return null\n}\n\nconst defaultHandlers = [\n {\n match: 'input,select,textarea',\n get: function(el) {\n if (el.tagName==='SELECT' && el.multiple) {\n let values = []\n for (let option of el.options) {\n if (option.selected) {\n values.push(option.value)\n }\n }\n return values\n }\n return el.dataset.simplyValue || el.value\n },\n check: function(el, evt) {\n return evt.type=='change' || (el.dataset.simplyImmediate && evt.type=='input')\n }\n },\n {\n match: 'a,button',\n get: function(el) {\n return el.dataset.simplyValue || el.href || el.value\n },\n check: function(el,evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n },\n {\n match: 'form',\n get: function(el) {\n let data = {}\n for (let input of Array.from(el.elements)) {\n if (input.tagName=='INPUT' \n && (input.type=='checkbox' || input.type=='radio')\n ) {\n if (!input.checked) {\n return;\n }\n }\n if (data[input.name] && !Array.isArray(data[input.name])) {\n data[input.name] = [data[input.name]]\n }\n if (Array.isArray(data[input.name])) {\n data[input.name].push(input.value)\n } else {\n data[input.name] = input.value\n }\n }\n return data\n },\n check: function(el,evt) {\n return evt.type=='submit'\n }\n },\n {\n \tmatch: '*',\n get: function(el) {\n return el.dataset.simplyValue\n },\n check: function(el, evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n }\n]", "export function actions(options) {\n\tif (options.app) {\n\t\tconst actionHandler = {\n\t\t\tget: (target, property) => {\n\t\t\t\treturn target[property].bind(options.app)\n\t\t\t}\n\t\t}\n\t\treturn new Proxy(options.actions, actionHandler)\n\t} else {\n\t\treturn options\n\t}\n}", "const KEY = Object.freeze({\n\tCompose: 229,\n\tControl: 17,\n\tMeta: 224,\n\tAlt: 18,\n\tShift: 16\n})\n\nclass SimplyKey {\n\tconstructor(options = {}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tObject.assign(this, options.keys)\n\n\t\tconst keyHandler = (e) => {\n\t\t\tif (e.isComposing || e.keyCode === KEY.Compose) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (e.defaultPrevented) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (!e.target) {\n\t\t\t return\n\t\t\t}\n\n\t\t\tlet selectedKeyboard = 'default'\n\t\t\tif (e.target.closest('[data-simply-keyboard]')) {\n\t\t\t selectedKeyboard = e.target.closest('[data-simply-keyboard]')\n\t\t\t \t\t\t\t\t.dataset.simplyKeyboard\n\t\t\t}\n\t\t\tlet keyCombination = []\n\t\t\tif (e.ctrlKey && e.keyCode!=KEY.Control) {\n\t\t\t keyCombination.push('Control')\n\t\t\t}\n\t\t\tif (e.metaKey && e.keyCode!=KEY.Meta) {\n\t\t\t keyCombination.push('Meta')\n\t\t\t}\n\t\t\tif (e.altKey && e.keyCode!=KEY.Alt) {\n\t\t\t keyCombination.push('Alt')\n\t\t\t}\n\t\t\tif (e.shiftKey && e.keyCode!=KEY.Shift) {\n\t\t\t keyCombination.push('Shift')\n\t\t\t}\n\t\t\tkeyCombination.push(e.key.toLowerCase())\n\n\t\t\tlet keyboards = []\n\t\t\tlet keyboardElement = event.target.closest('[data-simply-keyboard]')\n\t\t\twhile (keyboardElement) {\n\t\t\t\tkeyboards.push(keyboardElement.dataset.simplyKeyboard)\n\t\t\t\tkeyboardElement = keyboardElement.parentNode.closest('[data-simply-keyboard]')\n\t\t\t}\n\t\t\tkeyboards.push('')\n\n\t\t\tlet keyboard, subkeyboard\n\t\t\tlet separators = ['+','-']\n\n\t\t\tfor (i in keyboards) {\n\t\t\t\tkeyboard = keyboards[i]\n\t\t\t\tif (keyboard == '') {\n\t\t\t\t\tsubkeyboard = 'default'\n\t\t\t\t} else {\n\t\t\t\t\tsubkeyboard = keyboard\n\t\t\t\t\tkeyboard += '.'\n\t\t\t\t}\n\t\t\t\tfor (let separator of separators) {\n\t\t\t\t\tlet keyString = keyCombination.join(separator)\n\n\t\t\t\t\tif (this[subkeyboard] && (typeof this[subkeyboard][keyString]=='function')) {\n\t\t\t\t\t\tlet _continue = this[subkeyboard][keyString].call(this[subkeyboard], e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof this[subkeyboard + keyString] == 'function') {\n\t\t\t\t\t\tlet _continue = this[subkeyboard + keyString].call(this, e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\t\t\t\t\t\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this[selectedKeyboard] && this[selectedKeyboard][keyString]) {\n\t\t\t\t\t\tlet targets = options.app.container.querySelectorAll('[data-simply-accesskey=\"'\n\t\t\t\t\t\t\t+ keyboard + keyString + '\"]')\n\t\t\t\t\t\tif (targets.length) {\n\t\t\t\t\t\t\ttargets.forEach(t => t.click())\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\toptions.app.container.addEventListener('keydown', keyHandler)\n\t}\n\n}\n\nexport function keys(options={}) {\n\treturn new SimplyKey(options)\n}\n\n", "export function view(options) {\n\tif (options.app) {\n\t\toptions.app.view = options.view || {}\n\n\t\tconst load = () => {\n\t\t\tconst data = options.app.view\n\t\t\tconst path = globalThis.editor.data.getDataPath(options.app.container || document.body)\n\t\t\toptions.app.view = globalThis.editor.currentData[path]\n\t\t\tObject.assign(options.app.view, data)\n\t\t}\n\t\tif (globalThis.editor && globalThis.editor.currentData) {\n\t\t\tload()\n\t\t} else {\n\t\t\tdocument.addEventListener('simply-content-loaded', load)\n\t\t}\n\t\treturn options.app.view\n\t} else {\n\t\treturn options.view\n\t}\n}", "import { routes } from './route.mjs'\nimport { commands } from './command.mjs'\nimport { actions } from './action.mjs'\nimport { keys } from './key.mjs'\nimport { view } from './view.mjs'\n\nclass SimplyApp {\n\tconstructor(options={}) {\n\t\tthis.container = options.container || document.body\n\t\tif (options.commands) {\n\t\t\tthis.commands = commands({ app: this, container: this.container, commands: options.commands})\n\t\t}\n\t\tif (options.keys) {\n\t\t\tthis.keys = keys({ app: this, keys: options.keys })\n\t\t}\n\t\tif (options.routes) {\n\t\t\tthis.routes = routes({ app: this, routes: options.routes})\n\t\t}\n\t\tif (options.actions) {\n\t\t\tthis.actions = actions({app: this, actions: options.actions})\n\t\t}\n\t\tif (options.view) {\n\t\t\tthis.view = view({app: this, view: options.view})\n\t\t}\n\t}\n}\n\nexport function app(options={}) {\n\treturn new SimplyApp(options)\n}"],
5
- "mappings": "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",
6
- "names": ["routes", "options", "SimplyRoute", "parseRoutes", "path", "args", "matches", "getPath", "route", "params", "key", "i", "action", "routeRe", "getRegexpFromRoute", "result", "callback", "evt", "link", "getURL", "listener", "root", "routeInfo", "paths", "matchParams", "SimplyCommands", "options", "defaultHandlers", "commandHandler", "evt", "command", "getCommand", "commands", "handlers", "el", "handler", "values", "option", "data", "input", "actions", "options", "actionHandler", "target", "property", "KEY", "SimplyKey", "options", "keyHandler", "e", "selectedKeyboard", "keyCombination", "keyboards", "keyboardElement", "keyboard", "subkeyboard", "separators", "separator", "keyString", "targets", "t", "keys", "view", "options", "load", "data", "path", "SimplyApp", "options", "commands", "keys", "routes", "actions", "view", "app"]
4
+ "sourcesContent": ["export function routes(options) {\n\treturn new SimplyRoute(options)\n}\n\nclass SimplyRoute {\n\tconstructor(options={}) {\n\t\tthis.root = options.root || '/'\n this.app = options.app\n this.addMissingSlash = !!options.addMissingSlash\n this.matchExact = !!options.matchExact\n\t\tthis.clear()\n\t\tif (options.routes) {\n\t\t\tthis.load(options.routes)\n\t\t}\n\t}\n\n\tload(routes) {\n\t\tparseRoutes(routes, this.routeInfo, this.matchExact)\n\t}\n\n\tclear() {\n\t\tthis.routeInfo = []\n\t\tthis.listeners = {\n\t\t\tmatch: {},\n\t\t\tcall: {},\n\t\t\tfinish: {}\n\t\t}\n\t}\n\n\tmatch(path, options) {\n\t\tlet args = {\n path,\n options\n }\n args = this.runListeners('match',args)\n path = args.path ? args.path : path;\n\n let matches;\n if (!path) {\n if (this.match(document.location.pathname+document.location.hash)) {\n return true;\n } else {\n return this.match(document.location.pathname);\n }\n }\n path = getPath(path);\n for ( let route of this.routeInfo) {\n matches = route.match.exec(path)\n if (this.addMissingSlash && !matches?.length) {\n if (path && path[path.length-1]!='/') {\n matches = route.match.exec(path+'/')\n if (matches) {\n path+='/'\n history.replaceState({}, '', getURL(path))\n }\n }\n }\n if (matches && matches.length) {\n var params = {};\n route.params.forEach((key, i) => {\n if (key=='*') {\n key = 'remainder'\n }\n params[key] = matches[i+1]\n })\n Object.assign(params, options)\n args.route = route\n args.params = params\n args = this.runListeners('call', args)\n params = args.params ? args.params : params\n args.result = route.action.call(route, params)\n this.runListeners('finish', args)\n return args.result\n }\n }\n return false\n\t}\n\n\trunListeners(action, params) {\n if (!Object.keys(this.listeners[action])) {\n return\n }\n Object.keys(this.listeners[action]).forEach((route) => {\n var routeRe = getRegexpFromRoute(route);\n if (routeRe.exec(params.path)) {\n var result;\n for (let callback of this.listeners[action][route]) {\n result = callback.call(this.app, params)\n if (result) {\n params = result\n }\n }\n }\n })\n return params\n }\n\n handleEvents() {\n globalThis.addEventListener('popstate', () => {\n if (this.match(getPath(document.location.pathname + document.location.hash, this.root)) === false) {\n this.match(getPath(document.location.pathname, this.root))\n }\n })\n this.app.container.addEventListener('click', (evt) => {\n\t if (evt.ctrlKey) {\n\t return;\n\t }\n\t if (evt.which != 1) {\n\t return; // not a 'left' mouse click\n\t }\n\t var link = evt.target;\n\t while (link && link.tagName!='A') {\n\t link = link.parentElement;\n\t }\n\t if (link \n\t && link.pathname \n\t && link.hostname==globalThis.location.hostname \n\t && !link.link\n\t && !link.dataset.simplyCommand\n\t ) {\n\t let path = getPath(link.pathname+link.hash, this.root);\n\t if ( !this.has(path) ) {\n\t path = getPath(link.pathname, this.root);\n\t }\n\t if ( this.has(path) ) {\n\t let params = this.runListeners('goto', { path: path});\n\t if (params.path) {\n\t if (this.goto(params.path)) {\n // now cancel the browser navigation, since a route handler was found\n evt.preventDefault();\n return false;\n }\n\t }\n\t }\n\t }\n\t })\n }\n\n goto(path) {\n history.pushState({},'',getURL(path))\n return this.match(path)\n }\n\n has(path) {\n \tpath = getPath(path, this.root)\n \tfor (let route of this.routeInfo) {\n var matches = route.match.exec(path)\n if (matches && matches.length) {\n return true\n }\n }\n return false\n }\n\n addListener(action, route, callback) {\n if (['goto','match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n this.listeners[action][route] = []\n }\n this.listeners[action][route].push(callback)\n }\n\n removeListener(action, route, callback) {\n if (['match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n return\n }\n this.listeners[action][route] = this.listeners[action][route].filter((listener) => {\n return listener != callback\n })\n }\n\n init(options) {\n \tif (options.root) {\n \t\tthis.root = options.root\n \t}\n }\n}\n\nfunction getPath(path, root='/') {\n if (path.substring(0,root.length)==root\n ||\n ( root[root.length-1]=='/' \n && path.length==(root.length-1)\n && path == root.substring(0,path.length)\n )\n ) {\n path = path.substring(root.length)\n }\n if (path[0]!='/' && path[0]!='#') {\n path = '/'+path\n }\n return path\n}\n\nfunction getURL(path, root) {\n path = getPath(path, root)\n if (root[root.length-1]==='/' && path[0]==='/') {\n path = path.substring(1)\n }\n return root + path;\n}\n\nfunction getRegexpFromRoute(route, exact=false) {\n if (exact) {\n return new RegExp('^'+route.replace(/:\\w+/g, '([^/]+)').replace(/:\\*/, '(.*)')+'(\\\\?|$)')\n }\n return new RegExp('^'+route.replace(/:\\w+/g, '([^/]+)').replace(/:\\*/, '(.*)'))\n}\n\nfunction parseRoutes(routes, routeInfo, exact=false) {\n const paths = Object.keys(routes)\n const matchParams = /:(\\w+|\\*)/g\n for (let path of paths) {\n let matches = []\n let params = []\n do {\n matches = matchParams.exec(path)\n if (matches) {\n params.push(matches[1])\n }\n } while(matches)\n routeInfo.push({\n match: getRegexpFromRoute(path, exact),\n params: params,\n action: routes[path]\n })\n }\n return routeInfo\n}\n", "class SimplyCommands {\n\tconstructor(options={}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tthis.$handlers = options.handlers || defaultHandlers\n if (options.commands) {\n \t\tObject.assign(this, options.commands)\n }\n\n\t\tconst commandHandler = (evt) => {\n\t\t\tconst command = getCommand(evt, this.$handlers)\n\t\t\tif (!command) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!this[command.name]) {\n console.error('simply.command: undefined command '+command.name, command.source);\n return\n\t\t\t}\n const shouldContinue = this[command.name].call(options.app, command.source, command.value)\n if (shouldContinue!==true) {\n evt.preventDefault()\n evt.stopPropagation()\n return false\n }\n\t\t}\n\n options.app.container.addEventListener('click', commandHandler)\n options.app.container.addEventListener('submit', commandHandler)\n options.app.container.addEventListener('change', commandHandler)\n options.app.container.addEventListener('input', commandHandler)\n\t}\n}\n\nexport function commands(options={}) {\n\treturn new SimplyCommands(options)\n}\n\nfunction getCommand(evt, handlers) {\n var el = evt.target.closest('[data-simply-command]')\n if (el) {\n for (let handler of handlers) {\n if (el.matches(handler.match)) {\n if (handler.check(el, evt)) {\n return {\n name: el.dataset.simplyCommand,\n source: el,\n value: handler.get(el)\n }\n }\n return null\n }\n }\n }\n return null\n}\n\nconst defaultHandlers = [\n {\n match: 'input,select,textarea',\n get: function(el) {\n if (el.tagName==='SELECT' && el.multiple) {\n let values = []\n for (let option of el.options) {\n if (option.selected) {\n values.push(option.value)\n }\n }\n return values\n }\n return el.dataset.simplyValue || el.value\n },\n check: function(el, evt) {\n return evt.type=='change' || (el.dataset.simplyImmediate && evt.type=='input')\n }\n },\n {\n match: 'a,button',\n get: function(el) {\n return el.dataset.simplyValue || el.href || el.value\n },\n check: function(el,evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n },\n {\n match: 'form',\n get: function(el) {\n let data = {}\n for (let input of Array.from(el.elements)) {\n if (input.tagName=='INPUT' \n && (input.type=='checkbox' || input.type=='radio')\n ) {\n if (!input.checked) {\n return;\n }\n }\n if (data[input.name] && !Array.isArray(data[input.name])) {\n data[input.name] = [data[input.name]]\n }\n if (Array.isArray(data[input.name])) {\n data[input.name].push(input.value)\n } else {\n data[input.name] = input.value\n }\n }\n return data\n },\n check: function(el,evt) {\n return evt.type=='submit'\n }\n },\n {\n \tmatch: '*',\n get: function(el) {\n return el.dataset.simplyValue\n },\n check: function(el, evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n }\n]", "export function actions(options) {\n\tif (options.app) {\n\t\tconst actionHandler = {\n\t\t\tget: (target, property) => {\n\t\t\t\treturn target[property].bind(options.app)\n\t\t\t}\n\t\t}\n\t\treturn new Proxy(options.actions, actionHandler)\n\t} else {\n\t\treturn options\n\t}\n}", "const KEY = Object.freeze({\n\tCompose: 229,\n\tControl: 17,\n\tMeta: 224,\n\tAlt: 18,\n\tShift: 16\n})\n\nclass SimplyKey {\n\tconstructor(options = {}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tObject.assign(this, options.keys)\n\n\t\tconst keyHandler = (e) => {\n\t\t\tif (e.isComposing || e.keyCode === KEY.Compose) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (e.defaultPrevented) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (!e.target) {\n\t\t\t return\n\t\t\t}\n\n\t\t\tlet selectedKeyboard = 'default'\n\t\t\tif (e.target.closest('[data-simply-keyboard]')) {\n\t\t\t selectedKeyboard = e.target.closest('[data-simply-keyboard]')\n\t\t\t \t\t\t\t\t.dataset.simplyKeyboard\n\t\t\t}\n\t\t\tlet keyCombination = []\n\t\t\tif (e.ctrlKey && e.keyCode!=KEY.Control) {\n\t\t\t keyCombination.push('Control')\n\t\t\t}\n\t\t\tif (e.metaKey && e.keyCode!=KEY.Meta) {\n\t\t\t keyCombination.push('Meta')\n\t\t\t}\n\t\t\tif (e.altKey && e.keyCode!=KEY.Alt) {\n\t\t\t keyCombination.push('Alt')\n\t\t\t}\n\t\t\tif (e.shiftKey && e.keyCode!=KEY.Shift) {\n\t\t\t keyCombination.push('Shift')\n\t\t\t}\n\t\t\tkeyCombination.push(e.key.toLowerCase())\n\n\t\t\tlet keyboards = []\n\t\t\tlet keyboardElement = event.target.closest('[data-simply-keyboard]')\n\t\t\twhile (keyboardElement) {\n\t\t\t\tkeyboards.push(keyboardElement.dataset.simplyKeyboard)\n\t\t\t\tkeyboardElement = keyboardElement.parentNode.closest('[data-simply-keyboard]')\n\t\t\t}\n\t\t\tkeyboards.push('')\n\n\t\t\tlet keyboard, subkeyboard\n\t\t\tlet separators = ['+','-']\n\n\t\t\tfor (i in keyboards) {\n\t\t\t\tkeyboard = keyboards[i]\n\t\t\t\tif (keyboard == '') {\n\t\t\t\t\tsubkeyboard = 'default'\n\t\t\t\t} else {\n\t\t\t\t\tsubkeyboard = keyboard\n\t\t\t\t\tkeyboard += '.'\n\t\t\t\t}\n\t\t\t\tfor (let separator of separators) {\n\t\t\t\t\tlet keyString = keyCombination.join(separator)\n\n\t\t\t\t\tif (this[subkeyboard] && (typeof this[subkeyboard][keyString]=='function')) {\n\t\t\t\t\t\tlet _continue = this[subkeyboard][keyString].call(this[subkeyboard], e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof this[subkeyboard + keyString] == 'function') {\n\t\t\t\t\t\tlet _continue = this[subkeyboard + keyString].call(this, e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\t\t\t\t\t\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this[selectedKeyboard] && this[selectedKeyboard][keyString]) {\n\t\t\t\t\t\tlet targets = options.app.container.querySelectorAll('[data-simply-accesskey=\"'\n\t\t\t\t\t\t\t+ keyboard + keyString + '\"]')\n\t\t\t\t\t\tif (targets.length) {\n\t\t\t\t\t\t\ttargets.forEach(t => t.click())\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\toptions.app.container.addEventListener('keydown', keyHandler)\n\t}\n\n}\n\nexport function keys(options={}) {\n\treturn new SimplyKey(options)\n}\n\n", "export function view(options) {\n\tif (options.app) {\n\t\toptions.app.view = options.view || {}\n\n\t\tconst load = () => {\n\t\t\tconst data = options.app.view\n\t\t\tconst path = globalThis.editor.data.getDataPath(options.app.container || document.body)\n\t\t\toptions.app.view = globalThis.editor.currentData[path]\n\t\t\tObject.assign(options.app.view, data)\n\t\t}\n\t\tif (globalThis.editor && globalThis.editor.currentData) {\n\t\t\tload()\n\t\t} else {\n\t\t\tdocument.addEventListener('simply-content-loaded', load)\n\t\t}\n\t\treturn options.app.view\n\t} else {\n\t\treturn options.view\n\t}\n}", "import { routes } from './route.mjs'\nimport { commands } from './command.mjs'\nimport { actions } from './action.mjs'\nimport { keys } from './key.mjs'\nimport { view } from './view.mjs'\n\nclass SimplyApp {\n\tconstructor(options={}) {\n\t\tthis.container = options.container || document.body\n\t\tfor (let key in options) {\n\t\t\tswitch(key) {\n\t\t\t\tcase 'commands':\n\t\t\t\t\tthis.commands = commands({ app: this, container: this.container, commands: options.commands})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'keys':\n\t\t\t\tcase 'keyboard': // backwards compatible\n\t\t\t\t\tthis.keys = keys({ app: this, keys: options.keys })\n\t\t\t\t\tbreak\n\t\t\t\tcase 'routes':\n\t\t\t\t\tthis.routes = routes({ app: this, routes: options.routes})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'actions':\n\t\t\t\t\tthis.actions = actions({app: this, actions: options.actions})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'view':\n\t\t\t\t\tthis.view = view({app: this, view: options.view})\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tthis[key] = options[key] // allows easy additions\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function app(options={}) {\n\treturn new SimplyApp(options)\n}"],
5
+ "mappings": "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",
6
+ "names": ["routes", "options", "SimplyRoute", "parseRoutes", "path", "args", "matches", "getPath", "route", "getURL", "params", "key", "i", "action", "routeRe", "getRegexpFromRoute", "result", "callback", "evt", "link", "listener", "root", "exact", "routeInfo", "paths", "matchParams", "SimplyCommands", "options", "defaultHandlers", "commandHandler", "evt", "command", "getCommand", "commands", "handlers", "el", "handler", "values", "option", "data", "input", "actions", "options", "actionHandler", "target", "property", "KEY", "SimplyKey", "options", "keyHandler", "e", "selectedKeyboard", "keyCombination", "keyboards", "keyboardElement", "keyboard", "subkeyboard", "separators", "separator", "keyString", "targets", "t", "keys", "view", "options", "load", "data", "path", "SimplyApp", "options", "key", "commands", "keys", "routes", "actions", "view", "app"]
7
7
  }
@@ -81,13 +81,15 @@
81
81
  constructor(options = {}) {
82
82
  this.root = options.root || "/";
83
83
  this.app = options.app;
84
+ this.addMissingSlash = !!options.addMissingSlash;
85
+ this.matchExact = !!options.matchExact;
84
86
  this.clear();
85
87
  if (options.routes) {
86
88
  this.load(options.routes);
87
89
  }
88
90
  }
89
91
  load(routes2) {
90
- parseRoutes(routes2, this.routeInfo);
92
+ parseRoutes(routes2, this.routeInfo, this.matchExact);
91
93
  }
92
94
  clear() {
93
95
  this.routeInfo = [];
@@ -115,6 +117,15 @@
115
117
  path = getPath(path);
116
118
  for (let route of this.routeInfo) {
117
119
  matches = route.match.exec(path);
120
+ if (this.addMissingSlash && !matches?.length) {
121
+ if (path && path[path.length - 1] != "/") {
122
+ matches = route.match.exec(path + "/");
123
+ if (matches) {
124
+ path += "/";
125
+ history.replaceState({}, "", getURL(path));
126
+ }
127
+ }
128
+ }
118
129
  if (matches && matches.length) {
119
130
  var params = {};
120
131
  route.params.forEach((key, i2) => {
@@ -133,11 +144,6 @@
133
144
  return args.result;
134
145
  }
135
146
  }
136
- if (path && path[path.length - 1] != "/") {
137
- return this.match(path + "/", options);
138
- }
139
- console.log(path, this.routeInfo);
140
- process.exit();
141
147
  return false;
142
148
  }
143
149
  runListeners(action, params) {
@@ -164,7 +170,7 @@
164
170
  this.match(getPath(document.location.pathname, this.root));
165
171
  }
166
172
  });
167
- globalThis.document.addEventListener("click", (evt) => {
173
+ this.app.container.addEventListener("click", (evt) => {
168
174
  if (evt.ctrlKey) {
169
175
  return;
170
176
  }
@@ -183,10 +189,11 @@
183
189
  if (this.has(path)) {
184
190
  let params = this.runListeners("goto", { path });
185
191
  if (params.path) {
186
- this.goto(params.path);
192
+ if (this.goto(params.path)) {
193
+ evt.preventDefault();
194
+ return false;
195
+ }
187
196
  }
188
- evt.preventDefault();
189
- return false;
190
197
  }
191
198
  }
192
199
  });
@@ -247,10 +254,13 @@
247
254
  }
248
255
  return root + path;
249
256
  }
250
- function getRegexpFromRoute(route) {
257
+ function getRegexpFromRoute(route, exact = false) {
258
+ if (exact) {
259
+ return new RegExp("^" + route.replace(/:\w+/g, "([^/]+)").replace(/:\*/, "(.*)") + "(\\?|$)");
260
+ }
251
261
  return new RegExp("^" + route.replace(/:\w+/g, "([^/]+)").replace(/:\*/, "(.*)"));
252
262
  }
253
- function parseRoutes(routes2, routeInfo) {
263
+ function parseRoutes(routes2, routeInfo, exact = false) {
254
264
  const paths = Object.keys(routes2);
255
265
  const matchParams = /:(\w+|\*)/g;
256
266
  for (let path of paths) {
@@ -263,7 +273,7 @@
263
273
  }
264
274
  } while (matches);
265
275
  routeInfo.push({
266
- match: getRegexpFromRoute(path),
276
+ match: getRegexpFromRoute(path, exact),
267
277
  params,
268
278
  action: routes2[path]
269
279
  });
@@ -511,20 +521,28 @@
511
521
  var SimplyApp = class {
512
522
  constructor(options = {}) {
513
523
  this.container = options.container || document.body;
514
- if (options.commands) {
515
- this.commands = commands({ app: this, container: this.container, commands: options.commands });
516
- }
517
- if (options.keys) {
518
- this.keys = keys({ app: this, keys: options.keys });
519
- }
520
- if (options.routes) {
521
- this.routes = routes({ app: this, routes: options.routes });
522
- }
523
- if (options.actions) {
524
- this.actions = actions({ app: this, actions: options.actions });
525
- }
526
- if (options.view) {
527
- this.view = view({ app: this, view: options.view });
524
+ for (let key in options) {
525
+ switch (key) {
526
+ case "commands":
527
+ this.commands = commands({ app: this, container: this.container, commands: options.commands });
528
+ break;
529
+ case "keys":
530
+ case "keyboard":
531
+ this.keys = keys({ app: this, keys: options.keys });
532
+ break;
533
+ case "routes":
534
+ this.routes = routes({ app: this, routes: options.routes });
535
+ break;
536
+ case "actions":
537
+ this.actions = actions({ app: this, actions: options.actions });
538
+ break;
539
+ case "view":
540
+ this.view = view({ app: this, view: options.view });
541
+ break;
542
+ default:
543
+ this[key] = options[key];
544
+ break;
545
+ }
528
546
  }
529
547
  }
530
548
  };
@@ -1,2 +1,2 @@
1
- (()=>{var u=new Map,S={addListener:(t,e)=>{u.has(t)||u.set(t,[]),u.get(t).push(e),_(t)},removeListener:(t,e)=>{if(!u.has(t))return!1;u.set(t,u.get(t).filter(r=>r!=e))}};function _(t){let e=document.querySelectorAll('[data-simply-activate="'+t+'"]');if(e)for(let r of e)N(r)}function N(t){let e=t?.dataset?.simplyActivate;if(e&&u.has(e))for(let r of u.get(e))r.call(t)}function V(t){let e=[];for(let n of t)if(n.type=="childList"){for(let a of n.addedNodes)if(a.querySelectorAll){var r=Array.from(a.querySelectorAll("[data-simply-activate]"));a.matches("[data-simply-activate]")&&r.push(a),e=e.concat(r)}}for(let n of e)N(n)}var $=new MutationObserver(V);$.observe(document,{subtree:!0,childList:!0});function g(t){if(t.app){let e={get:(r,n)=>r[n].bind(t.app)};return new Proxy(t.actions,e)}else return t}function b(t){return new C(t)}var C=class{constructor(e={}){this.root=e.root||"/",this.app=e.app,this.clear(),e.routes&&this.load(e.routes)}load(e){W(e,this.routeInfo)}clear(){this.routeInfo=[],this.listeners={match:{},call:{},finish:{}}}match(e,r){let n={path:e,options:r};n=this.runListeners("match",n),e=n.path?n.path:e;let a;if(!e)return this.match(document.location.pathname+document.location.hash)?!0:this.match(document.location.pathname);e=f(e);for(let s of this.routeInfo)if(a=s.match.exec(e),a&&a.length){var l={};return s.params.forEach((o,h)=>{o=="*"&&(o="remainder"),l[o]=a[h+1]}),Object.assign(l,r),n.route=s,n.params=l,n=this.runListeners("call",n),l=n.params?n.params:l,n.result=s.action.call(s,l),this.runListeners("finish",n),n.result}return e&&e[e.length-1]!="/"?this.match(e+"/",r):(console.log(e,this.routeInfo),process.exit(),!1)}runListeners(e,r){if(Object.keys(this.listeners[e]))return Object.keys(this.listeners[e]).forEach(n=>{var a=O(n);if(a.exec(r.path)){var l;for(let s of this.listeners[e][n])l=s.call(this.app,r),l&&(r=l)}}),r}handleEvents(){globalThis.addEventListener("popstate",()=>{this.match(f(document.location.pathname+document.location.hash,this.root))===!1&&this.match(f(document.location.pathname,this.root))}),globalThis.document.addEventListener("click",e=>{if(!e.ctrlKey&&e.which==1){for(var r=e.target;r&&r.tagName!="A";)r=r.parentElement;if(r&&r.pathname&&r.hostname==globalThis.location.hostname&&!r.link&&!r.dataset.simplyCommand){let n=f(r.pathname+r.hash,this.root);if(this.has(n)||(n=f(r.pathname,this.root)),this.has(n)){let a=this.runListeners("goto",{path:n});return a.path&&this.goto(a.path),e.preventDefault(),!1}}}})}goto(e){return history.pushState({},"",z(e)),this.match(e)}has(e){e=f(e,this.root);for(let n of this.routeInfo){var r=n.match.exec(e);if(r&&r.length)return!0}return!1}addListener(e,r,n){if(["goto","match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][r]||(this.listeners[e][r]=[]),this.listeners[e][r].push(n)}removeListener(e,r,n){if(["match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][r]&&(this.listeners[e][r]=this.listeners[e][r].filter(a=>a!=n))}init(e){e.root&&(this.root=e.root)}};function f(t,e="/"){return(t.substring(0,e.length)==e||e[e.length-1]=="/"&&t.length==e.length-1&&t==e.substring(0,t.length))&&(t=t.substring(e.length)),t[0]!="/"&&t[0]!="#"&&(t="/"+t),t}function z(t,e){return t=f(t,e),e[e.length-1]==="/"&&t[0]==="/"&&(t=t.substring(1)),e+t}function O(t){return new RegExp("^"+t.replace(/:\w+/g,"([^/]+)").replace(/:\*/,"(.*)"))}function W(t,e){let r=Object.keys(t),n=/:(\w+|\*)/g;for(let a of r){let l=[],s=[];do l=n.exec(a),l&&s.push(l[1]);while(l);e.push({match:O(a),params:s,action:t[a]})}return e}var T=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),this.$handlers=e.handlers||G,e.commands&&Object.assign(this,e.commands);let r=n=>{let a=Y(n,this.$handlers);if(!a)return;if(!this[a.name]){console.error("simply.command: undefined command "+a.name,a.source);return}if(this[a.name].call(e.app,a.source,a.value)!==!0)return n.preventDefault(),n.stopPropagation(),!1};e.app.container.addEventListener("click",r),e.app.container.addEventListener("submit",r),e.app.container.addEventListener("change",r),e.app.container.addEventListener("input",r)}};function v(t={}){return new T(t)}function Y(t,e){var r=t.target.closest("[data-simply-command]");if(r){for(let n of e)if(r.matches(n.match))return n.check(r,t)?{name:r.dataset.simplyCommand,source:r,value:n.get(r)}:null}return null}var G=[{match:"input,select,textarea",get:function(t){if(t.tagName==="SELECT"&&t.multiple){let e=[];for(let r of t.options)r.selected&&e.push(r.value);return e}return t.dataset.simplyValue||t.value},check:function(t,e){return e.type=="change"||t.dataset.simplyImmediate&&e.type=="input"}},{match:"a,button",get:function(t){return t.dataset.simplyValue||t.href||t.value},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}},{match:"form",get:function(t){let e={};for(let r of Array.from(t.elements)){if(r.tagName=="INPUT"&&(r.type=="checkbox"||r.type=="radio")&&!r.checked)return;e[r.name]&&!Array.isArray(e[r.name])&&(e[r.name]=[e[r.name]]),Array.isArray(e[r.name])?e[r.name].push(r.value):e[r.name]=r.value}return e},check:function(t,e){return e.type=="submit"}},{match:"*",get:function(t){return t.dataset.simplyValue},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}}];var p=Object.freeze({Compose:229,Control:17,Meta:224,Alt:18,Shift:16}),x=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),Object.assign(this,e.keys);let r=n=>{if(n.isComposing||n.keyCode===p.Compose||n.defaultPrevented||!n.target)return;let a="default";n.target.closest("[data-simply-keyboard]")&&(a=n.target.closest("[data-simply-keyboard]").dataset.simplyKeyboard);let l=[];n.ctrlKey&&n.keyCode!=p.Control&&l.push("Control"),n.metaKey&&n.keyCode!=p.Meta&&l.push("Meta"),n.altKey&&n.keyCode!=p.Alt&&l.push("Alt"),n.shiftKey&&n.keyCode!=p.Shift&&l.push("Shift"),l.push(n.key.toLowerCase());let s=[],o=event.target.closest("[data-simply-keyboard]");for(;o;)s.push(o.dataset.simplyKeyboard),o=o.parentNode.closest("[data-simply-keyboard]");s.push("");let h,c,H=["+","-"];for(i in s){h=s[i],h==""?c="default":(c=h,h+=".");for(let U of H){let d=l.join(U);if(this[c]&&typeof this[c][d]=="function"&&!this[c][d].call(this[c],n)){n.preventDefault();return}if(typeof this[c+d]=="function"&&!this[c+d].call(this,n)){n.preventDefault();return}if(this[a]&&this[a][d]){let y=e.app.container.querySelectorAll('[data-simply-accesskey="'+h+d+'"]');y.length&&(y.forEach(F=>F.click()),n.preventDefault())}}}};e.app.container.addEventListener("keydown",r)}};function k(t={}){return new x(t)}function w(t){if(t.app){t.app.view=t.view||{};let e=()=>{let r=t.app.view,n=globalThis.editor.data.getDataPath(t.app.container||document.body);t.app.view=globalThis.editor.currentData[n],Object.assign(t.app.view,r)};return globalThis.editor&&globalThis.editor.currentData?e():document.addEventListener("simply-content-loaded",e),t.app.view}else return t.view}var A=class{constructor(e={}){this.container=e.container||document.body,e.commands&&(this.commands=v({app:this,container:this.container,commands:e.commands})),e.keys&&(this.keys=k({app:this,keys:e.keys})),e.routes&&(this.routes=b({app:this,routes:e.routes})),e.actions&&(this.actions=g({app:this,actions:e.actions})),e.view&&(this.view=w({app:this,view:e.view}))}};function j(t={}){return new A(t)}function J(t,e){let r=0;return()=>{let n=arguments;r||(r=globalThis.setTimeout(()=>{t.apply(this,n),r=0},e))}}var Q=globalThis.requestIdleCallback?t=>{globalThis.requestIdleCallback(t,{timeout:500})}:globalThis.requestAnimationFrame;function q(t,e){let r=new URL(t,e);return m.cacheBuster&&r.searchParams.set("cb",m.cacheBuster),r.href}var I,X={},E=globalThis.document.querySelector("head"),K=globalThis.document.currentScript,P,D;K?D=K.src:(P=(()=>{var t=document.getElementsByTagName("script"),e=t.length-1,r=t[e];return()=>r.src})(),D=P());var Z=async()=>new Promise(function(t){var e=globalThis.document.createElement("script");e.src="https://cdn.jsdelivr.net/gh/simplyedit/simplyview/dist/simply.include.next.js",e.async=!1,globalThis.document.addEventListener("simply-include-next",()=>{E.removeChild(e),t()},{once:!0,passive:!0}),E.appendChild(e)}),L=[],m={cacheBuster:null,scripts:(t,e)=>{let r=t.slice(),n=()=>{let a=r.shift();if(!a)return;let l=[].map.call(a.attributes,o=>o.name),s=globalThis.document.createElement("script");for(let o of l)s.setAttribute(o,a.getAttribute(o));if(s.removeAttribute("data-simply-location"),!s.src)s.innerHTML=a.innerHTML,Z().then(()=>{let o=L[a.dataset.simplyLocation];o.parentNode.insertBefore(s,o),o.parentNode.removeChild(o),n()});else{s.src=q(s.src,e),!s.hasAttribute("async")&&!s.hasAttribute("defer")&&(s.async=!1);let o=L[a.dataset.simplyLocation];o.parentNode.insertBefore(s,o),o.parentNode.removeChild(o),X[s.src]=!0,n()}};r.length&&n()},html:(t,e)=>{let r=globalThis.document.createRange().createContextualFragment(t),n=r.querySelectorAll('link[rel="stylesheet"],style');for(let s of n)s.href&&(s.href=q(s.href,e.href)),E.appendChild(s);let a=globalThis.document.createDocumentFragment(),l=r.querySelectorAll("script");if(l.length){for(let s of l){let o=globalThis.document.createComment(s.src||"inline script");s.parentNode.insertBefore(o,s),s.dataset.simplyLocation=L.length,L.push(o),a.appendChild(s)}globalThis.setTimeout(function(){m.scripts(Array.from(a.children),e?e.href:globalThis.location.href)},10)}e.parentNode.insertBefore(r,e||null)}},R={},ee=async t=>{let e=[].reduce.call(t,(r,n)=>(n.rel=="simply-include-once"&&R[n.href]?n.parentNode.removeChild(n):(R[n.href]=!0,n.rel="simply-include-loading",r.push(n)),r),[]);for(let r of e){if(!r.href)return;let n=await fetch(r.href);if(!n.ok){console.log("simply-include: failed to load "+r.href);continue}console.log("simply-include: loaded "+r.href);let a=await n.text();m.html(a,r),r.parentNode.removeChild(r)}},B=J(()=>{Q(()=>{var t=globalThis.document.querySelectorAll('link[rel="simply-include"],link[rel="simply-include-once"]');t.length&&ee(t)})}),te=()=>{I=new MutationObserver(B),I.observe(globalThis.document,{subtree:!0,childList:!0})};te();B();var M={activate:S,action:g,app:j,command:v,include:m,key:k,route:b,view:w};window.simply=M;var Ce=M;})();
1
+ (()=>{var u=new Map,S={addListener:(t,e)=>{u.has(t)||u.set(t,[]),u.get(t).push(e),V(t)},removeListener:(t,e)=>{if(!u.has(t))return!1;u.set(t,u.get(t).filter(r=>r!=e))}};function V(t){let e=document.querySelectorAll('[data-simply-activate="'+t+'"]');if(e)for(let r of e)N(r)}function N(t){let e=t?.dataset?.simplyActivate;if(e&&u.has(e))for(let r of u.get(e))r.call(t)}function $(t){let e=[];for(let a of t)if(a.type=="childList"){for(let n of a.addedNodes)if(n.querySelectorAll){var r=Array.from(n.querySelectorAll("[data-simply-activate]"));n.matches("[data-simply-activate]")&&r.push(n),e=e.concat(r)}}for(let a of e)N(a)}var z=new MutationObserver($);z.observe(document,{subtree:!0,childList:!0});function g(t){if(t.app){let e={get:(r,a)=>r[a].bind(t.app)};return new Proxy(t.actions,e)}else return t}function b(t){return new C(t)}var C=class{constructor(e={}){this.root=e.root||"/",this.app=e.app,this.addMissingSlash=!!e.addMissingSlash,this.matchExact=!!e.matchExact,this.clear(),e.routes&&this.load(e.routes)}load(e){W(e,this.routeInfo,this.matchExact)}clear(){this.routeInfo=[],this.listeners={match:{},call:{},finish:{}}}match(e,r){let a={path:e,options:r};a=this.runListeners("match",a),e=a.path?a.path:e;let n;if(!e)return this.match(document.location.pathname+document.location.hash)?!0:this.match(document.location.pathname);e=f(e);for(let s of this.routeInfo)if(n=s.match.exec(e),this.addMissingSlash&&!n?.length&&e&&e[e.length-1]!="/"&&(n=s.match.exec(e+"/"),n&&(e+="/",history.replaceState({},"",O(e)))),n&&n.length){var c={};return s.params.forEach((l,h)=>{l=="*"&&(l="remainder"),c[l]=n[h+1]}),Object.assign(c,r),a.route=s,a.params=c,a=this.runListeners("call",a),c=a.params?a.params:c,a.result=s.action.call(s,c),this.runListeners("finish",a),a.result}return!1}runListeners(e,r){if(Object.keys(this.listeners[e]))return Object.keys(this.listeners[e]).forEach(a=>{var n=j(a);if(n.exec(r.path)){var c;for(let s of this.listeners[e][a])c=s.call(this.app,r),c&&(r=c)}}),r}handleEvents(){globalThis.addEventListener("popstate",()=>{this.match(f(document.location.pathname+document.location.hash,this.root))===!1&&this.match(f(document.location.pathname,this.root))}),this.app.container.addEventListener("click",e=>{if(!e.ctrlKey&&e.which==1){for(var r=e.target;r&&r.tagName!="A";)r=r.parentElement;if(r&&r.pathname&&r.hostname==globalThis.location.hostname&&!r.link&&!r.dataset.simplyCommand){let a=f(r.pathname+r.hash,this.root);if(this.has(a)||(a=f(r.pathname,this.root)),this.has(a)){let n=this.runListeners("goto",{path:a});if(n.path&&this.goto(n.path))return e.preventDefault(),!1}}}})}goto(e){return history.pushState({},"",O(e)),this.match(e)}has(e){e=f(e,this.root);for(let a of this.routeInfo){var r=a.match.exec(e);if(r&&r.length)return!0}return!1}addListener(e,r,a){if(["goto","match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][r]||(this.listeners[e][r]=[]),this.listeners[e][r].push(a)}removeListener(e,r,a){if(["match","call","finish"].indexOf(e)==-1)throw new Error("Unknown action "+e);this.listeners[e][r]&&(this.listeners[e][r]=this.listeners[e][r].filter(n=>n!=a))}init(e){e.root&&(this.root=e.root)}};function f(t,e="/"){return(t.substring(0,e.length)==e||e[e.length-1]=="/"&&t.length==e.length-1&&t==e.substring(0,t.length))&&(t=t.substring(e.length)),t[0]!="/"&&t[0]!="#"&&(t="/"+t),t}function O(t,e){return t=f(t,e),e[e.length-1]==="/"&&t[0]==="/"&&(t=t.substring(1)),e+t}function j(t,e=!1){return e?new RegExp("^"+t.replace(/:\w+/g,"([^/]+)").replace(/:\*/,"(.*)")+"(\\?|$)"):new RegExp("^"+t.replace(/:\w+/g,"([^/]+)").replace(/:\*/,"(.*)"))}function W(t,e,r=!1){let a=Object.keys(t),n=/:(\w+|\*)/g;for(let c of a){let s=[],l=[];do s=n.exec(c),s&&l.push(s[1]);while(s);e.push({match:j(c,r),params:l,action:t[c]})}return e}var x=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),this.$handlers=e.handlers||G,e.commands&&Object.assign(this,e.commands);let r=a=>{let n=Y(a,this.$handlers);if(!n)return;if(!this[n.name]){console.error("simply.command: undefined command "+n.name,n.source);return}if(this[n.name].call(e.app,n.source,n.value)!==!0)return a.preventDefault(),a.stopPropagation(),!1};e.app.container.addEventListener("click",r),e.app.container.addEventListener("submit",r),e.app.container.addEventListener("change",r),e.app.container.addEventListener("input",r)}};function v(t={}){return new x(t)}function Y(t,e){var r=t.target.closest("[data-simply-command]");if(r){for(let a of e)if(r.matches(a.match))return a.check(r,t)?{name:r.dataset.simplyCommand,source:r,value:a.get(r)}:null}return null}var G=[{match:"input,select,textarea",get:function(t){if(t.tagName==="SELECT"&&t.multiple){let e=[];for(let r of t.options)r.selected&&e.push(r.value);return e}return t.dataset.simplyValue||t.value},check:function(t,e){return e.type=="change"||t.dataset.simplyImmediate&&e.type=="input"}},{match:"a,button",get:function(t){return t.dataset.simplyValue||t.href||t.value},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}},{match:"form",get:function(t){let e={};for(let r of Array.from(t.elements)){if(r.tagName=="INPUT"&&(r.type=="checkbox"||r.type=="radio")&&!r.checked)return;e[r.name]&&!Array.isArray(e[r.name])&&(e[r.name]=[e[r.name]]),Array.isArray(e[r.name])?e[r.name].push(r.value):e[r.name]=r.value}return e},check:function(t,e){return e.type=="submit"}},{match:"*",get:function(t){return t.dataset.simplyValue},check:function(t,e){return e.type=="click"&&e.ctrlKey==!1&&e.button==0}}];var p=Object.freeze({Compose:229,Control:17,Meta:224,Alt:18,Shift:16}),T=class{constructor(e={}){e.app||(e.app={}),e.app.container||(e.app.container=document.body),Object.assign(this,e.keys);let r=a=>{if(a.isComposing||a.keyCode===p.Compose||a.defaultPrevented||!a.target)return;let n="default";a.target.closest("[data-simply-keyboard]")&&(n=a.target.closest("[data-simply-keyboard]").dataset.simplyKeyboard);let c=[];a.ctrlKey&&a.keyCode!=p.Control&&c.push("Control"),a.metaKey&&a.keyCode!=p.Meta&&c.push("Meta"),a.altKey&&a.keyCode!=p.Alt&&c.push("Alt"),a.shiftKey&&a.keyCode!=p.Shift&&c.push("Shift"),c.push(a.key.toLowerCase());let s=[],l=event.target.closest("[data-simply-keyboard]");for(;l;)s.push(l.dataset.simplyKeyboard),l=l.parentNode.closest("[data-simply-keyboard]");s.push("");let h,o,U=["+","-"];for(i in s){h=s[i],h==""?o="default":(o=h,h+=".");for(let F of U){let d=c.join(F);if(this[o]&&typeof this[o][d]=="function"&&!this[o][d].call(this[o],a)){a.preventDefault();return}if(typeof this[o+d]=="function"&&!this[o+d].call(this,a)){a.preventDefault();return}if(this[n]&&this[n][d]){let y=e.app.container.querySelectorAll('[data-simply-accesskey="'+h+d+'"]');y.length&&(y.forEach(_=>_.click()),a.preventDefault())}}}};e.app.container.addEventListener("keydown",r)}};function k(t={}){return new T(t)}function w(t){if(t.app){t.app.view=t.view||{};let e=()=>{let r=t.app.view,a=globalThis.editor.data.getDataPath(t.app.container||document.body);t.app.view=globalThis.editor.currentData[a],Object.assign(t.app.view,r)};return globalThis.editor&&globalThis.editor.currentData?e():document.addEventListener("simply-content-loaded",e),t.app.view}else return t.view}var E=class{constructor(e={}){this.container=e.container||document.body;for(let r in e)switch(r){case"commands":this.commands=v({app:this,container:this.container,commands:e.commands});break;case"keys":case"keyboard":this.keys=k({app:this,keys:e.keys});break;case"routes":this.routes=b({app:this,routes:e.routes});break;case"actions":this.actions=g({app:this,actions:e.actions});break;case"view":this.view=w({app:this,view:e.view});break;default:this[r]=e[r];break}}};function q(t={}){return new E(t)}function J(t,e){let r=0;return()=>{let a=arguments;r||(r=globalThis.setTimeout(()=>{t.apply(this,a),r=0},e))}}var Q=globalThis.requestIdleCallback?t=>{globalThis.requestIdleCallback(t,{timeout:500})}:globalThis.requestAnimationFrame;function M(t,e){let r=new URL(t,e);return m.cacheBuster&&r.searchParams.set("cb",m.cacheBuster),r.href}var K,X={},A=globalThis.document.querySelector("head"),P=globalThis.document.currentScript,R,D;P?D=P.src:(R=(()=>{var t=document.getElementsByTagName("script"),e=t.length-1,r=t[e];return()=>r.src})(),D=R());var Z=async()=>new Promise(function(t){var e=globalThis.document.createElement("script");e.src="https://cdn.jsdelivr.net/gh/simplyedit/simplyview/dist/simply.include.next.js",e.async=!1,globalThis.document.addEventListener("simply-include-next",()=>{A.removeChild(e),t()},{once:!0,passive:!0}),A.appendChild(e)}),L=[],m={cacheBuster:null,scripts:(t,e)=>{let r=t.slice(),a=()=>{let n=r.shift();if(!n)return;let c=[].map.call(n.attributes,l=>l.name),s=globalThis.document.createElement("script");for(let l of c)s.setAttribute(l,n.getAttribute(l));if(s.removeAttribute("data-simply-location"),!s.src)s.innerHTML=n.innerHTML,Z().then(()=>{let l=L[n.dataset.simplyLocation];l.parentNode.insertBefore(s,l),l.parentNode.removeChild(l),a()});else{s.src=M(s.src,e),!s.hasAttribute("async")&&!s.hasAttribute("defer")&&(s.async=!1);let l=L[n.dataset.simplyLocation];l.parentNode.insertBefore(s,l),l.parentNode.removeChild(l),X[s.src]=!0,a()}};r.length&&a()},html:(t,e)=>{let r=globalThis.document.createRange().createContextualFragment(t),a=r.querySelectorAll('link[rel="stylesheet"],style');for(let s of a)s.href&&(s.href=M(s.href,e.href)),A.appendChild(s);let n=globalThis.document.createDocumentFragment(),c=r.querySelectorAll("script");if(c.length){for(let s of c){let l=globalThis.document.createComment(s.src||"inline script");s.parentNode.insertBefore(l,s),s.dataset.simplyLocation=L.length,L.push(l),n.appendChild(s)}globalThis.setTimeout(function(){m.scripts(Array.from(n.children),e?e.href:globalThis.location.href)},10)}e.parentNode.insertBefore(r,e||null)}},I={},ee=async t=>{let e=[].reduce.call(t,(r,a)=>(a.rel=="simply-include-once"&&I[a.href]?a.parentNode.removeChild(a):(I[a.href]=!0,a.rel="simply-include-loading",r.push(a)),r),[]);for(let r of e){if(!r.href)return;let a=await fetch(r.href);if(!a.ok){console.log("simply-include: failed to load "+r.href);continue}console.log("simply-include: loaded "+r.href);let n=await a.text();m.html(n,r),r.parentNode.removeChild(r)}},B=J(()=>{Q(()=>{var t=globalThis.document.querySelectorAll('link[rel="simply-include"],link[rel="simply-include-once"]');t.length&&ee(t)})}),te=()=>{K=new MutationObserver(B),K.observe(globalThis.document,{subtree:!0,childList:!0})};te();B();var H={activate:S,action:g,app:q,command:v,include:m,key:k,route:b,view:w};window.simply=H;var Ce=H;})();
2
2
  //# sourceMappingURL=simply.everything.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/activate.mjs", "../src/action.mjs", "../src/route.mjs", "../src/command.mjs", "../src/key.mjs", "../src/view.mjs", "../src/app.mjs", "../src/include.mjs", "../src/everything.mjs"],
4
- "sourcesContent": ["const listeners = new Map()\n\nexport const activate = {\n addListener: (name, callback) => {\n if (!listeners.has(name)) {\n listeners.set(name, [])\n }\n listeners.get(name).push(callback)\n initialCall(name)\n },\n removeListener: (name, callback) => {\n if (!listeners.has(name)) {\n return false\n }\n listeners.set(name, listeners.get(name).filter((listener) => {\n return listener!=callback\n }))\n }\n}\n\nfunction initialCall(name) {\n const nodes = document.querySelectorAll('[data-simply-activate=\"'+name+'\"]')\n if (nodes) {\n for( let node of nodes) {\n callListeners(node)\n }\n }\n}\n\nfunction callListeners(node) {\n const activate = node?.dataset?.simplyActivate\n if (activate && listeners.has(activate)) {\n for (let callback of listeners.get(activate)) {\n callback.call(node)\n }\n }\n}\n\nfunction handleChanges(changes) {\n let activateNodes = []\n for (let change of changes) {\n if (change.type == 'childList') {\n for (let node of change.addedNodes) {\n if (node.querySelectorAll) {\n var toActivate = Array.from(node.querySelectorAll('[data-simply-activate]'))\n if (node.matches('[data-simply-activate]')) {\n toActivate.push(node)\n }\n activateNodes = activateNodes.concat(toActivate)\n }\n }\n }\n }\n for (let node of activateNodes) {\n callListeners(node)\n }\n}\n\nconst observer = new MutationObserver(handleChanges)\nobserver.observe(document, {\n subtree: true,\n childList: true\n})", "export function actions(options) {\n\tif (options.app) {\n\t\tconst actionHandler = {\n\t\t\tget: (target, property) => {\n\t\t\t\treturn target[property].bind(options.app)\n\t\t\t}\n\t\t}\n\t\treturn new Proxy(options.actions, actionHandler)\n\t} else {\n\t\treturn options\n\t}\n}", "export function routes(options) {\n\treturn new SimplyRoute(options)\n}\n\nclass SimplyRoute {\n\tconstructor(options={}) {\n\t\tthis.root = options.root || '/'\n this.app = options.app\n\t\tthis.clear()\n\t\tif (options.routes) {\n\t\t\tthis.load(options.routes)\n\t\t}\n\t}\n\n\tload(routes) {\n\t\tparseRoutes(routes, this.routeInfo)\n\t}\n\n\tclear() {\n\t\tthis.routeInfo = []\n\t\tthis.listeners = {\n\t\t\tmatch: {},\n\t\t\tcall: {},\n\t\t\tfinish: {}\n\t\t}\n\t}\n\n\tmatch(path, options) {\n\t\tlet args = {\n path,\n options\n }\n args = this.runListeners('match',args)\n path = args.path ? args.path : path;\n\n let matches;\n if (!path) {\n if (this.match(document.location.pathname+document.location.hash)) {\n return true;\n } else {\n return this.match(document.location.pathname);\n }\n }\n path = getPath(path);\n for ( let route of this.routeInfo) {\n matches = route.match.exec(path)\n if (matches && matches.length) {\n var params = {};\n route.params.forEach((key, i) => {\n if (key=='*') {\n key = 'remainder'\n }\n params[key] = matches[i+1]\n })\n Object.assign(params, options)\n args.route = route\n args.params = params\n args = this.runListeners('call', args)\n params = args.params ? args.params : params\n args.result = route.action.call(route, params)\n this.runListeners('finish', args)\n return args.result\n }\n }\n if (path && path[path.length-1]!='/') {\n \treturn this.match(path+'/', options)\n }\n console.log(path, this.routeInfo)\n process.exit()\n return false\n\t}\n\n\trunListeners(action, params) {\n if (!Object.keys(this.listeners[action])) {\n return\n }\n Object.keys(this.listeners[action]).forEach((route) => {\n var routeRe = getRegexpFromRoute(route);\n if (routeRe.exec(params.path)) {\n var result;\n for (let callback of this.listeners[action][route]) {\n result = callback.call(this.app, params)\n if (result) {\n params = result\n }\n }\n }\n })\n return params\n }\n\n handleEvents() {\n globalThis.addEventListener('popstate', () => {\n if (this.match(getPath(document.location.pathname + document.location.hash, this.root)) === false) {\n this.match(getPath(document.location.pathname, this.root))\n }\n })\n globalThis.document.addEventListener('click', (evt) => {\n\t if (evt.ctrlKey) {\n\t return;\n\t }\n\t if (evt.which != 1) {\n\t return; // not a 'left' mouse click\n\t }\n\t var link = evt.target;\n\t while (link && link.tagName!='A') {\n\t link = link.parentElement;\n\t }\n\t if (link \n\t && link.pathname \n\t && link.hostname==globalThis.location.hostname \n\t && !link.link\n\t && !link.dataset.simplyCommand\n\t ) {\n\t let path = getPath(link.pathname+link.hash, this.root);\n\t if ( !this.has(path) ) {\n\t path = getPath(link.pathname, this.root);\n\t }\n\t if ( this.has(path) ) {\n\t let params = this.runListeners('goto', { path: path});\n\t if (params.path) {\n\t this.goto(params.path);\n\t }\n\t evt.preventDefault();\n\t return false;\n\t }\n\t }\n\t })\n }\n\n goto(path) {\n history.pushState({},'',getURL(path))\n return this.match(path)\n }\n\n has(path) {\n \tpath = getPath(path, this.root)\n \tfor (let route of this.routeInfo) {\n var matches = route.match.exec(path)\n if (matches && matches.length) {\n return true\n }\n }\n return false\n }\n\n addListener(action, route, callback) {\n if (['goto','match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n this.listeners[action][route] = []\n }\n this.listeners[action][route].push(callback)\n }\n\n removeListener(action, route, callback) {\n if (['match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n return\n }\n this.listeners[action][route] = this.listeners[action][route].filter((listener) => {\n return listener != callback\n })\n }\n\n init(options) {\n \tif (options.root) {\n \t\tthis.root = options.root\n \t}\n }\n}\n\nfunction getPath(path, root='/') {\n if (path.substring(0,root.length)==root\n ||\n ( root[root.length-1]=='/' \n && path.length==(root.length-1)\n && path == root.substring(0,path.length)\n )\n ) {\n path = path.substring(root.length)\n }\n if (path[0]!='/' && path[0]!='#') {\n path = '/'+path\n }\n return path\n}\n\nfunction getURL(path, root) {\n path = getPath(path, root)\n if (root[root.length-1]==='/' && path[0]==='/') {\n path = path.substring(1)\n }\n return root + path;\n}\n\nfunction getRegexpFromRoute(route) {\n return new RegExp('^'+route.replace(/:\\w+/g, '([^/]+)').replace(/:\\*/, '(.*)'));\n}\n\nfunction parseRoutes(routes, routeInfo) {\n const paths = Object.keys(routes)\n const matchParams = /:(\\w+|\\*)/g\n for (let path of paths) {\n let matches = []\n let params = []\n do {\n matches = matchParams.exec(path)\n if (matches) {\n params.push(matches[1])\n }\n } while(matches)\n routeInfo.push({\n match: getRegexpFromRoute(path),\n params: params,\n action: routes[path]\n })\n }\n return routeInfo\n}\n", "class SimplyCommands {\n\tconstructor(options={}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tthis.$handlers = options.handlers || defaultHandlers\n if (options.commands) {\n \t\tObject.assign(this, options.commands)\n }\n\n\t\tconst commandHandler = (evt) => {\n\t\t\tconst command = getCommand(evt, this.$handlers)\n\t\t\tif (!command) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!this[command.name]) {\n console.error('simply.command: undefined command '+command.name, command.source);\n return\n\t\t\t}\n const shouldContinue = this[command.name].call(options.app, command.source, command.value)\n if (shouldContinue!==true) {\n evt.preventDefault()\n evt.stopPropagation()\n return false\n }\n\t\t}\n\n options.app.container.addEventListener('click', commandHandler)\n options.app.container.addEventListener('submit', commandHandler)\n options.app.container.addEventListener('change', commandHandler)\n options.app.container.addEventListener('input', commandHandler)\n\t}\n}\n\nexport function commands(options={}) {\n\treturn new SimplyCommands(options)\n}\n\nfunction getCommand(evt, handlers) {\n var el = evt.target.closest('[data-simply-command]')\n if (el) {\n for (let handler of handlers) {\n if (el.matches(handler.match)) {\n if (handler.check(el, evt)) {\n return {\n name: el.dataset.simplyCommand,\n source: el,\n value: handler.get(el)\n }\n }\n return null\n }\n }\n }\n return null\n}\n\nconst defaultHandlers = [\n {\n match: 'input,select,textarea',\n get: function(el) {\n if (el.tagName==='SELECT' && el.multiple) {\n let values = []\n for (let option of el.options) {\n if (option.selected) {\n values.push(option.value)\n }\n }\n return values\n }\n return el.dataset.simplyValue || el.value\n },\n check: function(el, evt) {\n return evt.type=='change' || (el.dataset.simplyImmediate && evt.type=='input')\n }\n },\n {\n match: 'a,button',\n get: function(el) {\n return el.dataset.simplyValue || el.href || el.value\n },\n check: function(el,evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n },\n {\n match: 'form',\n get: function(el) {\n let data = {}\n for (let input of Array.from(el.elements)) {\n if (input.tagName=='INPUT' \n && (input.type=='checkbox' || input.type=='radio')\n ) {\n if (!input.checked) {\n return;\n }\n }\n if (data[input.name] && !Array.isArray(data[input.name])) {\n data[input.name] = [data[input.name]]\n }\n if (Array.isArray(data[input.name])) {\n data[input.name].push(input.value)\n } else {\n data[input.name] = input.value\n }\n }\n return data\n },\n check: function(el,evt) {\n return evt.type=='submit'\n }\n },\n {\n \tmatch: '*',\n get: function(el) {\n return el.dataset.simplyValue\n },\n check: function(el, evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n }\n]", "const KEY = Object.freeze({\n\tCompose: 229,\n\tControl: 17,\n\tMeta: 224,\n\tAlt: 18,\n\tShift: 16\n})\n\nclass SimplyKey {\n\tconstructor(options = {}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tObject.assign(this, options.keys)\n\n\t\tconst keyHandler = (e) => {\n\t\t\tif (e.isComposing || e.keyCode === KEY.Compose) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (e.defaultPrevented) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (!e.target) {\n\t\t\t return\n\t\t\t}\n\n\t\t\tlet selectedKeyboard = 'default'\n\t\t\tif (e.target.closest('[data-simply-keyboard]')) {\n\t\t\t selectedKeyboard = e.target.closest('[data-simply-keyboard]')\n\t\t\t \t\t\t\t\t.dataset.simplyKeyboard\n\t\t\t}\n\t\t\tlet keyCombination = []\n\t\t\tif (e.ctrlKey && e.keyCode!=KEY.Control) {\n\t\t\t keyCombination.push('Control')\n\t\t\t}\n\t\t\tif (e.metaKey && e.keyCode!=KEY.Meta) {\n\t\t\t keyCombination.push('Meta')\n\t\t\t}\n\t\t\tif (e.altKey && e.keyCode!=KEY.Alt) {\n\t\t\t keyCombination.push('Alt')\n\t\t\t}\n\t\t\tif (e.shiftKey && e.keyCode!=KEY.Shift) {\n\t\t\t keyCombination.push('Shift')\n\t\t\t}\n\t\t\tkeyCombination.push(e.key.toLowerCase())\n\n\t\t\tlet keyboards = []\n\t\t\tlet keyboardElement = event.target.closest('[data-simply-keyboard]')\n\t\t\twhile (keyboardElement) {\n\t\t\t\tkeyboards.push(keyboardElement.dataset.simplyKeyboard)\n\t\t\t\tkeyboardElement = keyboardElement.parentNode.closest('[data-simply-keyboard]')\n\t\t\t}\n\t\t\tkeyboards.push('')\n\n\t\t\tlet keyboard, subkeyboard\n\t\t\tlet separators = ['+','-']\n\n\t\t\tfor (i in keyboards) {\n\t\t\t\tkeyboard = keyboards[i]\n\t\t\t\tif (keyboard == '') {\n\t\t\t\t\tsubkeyboard = 'default'\n\t\t\t\t} else {\n\t\t\t\t\tsubkeyboard = keyboard\n\t\t\t\t\tkeyboard += '.'\n\t\t\t\t}\n\t\t\t\tfor (let separator of separators) {\n\t\t\t\t\tlet keyString = keyCombination.join(separator)\n\n\t\t\t\t\tif (this[subkeyboard] && (typeof this[subkeyboard][keyString]=='function')) {\n\t\t\t\t\t\tlet _continue = this[subkeyboard][keyString].call(this[subkeyboard], e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof this[subkeyboard + keyString] == 'function') {\n\t\t\t\t\t\tlet _continue = this[subkeyboard + keyString].call(this, e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\t\t\t\t\t\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this[selectedKeyboard] && this[selectedKeyboard][keyString]) {\n\t\t\t\t\t\tlet targets = options.app.container.querySelectorAll('[data-simply-accesskey=\"'\n\t\t\t\t\t\t\t+ keyboard + keyString + '\"]')\n\t\t\t\t\t\tif (targets.length) {\n\t\t\t\t\t\t\ttargets.forEach(t => t.click())\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\toptions.app.container.addEventListener('keydown', keyHandler)\n\t}\n\n}\n\nexport function keys(options={}) {\n\treturn new SimplyKey(options)\n}\n\n", "export function view(options) {\n\tif (options.app) {\n\t\toptions.app.view = options.view || {}\n\n\t\tconst load = () => {\n\t\t\tconst data = options.app.view\n\t\t\tconst path = globalThis.editor.data.getDataPath(options.app.container || document.body)\n\t\t\toptions.app.view = globalThis.editor.currentData[path]\n\t\t\tObject.assign(options.app.view, data)\n\t\t}\n\t\tif (globalThis.editor && globalThis.editor.currentData) {\n\t\t\tload()\n\t\t} else {\n\t\t\tdocument.addEventListener('simply-content-loaded', load)\n\t\t}\n\t\treturn options.app.view\n\t} else {\n\t\treturn options.view\n\t}\n}", "import { routes } from './route.mjs'\nimport { commands } from './command.mjs'\nimport { actions } from './action.mjs'\nimport { keys } from './key.mjs'\nimport { view } from './view.mjs'\n\nclass SimplyApp {\n\tconstructor(options={}) {\n\t\tthis.container = options.container || document.body\n\t\tif (options.commands) {\n\t\t\tthis.commands = commands({ app: this, container: this.container, commands: options.commands})\n\t\t}\n\t\tif (options.keys) {\n\t\t\tthis.keys = keys({ app: this, keys: options.keys })\n\t\t}\n\t\tif (options.routes) {\n\t\t\tthis.routes = routes({ app: this, routes: options.routes})\n\t\t}\n\t\tif (options.actions) {\n\t\t\tthis.actions = actions({app: this, actions: options.actions})\n\t\t}\n\t\tif (options.view) {\n\t\t\tthis.view = view({app: this, view: options.view})\n\t\t}\n\t}\n}\n\nexport function app(options={}) {\n\treturn new SimplyApp(options)\n}", "function throttle( callbackFunction, intervalTime ) {\n let eventId = 0\n return () => {\n const myArguments = arguments\n if ( eventId ) {\n return\n } else {\n eventId = globalThis.setTimeout( () => {\n callbackFunction.apply(this, myArguments)\n eventId = 0\n }, intervalTime )\n }\n }\n}\n\nconst runWhenIdle = (() => {\n if (globalThis.requestIdleCallback) {\n return (callback) => {\n globalThis.requestIdleCallback(callback, {timeout: 500})\n }\n }\n return globalThis.requestAnimationFrame\n})()\n\nfunction rebaseHref(relative, base) {\n let url = new URL(relative, base)\n if (include.cacheBuster) {\n url.searchParams.set('cb',include.cacheBuster)\n }\n return url.href\n}\n\nlet observer, loaded = {}\nlet head = globalThis.document.querySelector('head')\nlet currentScript = globalThis.document.currentScript\nlet getScriptURL, currentScriptURL\nif (!currentScript) {\n getScriptURL = (() => {\n var scripts = document.getElementsByTagName('script')\n var index = scripts.length - 1\n var myScript = scripts[index]\n return () => myScript.src\n })()\n currentScriptURL = getScriptURL()\n} else {\n currentScriptURL = currentScript.src\n}\n\nconst waitForPreviousScripts = async () => {\n // because of the async=false attribute, this script will run after\n // the previous scripts have been loaded and run\n // simply.include.next.js only fires the simply-next-script event\n // that triggers the Promise.resolve method\n return new Promise(function(resolve) {\n var next = globalThis.document.createElement('script')\n next.src = \"https://cdn.jsdelivr.net/gh/simplyedit/simplyview/dist/simply.include.next.js\"\n next.async = false\n globalThis.document.addEventListener('simply-include-next', () => {\n head.removeChild(next)\n resolve()\n }, { once: true, passive: true})\n head.appendChild(next)\n })\n}\n\nlet scriptLocations = []\n\nexport const include = {\n cacheBuster: null,\n scripts: (scripts, base) => {\n let arr = scripts.slice()\n const importScript = () => {\n const script = arr.shift()\n if (!script) {\n return\n }\n const attrs = [].map.call(script.attributes, (attr) => {\n return attr.name\n })\n let clone = globalThis.document.createElement('script')\n for (const attr of attrs) {\n clone.setAttribute(attr, script.getAttribute(attr))\n }\n clone.removeAttribute('data-simply-location')\n if (!clone.src) {\n // this is an inline script, so copy the content and wait for previous scripts to run\n clone.innerHTML = script.innerHTML\n waitForPreviousScripts()\n .then(() => {\n const node = scriptLocations[script.dataset.simplyLocation]\n node.parentNode.insertBefore(clone, node)\n node.parentNode.removeChild(node)\n importScript()\n })\n } else {\n clone.src = rebaseHref(clone.src, base)\n if (!clone.hasAttribute('async') && !clone.hasAttribute('defer')) {\n clone.async = false //important! do not use clone.setAttribute('async', false) - it has no effect\n }\n const node = scriptLocations[script.dataset.simplyLocation]\n node.parentNode.insertBefore(clone, node)\n node.parentNode.removeChild(node)\n loaded[clone.src]=true\n importScript()\n }\n }\n if (arr.length) {\n importScript()\n }\n },\n html: (html, link) => {\n let fragment = globalThis.document.createRange().createContextualFragment(html)\n const stylesheets = fragment.querySelectorAll('link[rel=\"stylesheet\"],style')\n // add all stylesheets to head\n for (let stylesheet of stylesheets) {\n if (stylesheet.href) {\n stylesheet.href = rebaseHref(stylesheet.href, link.href)\n }\n head.appendChild(stylesheet)\n }\n // remove the scripts from the fragment, as they will not run in the\n // order in which they are defined\n let scriptsFragment = globalThis.document.createDocumentFragment()\n const scripts = fragment.querySelectorAll('script')\n if (scripts.length) {\n for (let script of scripts) {\n let placeholder = globalThis.document.createComment(script.src || 'inline script')\n script.parentNode.insertBefore(placeholder, script)\n script.dataset.simplyLocation = scriptLocations.length\n scriptLocations.push(placeholder)\n scriptsFragment.appendChild(script)\n }\n globalThis.setTimeout(function() {\n include.scripts(Array.from(scriptsFragment.children), link ? link.href : globalThis.location.href )\n }, 10)\n }\n // add the remainder before the include link\n link.parentNode.insertBefore(fragment, link ? link : null)\n\n }\n}\n\nlet included = {}\nconst includeLinks = async (links) => {\n // mark them as in progress, so handleChanges doesn't find them again\n let remainingLinks = [].reduce.call(links, (remainder, link) => {\n if (link.rel=='simply-include-once' && included[link.href]) {\n link.parentNode.removeChild(link)\n } else {\n included[link.href]=true\n link.rel = 'simply-include-loading'\n remainder.push(link)\n }\n return remainder\n }, [])\n\n for (let link of remainingLinks) {\n if (!link.href) {\n return\n }\n // fetch the html\n const response = await fetch(link.href)\n if (!response.ok) {\n console.log('simply-include: failed to load '+link.href);\n continue\n }\n console.log('simply-include: loaded '+link.href);\n const html = await response.text()\n // if succesfull import the html\n include.html(html, link)\n // remove the include link\n link.parentNode.removeChild(link)\n }\n}\n\nconst handleChanges = throttle(() => {\n runWhenIdle(() => {\n var links = globalThis.document.querySelectorAll('link[rel=\"simply-include\"],link[rel=\"simply-include-once\"]')\n if (links.length) {\n includeLinks(links)\n }\n })\n})\n\nconst observe = () => {\n observer = new MutationObserver(handleChanges)\n observer.observe(globalThis.document, {\n subtree: true,\n childList: true,\n })\n}\n\nobserve()\nhandleChanges() // check if there are include links in the dom already\n", "import { activate } from './activate.mjs'\nimport { actions as action } from './action.mjs'\nimport { app } from './app.mjs'\nimport { commands as command } from './command.mjs'\nimport { include } from './include.mjs'\nimport { keys as key } from './key.mjs'\nimport { routes as route } from './route.mjs'\nimport { view } from './view.mjs'\n\nconst simply = {\n\tactivate,\n\taction,\n\tapp,\n\tcommand,\n\tinclude,\n\tkey,\n\troute,\n\tview\n}\n\nwindow.simply = simply\n\nexport default simply"],
5
- "mappings": "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",
6
- "names": ["listeners", "activate", "name", "callback", "initialCall", "listener", "nodes", "node", "callListeners", "handleChanges", "changes", "activateNodes", "change", "toActivate", "observer", "actions", "options", "actionHandler", "target", "property", "routes", "options", "SimplyRoute", "parseRoutes", "path", "args", "matches", "getPath", "route", "params", "key", "i", "action", "routeRe", "getRegexpFromRoute", "result", "callback", "evt", "link", "getURL", "listener", "root", "routeInfo", "paths", "matchParams", "SimplyCommands", "options", "defaultHandlers", "commandHandler", "evt", "command", "getCommand", "commands", "handlers", "el", "handler", "values", "option", "data", "input", "KEY", "SimplyKey", "options", "keyHandler", "e", "selectedKeyboard", "keyCombination", "keyboards", "keyboardElement", "keyboard", "subkeyboard", "separators", "separator", "keyString", "targets", "t", "keys", "view", "options", "load", "data", "path", "SimplyApp", "options", "commands", "keys", "routes", "actions", "view", "app", "throttle", "callbackFunction", "intervalTime", "eventId", "myArguments", "runWhenIdle", "callback", "rebaseHref", "relative", "base", "url", "include", "observer", "loaded", "head", "currentScript", "getScriptURL", "currentScriptURL", "scripts", "index", "myScript", "waitForPreviousScripts", "resolve", "next", "scriptLocations", "arr", "importScript", "script", "attrs", "attr", "clone", "node", "html", "link", "fragment", "stylesheets", "stylesheet", "scriptsFragment", "placeholder", "included", "includeLinks", "links", "remainingLinks", "remainder", "response", "handleChanges", "observe", "simply", "activate", "actions", "app", "commands", "include", "keys", "routes", "view", "everything_default"]
4
+ "sourcesContent": ["const listeners = new Map()\n\nexport const activate = {\n addListener: (name, callback) => {\n if (!listeners.has(name)) {\n listeners.set(name, [])\n }\n listeners.get(name).push(callback)\n initialCall(name)\n },\n removeListener: (name, callback) => {\n if (!listeners.has(name)) {\n return false\n }\n listeners.set(name, listeners.get(name).filter((listener) => {\n return listener!=callback\n }))\n }\n}\n\nfunction initialCall(name) {\n const nodes = document.querySelectorAll('[data-simply-activate=\"'+name+'\"]')\n if (nodes) {\n for( let node of nodes) {\n callListeners(node)\n }\n }\n}\n\nfunction callListeners(node) {\n const activate = node?.dataset?.simplyActivate\n if (activate && listeners.has(activate)) {\n for (let callback of listeners.get(activate)) {\n callback.call(node)\n }\n }\n}\n\nfunction handleChanges(changes) {\n let activateNodes = []\n for (let change of changes) {\n if (change.type == 'childList') {\n for (let node of change.addedNodes) {\n if (node.querySelectorAll) {\n var toActivate = Array.from(node.querySelectorAll('[data-simply-activate]'))\n if (node.matches('[data-simply-activate]')) {\n toActivate.push(node)\n }\n activateNodes = activateNodes.concat(toActivate)\n }\n }\n }\n }\n for (let node of activateNodes) {\n callListeners(node)\n }\n}\n\nconst observer = new MutationObserver(handleChanges)\nobserver.observe(document, {\n subtree: true,\n childList: true\n})", "export function actions(options) {\n\tif (options.app) {\n\t\tconst actionHandler = {\n\t\t\tget: (target, property) => {\n\t\t\t\treturn target[property].bind(options.app)\n\t\t\t}\n\t\t}\n\t\treturn new Proxy(options.actions, actionHandler)\n\t} else {\n\t\treturn options\n\t}\n}", "export function routes(options) {\n\treturn new SimplyRoute(options)\n}\n\nclass SimplyRoute {\n\tconstructor(options={}) {\n\t\tthis.root = options.root || '/'\n this.app = options.app\n this.addMissingSlash = !!options.addMissingSlash\n this.matchExact = !!options.matchExact\n\t\tthis.clear()\n\t\tif (options.routes) {\n\t\t\tthis.load(options.routes)\n\t\t}\n\t}\n\n\tload(routes) {\n\t\tparseRoutes(routes, this.routeInfo, this.matchExact)\n\t}\n\n\tclear() {\n\t\tthis.routeInfo = []\n\t\tthis.listeners = {\n\t\t\tmatch: {},\n\t\t\tcall: {},\n\t\t\tfinish: {}\n\t\t}\n\t}\n\n\tmatch(path, options) {\n\t\tlet args = {\n path,\n options\n }\n args = this.runListeners('match',args)\n path = args.path ? args.path : path;\n\n let matches;\n if (!path) {\n if (this.match(document.location.pathname+document.location.hash)) {\n return true;\n } else {\n return this.match(document.location.pathname);\n }\n }\n path = getPath(path);\n for ( let route of this.routeInfo) {\n matches = route.match.exec(path)\n if (this.addMissingSlash && !matches?.length) {\n if (path && path[path.length-1]!='/') {\n matches = route.match.exec(path+'/')\n if (matches) {\n path+='/'\n history.replaceState({}, '', getURL(path))\n }\n }\n }\n if (matches && matches.length) {\n var params = {};\n route.params.forEach((key, i) => {\n if (key=='*') {\n key = 'remainder'\n }\n params[key] = matches[i+1]\n })\n Object.assign(params, options)\n args.route = route\n args.params = params\n args = this.runListeners('call', args)\n params = args.params ? args.params : params\n args.result = route.action.call(route, params)\n this.runListeners('finish', args)\n return args.result\n }\n }\n return false\n\t}\n\n\trunListeners(action, params) {\n if (!Object.keys(this.listeners[action])) {\n return\n }\n Object.keys(this.listeners[action]).forEach((route) => {\n var routeRe = getRegexpFromRoute(route);\n if (routeRe.exec(params.path)) {\n var result;\n for (let callback of this.listeners[action][route]) {\n result = callback.call(this.app, params)\n if (result) {\n params = result\n }\n }\n }\n })\n return params\n }\n\n handleEvents() {\n globalThis.addEventListener('popstate', () => {\n if (this.match(getPath(document.location.pathname + document.location.hash, this.root)) === false) {\n this.match(getPath(document.location.pathname, this.root))\n }\n })\n this.app.container.addEventListener('click', (evt) => {\n\t if (evt.ctrlKey) {\n\t return;\n\t }\n\t if (evt.which != 1) {\n\t return; // not a 'left' mouse click\n\t }\n\t var link = evt.target;\n\t while (link && link.tagName!='A') {\n\t link = link.parentElement;\n\t }\n\t if (link \n\t && link.pathname \n\t && link.hostname==globalThis.location.hostname \n\t && !link.link\n\t && !link.dataset.simplyCommand\n\t ) {\n\t let path = getPath(link.pathname+link.hash, this.root);\n\t if ( !this.has(path) ) {\n\t path = getPath(link.pathname, this.root);\n\t }\n\t if ( this.has(path) ) {\n\t let params = this.runListeners('goto', { path: path});\n\t if (params.path) {\n\t if (this.goto(params.path)) {\n // now cancel the browser navigation, since a route handler was found\n evt.preventDefault();\n return false;\n }\n\t }\n\t }\n\t }\n\t })\n }\n\n goto(path) {\n history.pushState({},'',getURL(path))\n return this.match(path)\n }\n\n has(path) {\n \tpath = getPath(path, this.root)\n \tfor (let route of this.routeInfo) {\n var matches = route.match.exec(path)\n if (matches && matches.length) {\n return true\n }\n }\n return false\n }\n\n addListener(action, route, callback) {\n if (['goto','match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n this.listeners[action][route] = []\n }\n this.listeners[action][route].push(callback)\n }\n\n removeListener(action, route, callback) {\n if (['match','call','finish'].indexOf(action)==-1) {\n throw new Error('Unknown action '+action)\n }\n if (!this.listeners[action][route]) {\n return\n }\n this.listeners[action][route] = this.listeners[action][route].filter((listener) => {\n return listener != callback\n })\n }\n\n init(options) {\n \tif (options.root) {\n \t\tthis.root = options.root\n \t}\n }\n}\n\nfunction getPath(path, root='/') {\n if (path.substring(0,root.length)==root\n ||\n ( root[root.length-1]=='/' \n && path.length==(root.length-1)\n && path == root.substring(0,path.length)\n )\n ) {\n path = path.substring(root.length)\n }\n if (path[0]!='/' && path[0]!='#') {\n path = '/'+path\n }\n return path\n}\n\nfunction getURL(path, root) {\n path = getPath(path, root)\n if (root[root.length-1]==='/' && path[0]==='/') {\n path = path.substring(1)\n }\n return root + path;\n}\n\nfunction getRegexpFromRoute(route, exact=false) {\n if (exact) {\n return new RegExp('^'+route.replace(/:\\w+/g, '([^/]+)').replace(/:\\*/, '(.*)')+'(\\\\?|$)')\n }\n return new RegExp('^'+route.replace(/:\\w+/g, '([^/]+)').replace(/:\\*/, '(.*)'))\n}\n\nfunction parseRoutes(routes, routeInfo, exact=false) {\n const paths = Object.keys(routes)\n const matchParams = /:(\\w+|\\*)/g\n for (let path of paths) {\n let matches = []\n let params = []\n do {\n matches = matchParams.exec(path)\n if (matches) {\n params.push(matches[1])\n }\n } while(matches)\n routeInfo.push({\n match: getRegexpFromRoute(path, exact),\n params: params,\n action: routes[path]\n })\n }\n return routeInfo\n}\n", "class SimplyCommands {\n\tconstructor(options={}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tthis.$handlers = options.handlers || defaultHandlers\n if (options.commands) {\n \t\tObject.assign(this, options.commands)\n }\n\n\t\tconst commandHandler = (evt) => {\n\t\t\tconst command = getCommand(evt, this.$handlers)\n\t\t\tif (!command) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!this[command.name]) {\n console.error('simply.command: undefined command '+command.name, command.source);\n return\n\t\t\t}\n const shouldContinue = this[command.name].call(options.app, command.source, command.value)\n if (shouldContinue!==true) {\n evt.preventDefault()\n evt.stopPropagation()\n return false\n }\n\t\t}\n\n options.app.container.addEventListener('click', commandHandler)\n options.app.container.addEventListener('submit', commandHandler)\n options.app.container.addEventListener('change', commandHandler)\n options.app.container.addEventListener('input', commandHandler)\n\t}\n}\n\nexport function commands(options={}) {\n\treturn new SimplyCommands(options)\n}\n\nfunction getCommand(evt, handlers) {\n var el = evt.target.closest('[data-simply-command]')\n if (el) {\n for (let handler of handlers) {\n if (el.matches(handler.match)) {\n if (handler.check(el, evt)) {\n return {\n name: el.dataset.simplyCommand,\n source: el,\n value: handler.get(el)\n }\n }\n return null\n }\n }\n }\n return null\n}\n\nconst defaultHandlers = [\n {\n match: 'input,select,textarea',\n get: function(el) {\n if (el.tagName==='SELECT' && el.multiple) {\n let values = []\n for (let option of el.options) {\n if (option.selected) {\n values.push(option.value)\n }\n }\n return values\n }\n return el.dataset.simplyValue || el.value\n },\n check: function(el, evt) {\n return evt.type=='change' || (el.dataset.simplyImmediate && evt.type=='input')\n }\n },\n {\n match: 'a,button',\n get: function(el) {\n return el.dataset.simplyValue || el.href || el.value\n },\n check: function(el,evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n },\n {\n match: 'form',\n get: function(el) {\n let data = {}\n for (let input of Array.from(el.elements)) {\n if (input.tagName=='INPUT' \n && (input.type=='checkbox' || input.type=='radio')\n ) {\n if (!input.checked) {\n return;\n }\n }\n if (data[input.name] && !Array.isArray(data[input.name])) {\n data[input.name] = [data[input.name]]\n }\n if (Array.isArray(data[input.name])) {\n data[input.name].push(input.value)\n } else {\n data[input.name] = input.value\n }\n }\n return data\n },\n check: function(el,evt) {\n return evt.type=='submit'\n }\n },\n {\n \tmatch: '*',\n get: function(el) {\n return el.dataset.simplyValue\n },\n check: function(el, evt) {\n return evt.type=='click' && evt.ctrlKey==false && evt.button==0\n }\n }\n]", "const KEY = Object.freeze({\n\tCompose: 229,\n\tControl: 17,\n\tMeta: 224,\n\tAlt: 18,\n\tShift: 16\n})\n\nclass SimplyKey {\n\tconstructor(options = {}) {\n\t\tif (!options.app) {\n\t\t\toptions.app = {}\n\t\t}\n\t\tif (!options.app.container) {\n\t\t\toptions.app.container = document.body\n\t\t}\n\t\tObject.assign(this, options.keys)\n\n\t\tconst keyHandler = (e) => {\n\t\t\tif (e.isComposing || e.keyCode === KEY.Compose) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (e.defaultPrevented) {\n\t\t\t return\n\t\t\t}\n\t\t\tif (!e.target) {\n\t\t\t return\n\t\t\t}\n\n\t\t\tlet selectedKeyboard = 'default'\n\t\t\tif (e.target.closest('[data-simply-keyboard]')) {\n\t\t\t selectedKeyboard = e.target.closest('[data-simply-keyboard]')\n\t\t\t \t\t\t\t\t.dataset.simplyKeyboard\n\t\t\t}\n\t\t\tlet keyCombination = []\n\t\t\tif (e.ctrlKey && e.keyCode!=KEY.Control) {\n\t\t\t keyCombination.push('Control')\n\t\t\t}\n\t\t\tif (e.metaKey && e.keyCode!=KEY.Meta) {\n\t\t\t keyCombination.push('Meta')\n\t\t\t}\n\t\t\tif (e.altKey && e.keyCode!=KEY.Alt) {\n\t\t\t keyCombination.push('Alt')\n\t\t\t}\n\t\t\tif (e.shiftKey && e.keyCode!=KEY.Shift) {\n\t\t\t keyCombination.push('Shift')\n\t\t\t}\n\t\t\tkeyCombination.push(e.key.toLowerCase())\n\n\t\t\tlet keyboards = []\n\t\t\tlet keyboardElement = event.target.closest('[data-simply-keyboard]')\n\t\t\twhile (keyboardElement) {\n\t\t\t\tkeyboards.push(keyboardElement.dataset.simplyKeyboard)\n\t\t\t\tkeyboardElement = keyboardElement.parentNode.closest('[data-simply-keyboard]')\n\t\t\t}\n\t\t\tkeyboards.push('')\n\n\t\t\tlet keyboard, subkeyboard\n\t\t\tlet separators = ['+','-']\n\n\t\t\tfor (i in keyboards) {\n\t\t\t\tkeyboard = keyboards[i]\n\t\t\t\tif (keyboard == '') {\n\t\t\t\t\tsubkeyboard = 'default'\n\t\t\t\t} else {\n\t\t\t\t\tsubkeyboard = keyboard\n\t\t\t\t\tkeyboard += '.'\n\t\t\t\t}\n\t\t\t\tfor (let separator of separators) {\n\t\t\t\t\tlet keyString = keyCombination.join(separator)\n\n\t\t\t\t\tif (this[subkeyboard] && (typeof this[subkeyboard][keyString]=='function')) {\n\t\t\t\t\t\tlet _continue = this[subkeyboard][keyString].call(this[subkeyboard], e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof this[subkeyboard + keyString] == 'function') {\n\t\t\t\t\t\tlet _continue = this[subkeyboard + keyString].call(this, e)\n\t\t\t\t\t\tif (!_continue) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\t\t\t\t\t\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this[selectedKeyboard] && this[selectedKeyboard][keyString]) {\n\t\t\t\t\t\tlet targets = options.app.container.querySelectorAll('[data-simply-accesskey=\"'\n\t\t\t\t\t\t\t+ keyboard + keyString + '\"]')\n\t\t\t\t\t\tif (targets.length) {\n\t\t\t\t\t\t\ttargets.forEach(t => t.click())\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\toptions.app.container.addEventListener('keydown', keyHandler)\n\t}\n\n}\n\nexport function keys(options={}) {\n\treturn new SimplyKey(options)\n}\n\n", "export function view(options) {\n\tif (options.app) {\n\t\toptions.app.view = options.view || {}\n\n\t\tconst load = () => {\n\t\t\tconst data = options.app.view\n\t\t\tconst path = globalThis.editor.data.getDataPath(options.app.container || document.body)\n\t\t\toptions.app.view = globalThis.editor.currentData[path]\n\t\t\tObject.assign(options.app.view, data)\n\t\t}\n\t\tif (globalThis.editor && globalThis.editor.currentData) {\n\t\t\tload()\n\t\t} else {\n\t\t\tdocument.addEventListener('simply-content-loaded', load)\n\t\t}\n\t\treturn options.app.view\n\t} else {\n\t\treturn options.view\n\t}\n}", "import { routes } from './route.mjs'\nimport { commands } from './command.mjs'\nimport { actions } from './action.mjs'\nimport { keys } from './key.mjs'\nimport { view } from './view.mjs'\n\nclass SimplyApp {\n\tconstructor(options={}) {\n\t\tthis.container = options.container || document.body\n\t\tfor (let key in options) {\n\t\t\tswitch(key) {\n\t\t\t\tcase 'commands':\n\t\t\t\t\tthis.commands = commands({ app: this, container: this.container, commands: options.commands})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'keys':\n\t\t\t\tcase 'keyboard': // backwards compatible\n\t\t\t\t\tthis.keys = keys({ app: this, keys: options.keys })\n\t\t\t\t\tbreak\n\t\t\t\tcase 'routes':\n\t\t\t\t\tthis.routes = routes({ app: this, routes: options.routes})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'actions':\n\t\t\t\t\tthis.actions = actions({app: this, actions: options.actions})\n\t\t\t\t\tbreak\n\t\t\t\tcase 'view':\n\t\t\t\t\tthis.view = view({app: this, view: options.view})\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tthis[key] = options[key] // allows easy additions\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function app(options={}) {\n\treturn new SimplyApp(options)\n}", "function throttle( callbackFunction, intervalTime ) {\n let eventId = 0\n return () => {\n const myArguments = arguments\n if ( eventId ) {\n return\n } else {\n eventId = globalThis.setTimeout( () => {\n callbackFunction.apply(this, myArguments)\n eventId = 0\n }, intervalTime )\n }\n }\n}\n\nconst runWhenIdle = (() => {\n if (globalThis.requestIdleCallback) {\n return (callback) => {\n globalThis.requestIdleCallback(callback, {timeout: 500})\n }\n }\n return globalThis.requestAnimationFrame\n})()\n\nfunction rebaseHref(relative, base) {\n let url = new URL(relative, base)\n if (include.cacheBuster) {\n url.searchParams.set('cb',include.cacheBuster)\n }\n return url.href\n}\n\nlet observer, loaded = {}\nlet head = globalThis.document.querySelector('head')\nlet currentScript = globalThis.document.currentScript\nlet getScriptURL, currentScriptURL\nif (!currentScript) {\n getScriptURL = (() => {\n var scripts = document.getElementsByTagName('script')\n var index = scripts.length - 1\n var myScript = scripts[index]\n return () => myScript.src\n })()\n currentScriptURL = getScriptURL()\n} else {\n currentScriptURL = currentScript.src\n}\n\nconst waitForPreviousScripts = async () => {\n // because of the async=false attribute, this script will run after\n // the previous scripts have been loaded and run\n // simply.include.next.js only fires the simply-next-script event\n // that triggers the Promise.resolve method\n return new Promise(function(resolve) {\n var next = globalThis.document.createElement('script')\n next.src = \"https://cdn.jsdelivr.net/gh/simplyedit/simplyview/dist/simply.include.next.js\"\n next.async = false\n globalThis.document.addEventListener('simply-include-next', () => {\n head.removeChild(next)\n resolve()\n }, { once: true, passive: true})\n head.appendChild(next)\n })\n}\n\nlet scriptLocations = []\n\nexport const include = {\n cacheBuster: null,\n scripts: (scripts, base) => {\n let arr = scripts.slice()\n const importScript = () => {\n const script = arr.shift()\n if (!script) {\n return\n }\n const attrs = [].map.call(script.attributes, (attr) => {\n return attr.name\n })\n let clone = globalThis.document.createElement('script')\n for (const attr of attrs) {\n clone.setAttribute(attr, script.getAttribute(attr))\n }\n clone.removeAttribute('data-simply-location')\n if (!clone.src) {\n // this is an inline script, so copy the content and wait for previous scripts to run\n clone.innerHTML = script.innerHTML\n waitForPreviousScripts()\n .then(() => {\n const node = scriptLocations[script.dataset.simplyLocation]\n node.parentNode.insertBefore(clone, node)\n node.parentNode.removeChild(node)\n importScript()\n })\n } else {\n clone.src = rebaseHref(clone.src, base)\n if (!clone.hasAttribute('async') && !clone.hasAttribute('defer')) {\n clone.async = false //important! do not use clone.setAttribute('async', false) - it has no effect\n }\n const node = scriptLocations[script.dataset.simplyLocation]\n node.parentNode.insertBefore(clone, node)\n node.parentNode.removeChild(node)\n loaded[clone.src]=true\n importScript()\n }\n }\n if (arr.length) {\n importScript()\n }\n },\n html: (html, link) => {\n let fragment = globalThis.document.createRange().createContextualFragment(html)\n const stylesheets = fragment.querySelectorAll('link[rel=\"stylesheet\"],style')\n // add all stylesheets to head\n for (let stylesheet of stylesheets) {\n if (stylesheet.href) {\n stylesheet.href = rebaseHref(stylesheet.href, link.href)\n }\n head.appendChild(stylesheet)\n }\n // remove the scripts from the fragment, as they will not run in the\n // order in which they are defined\n let scriptsFragment = globalThis.document.createDocumentFragment()\n const scripts = fragment.querySelectorAll('script')\n if (scripts.length) {\n for (let script of scripts) {\n let placeholder = globalThis.document.createComment(script.src || 'inline script')\n script.parentNode.insertBefore(placeholder, script)\n script.dataset.simplyLocation = scriptLocations.length\n scriptLocations.push(placeholder)\n scriptsFragment.appendChild(script)\n }\n globalThis.setTimeout(function() {\n include.scripts(Array.from(scriptsFragment.children), link ? link.href : globalThis.location.href )\n }, 10)\n }\n // add the remainder before the include link\n link.parentNode.insertBefore(fragment, link ? link : null)\n\n }\n}\n\nlet included = {}\nconst includeLinks = async (links) => {\n // mark them as in progress, so handleChanges doesn't find them again\n let remainingLinks = [].reduce.call(links, (remainder, link) => {\n if (link.rel=='simply-include-once' && included[link.href]) {\n link.parentNode.removeChild(link)\n } else {\n included[link.href]=true\n link.rel = 'simply-include-loading'\n remainder.push(link)\n }\n return remainder\n }, [])\n\n for (let link of remainingLinks) {\n if (!link.href) {\n return\n }\n // fetch the html\n const response = await fetch(link.href)\n if (!response.ok) {\n console.log('simply-include: failed to load '+link.href);\n continue\n }\n console.log('simply-include: loaded '+link.href);\n const html = await response.text()\n // if succesfull import the html\n include.html(html, link)\n // remove the include link\n link.parentNode.removeChild(link)\n }\n}\n\nconst handleChanges = throttle(() => {\n runWhenIdle(() => {\n var links = globalThis.document.querySelectorAll('link[rel=\"simply-include\"],link[rel=\"simply-include-once\"]')\n if (links.length) {\n includeLinks(links)\n }\n })\n})\n\nconst observe = () => {\n observer = new MutationObserver(handleChanges)\n observer.observe(globalThis.document, {\n subtree: true,\n childList: true,\n })\n}\n\nobserve()\nhandleChanges() // check if there are include links in the dom already\n", "import { activate } from './activate.mjs'\nimport { actions as action } from './action.mjs'\nimport { app } from './app.mjs'\nimport { commands as command } from './command.mjs'\nimport { include } from './include.mjs'\nimport { keys as key } from './key.mjs'\nimport { routes as route } from './route.mjs'\nimport { view } from './view.mjs'\n\nconst simply = {\n\tactivate,\n\taction,\n\tapp,\n\tcommand,\n\tinclude,\n\tkey,\n\troute,\n\tview\n}\n\nwindow.simply = simply\n\nexport default simply"],
5
+ "mappings": "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",
6
+ "names": ["listeners", "activate", "name", "callback", "initialCall", "listener", "nodes", "node", "callListeners", "handleChanges", "changes", "activateNodes", "change", "toActivate", "observer", "actions", "options", "actionHandler", "target", "property", "routes", "options", "SimplyRoute", "parseRoutes", "path", "args", "matches", "getPath", "route", "getURL", "params", "key", "i", "action", "routeRe", "getRegexpFromRoute", "result", "callback", "evt", "link", "listener", "root", "exact", "routeInfo", "paths", "matchParams", "SimplyCommands", "options", "defaultHandlers", "commandHandler", "evt", "command", "getCommand", "commands", "handlers", "el", "handler", "values", "option", "data", "input", "KEY", "SimplyKey", "options", "keyHandler", "e", "selectedKeyboard", "keyCombination", "keyboards", "keyboardElement", "keyboard", "subkeyboard", "separators", "separator", "keyString", "targets", "t", "keys", "view", "options", "load", "data", "path", "SimplyApp", "options", "key", "commands", "keys", "routes", "actions", "view", "app", "throttle", "callbackFunction", "intervalTime", "eventId", "myArguments", "runWhenIdle", "callback", "rebaseHref", "relative", "base", "url", "include", "observer", "loaded", "head", "currentScript", "getScriptURL", "currentScriptURL", "scripts", "index", "myScript", "waitForPreviousScripts", "resolve", "next", "scriptLocations", "arr", "importScript", "script", "attrs", "attr", "clone", "node", "html", "link", "fragment", "stylesheets", "stylesheet", "scriptsFragment", "placeholder", "included", "includeLinks", "links", "remainingLinks", "remainder", "response", "handleChanges", "observe", "simply", "activate", "actions", "app", "commands", "include", "keys", "routes", "view", "everything_default"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simplyview",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "Library to rapidly build UI components, using declarative tools",
5
5
  "main": "src/everything.mjs",
6
6
  "type": "module",
package/src/app.mjs CHANGED
@@ -7,20 +7,28 @@ import { view } from './view.mjs'
7
7
  class SimplyApp {
8
8
  constructor(options={}) {
9
9
  this.container = options.container || document.body
10
- if (options.commands) {
11
- this.commands = commands({ app: this, container: this.container, commands: options.commands})
12
- }
13
- if (options.keys) {
14
- this.keys = keys({ app: this, keys: options.keys })
15
- }
16
- if (options.routes) {
17
- this.routes = routes({ app: this, routes: options.routes})
18
- }
19
- if (options.actions) {
20
- this.actions = actions({app: this, actions: options.actions})
21
- }
22
- if (options.view) {
23
- this.view = view({app: this, view: options.view})
10
+ for (let key in options) {
11
+ switch(key) {
12
+ case 'commands':
13
+ this.commands = commands({ app: this, container: this.container, commands: options.commands})
14
+ break
15
+ case 'keys':
16
+ case 'keyboard': // backwards compatible
17
+ this.keys = keys({ app: this, keys: options.keys })
18
+ break
19
+ case 'routes':
20
+ this.routes = routes({ app: this, routes: options.routes})
21
+ break
22
+ case 'actions':
23
+ this.actions = actions({app: this, actions: options.actions})
24
+ break
25
+ case 'view':
26
+ this.view = view({app: this, view: options.view})
27
+ break
28
+ default:
29
+ this[key] = options[key] // allows easy additions
30
+ break
31
+ }
24
32
  }
25
33
  }
26
34
  }
package/src/route.mjs CHANGED
@@ -6,6 +6,8 @@ class SimplyRoute {
6
6
  constructor(options={}) {
7
7
  this.root = options.root || '/'
8
8
  this.app = options.app
9
+ this.addMissingSlash = !!options.addMissingSlash
10
+ this.matchExact = !!options.matchExact
9
11
  this.clear()
10
12
  if (options.routes) {
11
13
  this.load(options.routes)
@@ -13,7 +15,7 @@ class SimplyRoute {
13
15
  }
14
16
 
15
17
  load(routes) {
16
- parseRoutes(routes, this.routeInfo)
18
+ parseRoutes(routes, this.routeInfo, this.matchExact)
17
19
  }
18
20
 
19
21
  clear() {
@@ -44,6 +46,15 @@ class SimplyRoute {
44
46
  path = getPath(path);
45
47
  for ( let route of this.routeInfo) {
46
48
  matches = route.match.exec(path)
49
+ if (this.addMissingSlash && !matches?.length) {
50
+ if (path && path[path.length-1]!='/') {
51
+ matches = route.match.exec(path+'/')
52
+ if (matches) {
53
+ path+='/'
54
+ history.replaceState({}, '', getURL(path))
55
+ }
56
+ }
57
+ }
47
58
  if (matches && matches.length) {
48
59
  var params = {};
49
60
  route.params.forEach((key, i) => {
@@ -62,11 +73,6 @@ class SimplyRoute {
62
73
  return args.result
63
74
  }
64
75
  }
65
- if (path && path[path.length-1]!='/') {
66
- return this.match(path+'/', options)
67
- }
68
- console.log(path, this.routeInfo)
69
- process.exit()
70
76
  return false
71
77
  }
72
78
 
@@ -95,7 +101,7 @@ class SimplyRoute {
95
101
  this.match(getPath(document.location.pathname, this.root))
96
102
  }
97
103
  })
98
- globalThis.document.addEventListener('click', (evt) => {
104
+ this.app.container.addEventListener('click', (evt) => {
99
105
  if (evt.ctrlKey) {
100
106
  return;
101
107
  }
@@ -119,10 +125,12 @@ class SimplyRoute {
119
125
  if ( this.has(path) ) {
120
126
  let params = this.runListeners('goto', { path: path});
121
127
  if (params.path) {
122
- this.goto(params.path);
128
+ if (this.goto(params.path)) {
129
+ // now cancel the browser navigation, since a route handler was found
130
+ evt.preventDefault();
131
+ return false;
132
+ }
123
133
  }
124
- evt.preventDefault();
125
- return false;
126
134
  }
127
135
  }
128
136
  })
@@ -197,11 +205,14 @@ function getURL(path, root) {
197
205
  return root + path;
198
206
  }
199
207
 
200
- function getRegexpFromRoute(route) {
201
- return new RegExp('^'+route.replace(/:\w+/g, '([^/]+)').replace(/:\*/, '(.*)'));
208
+ function getRegexpFromRoute(route, exact=false) {
209
+ if (exact) {
210
+ return new RegExp('^'+route.replace(/:\w+/g, '([^/]+)').replace(/:\*/, '(.*)')+'(\\?|$)')
211
+ }
212
+ return new RegExp('^'+route.replace(/:\w+/g, '([^/]+)').replace(/:\*/, '(.*)'))
202
213
  }
203
214
 
204
- function parseRoutes(routes, routeInfo) {
215
+ function parseRoutes(routes, routeInfo, exact=false) {
205
216
  const paths = Object.keys(routes)
206
217
  const matchParams = /:(\w+|\*)/g
207
218
  for (let path of paths) {
@@ -214,7 +225,7 @@ function parseRoutes(routes, routeInfo) {
214
225
  }
215
226
  } while(matches)
216
227
  routeInfo.push({
217
- match: getRegexpFromRoute(path),
228
+ match: getRegexpFromRoute(path, exact),
218
229
  params: params,
219
230
  action: routes[path]
220
231
  })