pinstripe 0.34.0 → 0.35.0
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/lib/component.js +24 -2
- package/lib/components/index.js +2 -0
- package/lib/components/pinstripe_document.js +33 -11
- package/lib/components/pinstripe_frame.js +8 -1
- package/lib/components/pinstripe_global_styles.js +13 -0
- package/lib/components/pinstripe_modal.js +4 -1
- package/lib/components/pinstripe_redirect.js +18 -0
- package/lib/initialize.js +8 -0
- package/package.json +2 -2
package/lib/component.js
CHANGED
|
@@ -54,6 +54,28 @@ export const Component = Class.extend().include({
|
|
|
54
54
|
if(autofocus){
|
|
55
55
|
this.setTimeout(() => this.node.focus());
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
const { name } = this.constructor;
|
|
59
|
+
|
|
60
|
+
if(this.constructor.mixins[name]) return;
|
|
61
|
+
|
|
62
|
+
if(name.match(/^([a-z0-9]+|document-fragment)$/)) return;
|
|
63
|
+
|
|
64
|
+
const { componentBase } = this.document;
|
|
65
|
+
if(!componentBase) return;
|
|
66
|
+
|
|
67
|
+
this.shadow.patch(`
|
|
68
|
+
<pinstripe-global-styles></pinstripe-global-styles>
|
|
69
|
+
<pinstripe-frame use-cache="true" load-on-init="false"></pinstripe-frame>
|
|
70
|
+
`);
|
|
71
|
+
const frame = this.shadow.find('pinstripe-frame');
|
|
72
|
+
|
|
73
|
+
const url = new URL(`${componentBase}/${name}`, frame.url);
|
|
74
|
+
const { params } = this;
|
|
75
|
+
for(const [key, value] of Object.entries(params)){
|
|
76
|
+
url.searchParams.set(key, value);
|
|
77
|
+
}
|
|
78
|
+
frame.load(url);
|
|
57
79
|
},
|
|
58
80
|
|
|
59
81
|
get type(){
|
|
@@ -467,7 +489,7 @@ export const Component = Class.extend().include({
|
|
|
467
489
|
}))
|
|
468
490
|
}
|
|
469
491
|
const promises = [
|
|
470
|
-
|
|
492
|
+
fetch(normalizedUrl, { signal: abortController.signal, ...otherOptions }),
|
|
471
493
|
new Promise((resolve, reject) => {
|
|
472
494
|
minimumDelayTimeout = setTimeout(resolve, minimumDelay);
|
|
473
495
|
rejectMinimumDelay = reject;
|
|
@@ -565,7 +587,7 @@ function createVirtualNode(html){
|
|
|
565
587
|
function patch(attributes, virtualChildren){
|
|
566
588
|
const isFrame = this.type == 'pinstripe-frame' || this.attributes['data-component'] == 'pinstripe-frame';
|
|
567
589
|
const isEmptyFrame = isFrame && virtualChildren.length == 0;
|
|
568
|
-
if(isEmptyFrame && attributes['data-load-on-init'] === undefined){
|
|
590
|
+
if(isEmptyFrame && attributes['load-on-init'] === undefined && attributes['data-load-on-init'] === undefined){
|
|
569
591
|
attributes['data-load-on-init'] = 'true';
|
|
570
592
|
}
|
|
571
593
|
patchAttributes.call(this, attributes);
|
package/lib/components/index.js
CHANGED
|
@@ -4,10 +4,12 @@ import './pinstripe_body.js';
|
|
|
4
4
|
import './pinstripe_document.js';
|
|
5
5
|
import './pinstripe_form.js';
|
|
6
6
|
import './pinstripe_frame.js';
|
|
7
|
+
import './pinstripe_global_styles.js';
|
|
7
8
|
import './pinstripe_menu.js';
|
|
8
9
|
import './pinstripe_modal.js';
|
|
9
10
|
import './pinstripe_overlay.js';
|
|
10
11
|
import './pinstripe_popover.js';
|
|
11
12
|
import './pinstripe_progress_bar.js';
|
|
13
|
+
import './pinstripe_redirect.js';
|
|
12
14
|
import './pinstripe_script.js';
|
|
13
15
|
import './pinstripe_skeleton.js';
|
|
@@ -30,17 +30,6 @@ Component.register('pinstripe-document', {
|
|
|
30
30
|
|
|
31
31
|
isDocument: true,
|
|
32
32
|
|
|
33
|
-
get httpProxy(){
|
|
34
|
-
if(!this._httpProxy){
|
|
35
|
-
this._httpProxy = {
|
|
36
|
-
fetch(...args){
|
|
37
|
-
return fetch(...args);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
return this._httpProxy;
|
|
42
|
-
},
|
|
43
|
-
|
|
44
33
|
get head(){
|
|
45
34
|
if(!this._head){
|
|
46
35
|
this._head = this.find('head');
|
|
@@ -63,6 +52,21 @@ Component.register('pinstripe-document', {
|
|
|
63
52
|
return this.head.find('meta[name="pinstripe-load-cache-namespace"]')?.params.content ?? 'default';
|
|
64
53
|
},
|
|
65
54
|
|
|
55
|
+
get globalStyles(){
|
|
56
|
+
if(!this._globalStyles){
|
|
57
|
+
try {
|
|
58
|
+
this._globalStyles = mergeCssStylesheets(this.node.styleSheets ?? []);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
this._globalStyles = undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return this._globalStyles;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
get componentBase(){
|
|
67
|
+
return this.head.find('meta[name="pinstripe-component-base"]')?.params.content;
|
|
68
|
+
},
|
|
69
|
+
|
|
66
70
|
async load(url = this.url.toString(), options = {}){
|
|
67
71
|
const { replace, method = 'GET' } = options;
|
|
68
72
|
const previousUrl = this.url.toString();
|
|
@@ -90,3 +94,21 @@ Component.register('pinstripe-document', {
|
|
|
90
94
|
delete preloading[url.toString()];
|
|
91
95
|
}
|
|
92
96
|
});
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
export function mergeCssStylesheets(stylesheets, out = new CSSStyleSheet()) {
|
|
100
|
+
for(const sheet of stylesheets){
|
|
101
|
+
try {
|
|
102
|
+
for(const rule of sheet.cssRules) {
|
|
103
|
+
if(rule instanceof CSSImportRule) {
|
|
104
|
+
mergeCssStylesheets([ rule.styleSheet ], out);
|
|
105
|
+
} else {
|
|
106
|
+
out.insertRule(rule.cssText);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// Ignore errors from stylesheets that cannot be merged
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
@@ -44,9 +44,16 @@ Component.register('pinstripe-frame', {
|
|
|
44
44
|
await clearEventLoop();
|
|
45
45
|
this.status = 'loading';
|
|
46
46
|
this.url = url;
|
|
47
|
-
const { method = 'GET', placeholderUrl } = options;
|
|
47
|
+
const { method = 'GET', placeholderUrl, useCache = this.params.useCache == 'true' } = options;
|
|
48
48
|
const cachedHtml = method == 'GET' ? loadCache.get(`${this.document.loadCacheNamespace}:${url}`) : undefined;
|
|
49
49
|
if(cachedHtml) {
|
|
50
|
+
if(useCache){
|
|
51
|
+
this.status = 'complete';
|
|
52
|
+
this.patch(cachedHtml);
|
|
53
|
+
await clearEventLoop();
|
|
54
|
+
progressBar.stop();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
50
57
|
this.status = 'using-cached-html';
|
|
51
58
|
this.patch(cachedHtml);
|
|
52
59
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
import { Component } from "../component.js";
|
|
3
|
+
|
|
4
|
+
Component.register('pinstripe-global-styles', {
|
|
5
|
+
initialize(...args){
|
|
6
|
+
this.constructor.parent.prototype.initialize.call(this, ...args);
|
|
7
|
+
|
|
8
|
+
const host = this.find('parents', el => el.node.shadowRoot );
|
|
9
|
+
if(!host) return;
|
|
10
|
+
|
|
11
|
+
host.shadow.node.adoptedStyleSheets = [ this.document.globalStyles ];
|
|
12
|
+
}
|
|
13
|
+
});
|
|
@@ -138,7 +138,10 @@ Component.register('pinstripe-modal', {
|
|
|
138
138
|
</div>
|
|
139
139
|
`);
|
|
140
140
|
|
|
141
|
-
this.shadow.on('click', '.root, .container, .body, .close-button', () =>
|
|
141
|
+
this.shadow.on('click', '.root, .container, .body, .close-button', () => {
|
|
142
|
+
if(this.overlay.find('nextSiblings', 'pinstripe-overlay')) return;
|
|
143
|
+
this.trigger('close');
|
|
144
|
+
});
|
|
142
145
|
|
|
143
146
|
this.on('clean', () => this.document.body.unclip());
|
|
144
147
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import { Component } from "../component.js";
|
|
3
|
+
import { loadFrame, getFrame, normalizeUrl } from "./helpers.js";
|
|
4
|
+
|
|
5
|
+
Component.register('pinstripe-redirect', {
|
|
6
|
+
initialize(...args){
|
|
7
|
+
this.constructor.parent.prototype.initialize.call(this, ...args);
|
|
8
|
+
|
|
9
|
+
if(this.isFromCachedHtml) return;
|
|
10
|
+
|
|
11
|
+
const { delay = '0', confirm, target = '_self', method = 'GET', url, placeholder } = this.params;
|
|
12
|
+
this.setTimeout(() => {
|
|
13
|
+
if(target == '_blank') return;
|
|
14
|
+
if(normalizeUrl(url, window.location.href).host != window.location.host) return;
|
|
15
|
+
loadFrame.call(this, { confirm, target, method, url, placeholderUrl: placeholder });
|
|
16
|
+
}, parseInt(delay));
|
|
17
|
+
}
|
|
18
|
+
});
|
package/lib/initialize.js
CHANGED
|
@@ -3,9 +3,17 @@ import './components/index.js';
|
|
|
3
3
|
import { Component } from './component.js';
|
|
4
4
|
|
|
5
5
|
if(typeof window != 'undefined'){
|
|
6
|
+
const originalDisplay = document.documentElement.style.display;
|
|
7
|
+
document.documentElement.style.display = 'none';
|
|
6
8
|
window.addEventListener('DOMContentLoaded', () => {
|
|
7
9
|
const documentComponent = Component.instanceFor(document);
|
|
8
10
|
documentComponent.observe({ add: true }, component => component.descendants);
|
|
9
11
|
documentComponent.patch(document.documentElement.outerHTML);
|
|
12
|
+
|
|
13
|
+
const interval = setInterval(() => {
|
|
14
|
+
documentComponent.progressBar.startCount == 0;
|
|
15
|
+
clearInterval(interval);
|
|
16
|
+
document.documentElement.style.display = originalDisplay;
|
|
17
|
+
}, 100);
|
|
10
18
|
});
|
|
11
19
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "pinstripe",
|
|
4
4
|
"description": "A slick web framework for your browser.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.35.0",
|
|
6
6
|
"author": "Jody Salt",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"exports": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"clean": "rm -rf ./node_modules"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@sintra/utils": "^0.
|
|
15
|
+
"@sintra/utils": "^0.35.0"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"esbuild": "^0.25.1"
|