@webqit/webflo 0.11.21 → 0.11.22

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.
package/README.md CHANGED
@@ -7,25 +7,31 @@
7
7
 
8
8
  <!-- /BADGES -->
9
9
 
10
- Webflo is a universal *web*, *mobile*, and *API backend* framework built to solve for the underrated `.html` + `.css` + `.js` stack! This has been written to facilitate working and thinking in vanilla HTML, CSS and JavaScript - for building more authentic, web-native applications!
10
+ Webflo is a universal *web*, *mobile*, and *API backend* framework that gets it all done in vanilla HTML, CSS, and JavaScript! It's a powerful little thing written to facilitate building more authentic, web-native applications!
11
11
 
12
- Ok, we've put all of that up for a 10min straight read!
12
+ Here, we've put all of that up for a 10min straight read!
13
+
14
+ TL;DR: here's what's ahead...
15
+
16
+ + web-native development and the vanilla advantage!
17
+ + the path of least engineering!
13
18
 
14
19
  ## The Catch...
15
20
 
16
- The overall motivation for Webflo is to facilitate *web-native* development; to be the cool framework that draws on native web platform features - including new fascinating features we're proposing as standards! So, it gets a little bit "futuristic"! You thus have to be excited about taking a plunge to happily meet Webflo!
21
+ Webflo is a framework on its own track - working and thinking in vanilla HTML, CSS and JavaScript! Instead of trying to follow certain norms, it takes a plunge to draw on native web platform features - plus some more futurisric, fascinating stuffs we're proposing as standards! This means that you also have to be excited about taking a plunge to happily meet Webflo!
17
22
 
18
23
  ## The Wins...
19
24
 
20
25
  Much of what eludes the web today...
21
26
 
22
- + An overarching HTML-first thinking!
23
- + The build-less, vanilla advantage!
24
- + (Futuristic) Native reactivity!
25
- + (Futuristic) Minimalist-JS philosophy!
26
- + Universal-everything!
27
+ + the long-missing framework design and architecture for a HTML-first thinking!
28
+ + a focused standards-based philosophy that breeds more authentic applications!
29
+
30
+ Plus native support for how you want to work...
27
31
 
28
- (Details just ahead!)
32
+ + a new approach to reactivity that's based on no syntax at all but plain old JavaScript!
33
+ + a new "imports" feature for HTML that makes HTML more reusable!
34
+ + and much more.
29
35
 
30
36
  ## Documentation
31
37
 
@@ -767,7 +773,7 @@ Here, you are able to define reusable contents in a `<template>` element...
767
773
  </body>
768
774
  ```
769
775
 
770
- The *module* element - `<template>` - is able to load its contents from a remote `.html` file that serves as a bundle:
776
+ The *module* element - `<template>` - is also able to load its contents from a remote `.html` file that serves as a bundle:
771
777
 
772
778
  ```html
773
779
  <!--
@@ -859,7 +865,7 @@ public/products
859
865
 
860
866
  #### In a Single Page Layout
861
867
 
