all repos — h3 @ 9edd7cb0addff929e8e8f0b9106899179470bc05

A tiny, extremely minimalist JavaScript microframework.

Updates.
h3rald h3rald@h3rald.com
Tue, 21 Apr 2020 17:24:01 +0200
commit

9edd7cb0addff929e8e8f0b9106899179470bc05

parent

e5eab54053c1beabef632902f0a587251185f76c

3 files changed, 31 insertions(+), 24 deletions(-)

jump to
M docs/H3_DeveloperGuide.htmdocs/H3_DeveloperGuide.htm

@@ -7312,6 +7312,11 @@

+<p><a href="https://www.npmjs.com/package/h3js"><img src="https://img.shields.io/npm/v/h3js" alt="NPM" /></a> +<a href="https://github.com/h3rald/h3/blob/master/LICENSE"><img src="https://img.shields.io/github/license/h3rald/h3" alt="License" /></a> +<a href="https://travis-ci.org/github/h3rald/h3"><img src="https://img.shields.io/travis/h3rald/h3" alt="Build" /></a> +<a href="https://coveralls.io/github/h3rald/h3?branch=master"><img src="https://img.shields.io/coveralls/github/h3rald/h3" alt="Coverage" /></a></p> + <a name="Overview"></a> <h2>Overview<a href="#document-top" title="Go to top"></a></h2>
M docs/example/assets/js/h3.jsdocs/example/assets/js/h3.js

@@ -525,13 +525,11 @@ }

} class Router { - constructor({ element, routes, store }) { + constructor({ element, routes, store, location }) { this.element = element; this.redraw = null; this.store = store; - if (!this.element) { - throw new Error(`[Router] No view element specified.`); - } + this.location = location || window.location; if (!routes || Object.keys(routes).length === 0) { throw new Error("[Router] No routes defined."); }

@@ -549,14 +547,14 @@ }

start() { const processPath = (data) => { - const hash = + const fragment = (data && data.newURL && data.newURL.match(/(#.+)$/) && data.newURL.match(/(#.+)$/)[1]) || - window.location.hash; - const path = hash.replace(/\?.+$/, "").slice(1); - const rawQuery = hash.match(/\?(.+)$/); + this.location.hash; + const path = fragment.replace(/\?.+$/, "").slice(1); + const rawQuery = fragment.match(/\?(.+)$/); const query = rawQuery && rawQuery[1] ? rawQuery[1] : ""; const pathParts = path.split("/").slice(1); let parts = {};

@@ -581,7 +579,7 @@ break;

} } if (!this.route) { - this.route = new Route({ query, path, def, parts }); + throw new Error(`[Router] No route matches '${fragment}'`); } // Display View while (this.element.firstChild) {

@@ -602,7 +600,7 @@ let query = Object.keys(params || {})

.map((p) => `${encodeURIComponent(p)}=${encodeURIComponent(params[p])}`) .join("&"); query = query ? `?${query}` : ""; - window.location.hash = `#${path}${query}`; + this.location.hash = `#${path}${query}`; } }

@@ -615,9 +613,12 @@ let store = null;

let router = null; h3.init = (config) => { - let { element, routes, modules, preStart, postStart } = config; + let { element, routes, modules, preStart, postStart, location } = config; if (!routes) { // Assume config is a component object, define default route + if (typeof config !== "function") { + throw new Error("[h3.init] The specified argument is not a valid configuration object or component function"); + } routes = { "/": config }; } element = element || document.body;

@@ -631,7 +632,7 @@ if (i) i(store);

}); store.dispatch("$init"); // Initialize router - router = new Router({ element, routes, store }); + router = new Router({ element, routes, store, location }); return Promise.resolve(preStart && preStart()) .then(() => router.start()) .then(() => postStart && postStart());
M docs/js/h3.jsdocs/js/h3.js

@@ -525,13 +525,11 @@ }

} class Router { - constructor({ element, routes, store }) { + constructor({ element, routes, store, location }) { this.element = element; this.redraw = null; this.store = store; - if (!this.element) { - throw new Error(`[Router] No view element specified.`); - } + this.location = location || window.location; if (!routes || Object.keys(routes).length === 0) { throw new Error("[Router] No routes defined."); }

@@ -549,14 +547,14 @@ }

start() { const processPath = (data) => { - const hash = + const fragment = (data && data.newURL && data.newURL.match(/(#.+)$/) && data.newURL.match(/(#.+)$/)[1]) || - window.location.hash; - const path = hash.replace(/\?.+$/, "").slice(1); - const rawQuery = hash.match(/\?(.+)$/); + this.location.hash; + const path = fragment.replace(/\?.+$/, "").slice(1); + const rawQuery = fragment.match(/\?(.+)$/); const query = rawQuery && rawQuery[1] ? rawQuery[1] : ""; const pathParts = path.split("/").slice(1); let parts = {};

@@ -581,7 +579,7 @@ break;

} } if (!this.route) { - this.route = new Route({ query, path, def, parts }); + throw new Error(`[Router] No route matches '${fragment}'`); } // Display View while (this.element.firstChild) {

@@ -602,7 +600,7 @@ let query = Object.keys(params || {})

.map((p) => `${encodeURIComponent(p)}=${encodeURIComponent(params[p])}`) .join("&"); query = query ? `?${query}` : ""; - window.location.hash = `#${path}${query}`; + this.location.hash = `#${path}${query}`; } }

@@ -615,9 +613,12 @@ let store = null;

let router = null; h3.init = (config) => { - let { element, routes, modules, preStart, postStart } = config; + let { element, routes, modules, preStart, postStart, location } = config; if (!routes) { // Assume config is a component object, define default route + if (typeof config !== "function") { + throw new Error("[h3.init] The specified argument is not a valid configuration object or component function"); + } routes = { "/": config }; } element = element || document.body;

@@ -631,7 +632,7 @@ if (i) i(store);

}); store.dispatch("$init"); // Initialize router - router = new Router({ element, routes, store }); + router = new Router({ element, routes, store, location }); return Promise.resolve(preStart && preStart()) .then(() => router.start()) .then(() => postStart && postStart());