862
- In a Single Page layout (as seen [earlier](#layout-and-templating-overview)), page-specific contents - e.g. main sections - are typically bundled together into one `bundle.html` file that can be embedded on the document root. Nested routes end up as nested `<template>` elements that form the equivalent of the application's URL structure.
868
+ In a Single Page layout (as seen [earlier](#layout-and-templating-overview)), page-specific contents - e.g. main sections - are typically bundled together into one `bundle.html` file that can be embedded on the document root. Notice how nested routes end up as nested `<template>` elements that form the equivalent of the application's URL structure.
863
869
 
864
870
  ```html
865
871
  <!--
@@ -1258,7 +1264,7 @@ Observer.observe(document.state, 'data', e => {
1258
1264
 
1259
1265
  #### The `document.state.url` Object
1260
1266
 
1261
- This is a *live* object that reperesents the properties of the application URL at any point in time. The object exposes the same URL properties as with the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) API, but as *live* properties that can be observed as navigation happens, and modified to initiate navigation - all using the [Observer API](#the-observer-api).
1267
+ This is a *live* object that reperesents the properties of the application URL at any point in time. The object exposes the same URL properties as of a standard [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) object, but, here, as *live* properties that can be observed as navigation happens, and modified to initiate navigation - all using the [Observer API](#the-observer-api).
1262
1268
 
1263
1269
  ```js
1264
1270
  console.log(document.state.url) // { hash, host, hostname, href, origin, password, pathname, port, protocol, search, searchParams, username }
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "vanila-javascript"
13
13
  ],
14
14
  "homepage": "https://webqit.io/tooling/webflo",
15
- "version": "0.11.21",
15
+ "version": "0.11.22",
16
16
  "license": "MIT",
17
17
  "repository": {
18
18
  "type": "git",
@@ -52,7 +52,6 @@ export default class Runtime {
52
52
  * @return void
53
53
  */
54
54
  constructor(cx, clientCallback) {
55
-
56
55
  // ---------------
57
56
  this.cx = cx;
58
57
  this.clients = new Map;
@@ -97,12 +96,12 @@ export default class Runtime {
97
96
  // Capture all link-clicks
98
97
  // and fire to this router.
99
98
  window.addEventListener('click', e => {
100
- var anchor = e.target.closest('a');
101
- if (!anchor || !anchor.href) return;
102
- if (!anchor.target && !anchor.download && this.isSpaRoute(anchor, e)) {
99
+ var anchorEl = e.target.closest('a');
100
+ if (!anchorEl || !anchorEl.href) return;
101
+ if (!anchorEl.target && !anchorEl.download && this.isSpaRoute(anchorEl, e)) {
103
102
  // Publish everything, including hash
104
- this.go(Url.copy(anchor), {}, { src: anchor, srcType: 'link', });
105
- if (!(_before(window.document.location.href, '#') === _before(anchor.href, '#') && anchor.href.includes('#'))) {
103
+ this.go(Url.copy(anchorEl), {}, { src: anchorEl, srcType: 'link', });
104
+ if (!this.isHashAction(anchorEl)) {
106
105
  e.preventDefault();
107
106
  }
108
107
  }
@@ -143,7 +142,7 @@ export default class Runtime {
143
142
  method: submitParams.method,
144
143
  body: formData,
145
144
  }, { ...submitParams, src: form, srcType: 'form', });
146
- if (!(_before(window.document.location.href, '#') === _before(actionEl.href, '#') && actionEl.href.includes('#'))) {
145
+ if (!this.isHashAction(actionEl)) {
147
146
  e.preventDefault();
148
147
  }
149
148
  }
@@ -188,8 +187,14 @@ export default class Runtime {
188
187
  return window.history;
189
188
  }
190
189
 
191
- // Check is-route
192
- isSpaRoute(url, e) {
190
+ // Check is-hash-action
191
+ isHashAction(urlObj) {
192
+ const isHashNav = _before(window.document.location.href, '#') === _before(urlObj.href, '#') && urlObj.href.includes('#');
193
+ return isHashNav && urlObj.hash.length > 1 && document.querySelector(urlObj.hash);
194
+ }
195
+
196
+ // Check is-spa-route
197
+ isSpaRoute(url, e = undefined) {
193
198
  url = typeof url === 'string' ? new whatwag.URL(url) : url;
194
199
  if (url.origin && url.origin !== this.location.origin) return false;
195
200
  if (e && (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)) return false;
@@ -278,13 +283,14 @@ export default class Runtime {
278
283
  // ------------
279
284
  if (response.redirected) {
280
285
  Observer.set(this.location, { href: response.url }, { detail: { redirected: true }, });
286
+ Observer.set(this.network, 'requesting', null);
281
287
  } else if (![302, 301].includes(finalResponse.status)) {
282
- Observer.set(this.location, url);
288
+ Observer.set(this.location, Url.copy(url)/* copy() is important */);
289
+ Observer.set(this.network, 'requesting', null);
283
290
  }
284
291
  // ------------
285
292
  // States
286
293
  // ------------
287
- Observer.set(this.network, 'requesting', null);
288
294
  if (['link', 'form'].includes(detail.srcType)) {
289
295
  detail.src.state && (detail.src.state.active = false);
290
296
  detail.submitter && detail.submitter.state && (detail.submitter.state.active = false);
@@ -330,10 +336,20 @@ export default class Runtime {
330
336
  if (!(response instanceof Response)) { response = new Response(response); }
331
337
  if (!response.redirected) {
332
338
  let location = response.headers.get('Location');
333
- if (location && response.status === this._xRedirectCode) {
334
- response.attrs.status = parseInt(response.headers.get('X-Redirect-Code'));
335
- Observer.set(this.network, 'redirecting', location);
336
- window.location = location;
339
+ if (location) {
340
+ let xActualRedirectCode = parseInt(response.headers.get('X-Redirect-Code'));
341
+ if (xActualRedirectCode && response.status === this._xRedirectCode) {
342
+ response.attrs.status = xActualRedirectCode;
343
+ Observer.set(this.network, 'redirecting', location);
344
+ window.location = location;
345
+ } else if ([302,301].includes(response.status)) {
346
+ if (!this.isSpaRoute(location)) {
347
+ Observer.set(this.network, 'redirecting', location);
348
+ window.location = location;
349
+ } else {
350
+ this.go(location, {}, { srcType: 'rdr' });
351
+ }
352
+ }
337
353
  }
338
354
  }
339
355
  return response;
@@ -1,10 +1,11 @@
1
+
1
2
  /**
2
3
  * @imports
3
4
  */
4
5
  import { config, runtime, Context } from '../src/index.js';
5
6
 
6
7
  let client = {
7
- handle: function(httpEvent) {
8
+ handle: function( httpEvent ) {
8
9
  return new httpEvent.Response({ abcd: '1234' }, {
9
10
  status: 302,
10
11
  headers: {
@@ -18,8 +19,8 @@ let client = {
18
19
  },
19
20
  };
20
21
 
21
- const cx = Context.create({ config: config, });
22
- const clientCallback = (_cx, hostName, defaultClientCallback) => client;
23
- const app = await runtime.server.start.call(cx, clientCallback);
22
+ const cx = Context.create( { config: config, } );
23
+ const clientCallback = ( _cx, hostName, defaultClientCallback ) => client;
24
+ const app = await runtime.server.start.call( cx, clientCallback );
24
25
 
25
- const response = await app.go('http://localhost/', { headers: { range: 'bytes=0-5, 6' } } );
26
+ const response = await app.go( 'http://localhost/', { headers: { range: 'bytes=0-5, 6' } } );