pinstripe 0.33.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/README.md +1 -1
- package/lib/class.js +1 -63
- package/lib/component.js +146 -100
- package/lib/components/helpers.js +6 -5
- package/lib/components/index.js +14 -0
- package/lib/components/pinstripe_anchor.js +5 -4
- package/lib/components/pinstripe_body.js +13 -4
- package/lib/components/pinstripe_document.js +36 -2
- package/lib/components/pinstripe_form.js +36 -5
- package/lib/components/pinstripe_frame.js +38 -20
- package/lib/components/pinstripe_global_styles.js +13 -0
- package/lib/components/pinstripe_menu.js +33 -0
- package/lib/components/pinstripe_modal.js +98 -31
- package/lib/components/pinstripe_overlay.js +5 -7
- package/lib/components/pinstripe_popover.js +86 -0
- package/lib/components/pinstripe_progress_bar.js +6 -4
- package/lib/components/pinstripe_redirect.js +18 -0
- package/lib/components/pinstripe_script.js +6 -3
- package/lib/components/pinstripe_skeleton.js +4 -2
- package/lib/constants.js +1 -26
- package/lib/index.js +0 -12
- package/lib/inflector.js +1 -187
- package/lib/initialize.js +9 -3
- package/lib/lru_cache.js +1 -52
- package/lib/proof_of_work.js +1 -83
- package/lib/registry.js +1 -137
- package/lib/trapify.js +1 -31
- package/lib/virtual_node.js +1 -171
- package/package.json +9 -41
- package/babel.config.cjs +0 -18
- package/cli.js +0 -36
- package/jest.config.cjs +0 -6
- package/lib/app.js +0 -37
- package/lib/apps/_file_importer.js +0 -1
- package/lib/apps/docs.js +0 -6
- package/lib/apps/main.js +0 -6
- package/lib/background_job.js +0 -42
- package/lib/background_jobs/_file_importer.js +0 -1
- package/lib/background_jobs/purge_used_hashes.js +0 -12
- package/lib/client.js +0 -20
- package/lib/command.js +0 -68
- package/lib/command.test.js +0 -32
- package/lib/commands/_file_importer.js +0 -1
- package/lib/commands/drop_database.js +0 -6
- package/lib/commands/generate_app.js +0 -43
- package/lib/commands/generate_background_job.js +0 -47
- package/lib/commands/generate_command.js +0 -39
- package/lib/commands/generate_component.js +0 -50
- package/lib/commands/generate_migration.js +0 -55
- package/lib/commands/generate_model.js +0 -40
- package/lib/commands/generate_project.js +0 -147
- package/lib/commands/generate_service.js +0 -34
- package/lib/commands/generate_static_site.js +0 -92
- package/lib/commands/generate_view.js +0 -80
- package/lib/commands/init_database.js +0 -9
- package/lib/commands/list_apps.js +0 -15
- package/lib/commands/list_background_jobs.js +0 -15
- package/lib/commands/list_commands.js +0 -21
- package/lib/commands/list_components.js +0 -16
- package/lib/commands/list_migrations.js +0 -15
- package/lib/commands/list_models.js +0 -15
- package/lib/commands/list_services.js +0 -15
- package/lib/commands/list_views.js +0 -19
- package/lib/commands/migrate_database.js +0 -6
- package/lib/commands/reset_database.js +0 -9
- package/lib/commands/run_background_job.js +0 -11
- package/lib/commands/seed_database.js +0 -6
- package/lib/commands/show_config.js +0 -6
- package/lib/commands/start_repl.js +0 -6
- package/lib/commands/start_server.js +0 -28
- package/lib/components/_file_importer.js +0 -1
- package/lib/context.js +0 -40
- package/lib/database/client.js +0 -322
- package/lib/database/column_reference.js +0 -13
- package/lib/database/constants.js +0 -99
- package/lib/database/index.js +0 -7
- package/lib/database/migration.js +0 -32
- package/lib/database/migrator.js +0 -28
- package/lib/database/row.js +0 -387
- package/lib/database/singleton.js +0 -12
- package/lib/database/table.js +0 -518
- package/lib/database/table_reference.js +0 -33
- package/lib/database/union.js +0 -130
- package/lib/database.js +0 -147
- package/lib/defer.js +0 -35
- package/lib/defer.test.js +0 -48
- package/lib/escape_html.js +0 -2
- package/lib/extensions/_file_importer.js +0 -1
- package/lib/extensions/multi-tenant/database/row.js +0 -48
- package/lib/extensions/multi-tenant/database/table.js +0 -30
- package/lib/extensions/multi-tenant/database.js +0 -18
- package/lib/extensions/multi-tenant/index.js +0 -4
- package/lib/extensions/multi-tenant/migrations/1627976174_create_tenant_table_and_add_tenant_id_to_existing_tables.js +0 -20
- package/lib/extensions/multi-tenant/migrations/_file_importer.js +0 -2
- package/lib/extensions/multi-tenant/models/_file_importer.js +0 -1
- package/lib/extensions/multi-tenant/models/tenant.js +0 -14
- package/lib/extensions/multi-tenant/services/_file_importer.js +0 -2
- package/lib/extensions/multi-tenant/services/database.js +0 -35
- package/lib/extensions/multi-tenant/services/run_background_job.js +0 -27
- package/lib/html.js +0 -72
- package/lib/import_all.js +0 -94
- package/lib/lru_cache.test.js +0 -45
- package/lib/markdown.js +0 -66
- package/lib/migrations/1708772281_create_used_hash.js +0 -9
- package/lib/migrations/_file_importer.js +0 -2
- package/lib/model.js +0 -110
- package/lib/models/_file_importer.js +0 -2
- package/lib/models/used_hash.js +0 -7
- package/lib/project.js +0 -70
- package/lib/service_consumer.js +0 -16
- package/lib/service_factory.js +0 -22
- package/lib/services/_file_importer.js +0 -1
- package/lib/services/app.js +0 -11
- package/lib/services/bot.js +0 -70
- package/lib/services/cli_utils.js +0 -25
- package/lib/services/client_builder.js +0 -70
- package/lib/services/config.js +0 -66
- package/lib/services/cookies.js +0 -19
- package/lib/services/create_model.js +0 -8
- package/lib/services/css_classes_for.js +0 -13
- package/lib/services/database.js +0 -14
- package/lib/services/defer.js +0 -8
- package/lib/services/docs.js +0 -93
- package/lib/services/fetch.js +0 -86
- package/lib/services/format_date.js +0 -8
- package/lib/services/fs_builder.js +0 -132
- package/lib/services/inflector.js +0 -8
- package/lib/services/initial_params.js +0 -13
- package/lib/services/only_once.js +0 -24
- package/lib/services/params.js +0 -13
- package/lib/services/parse_html.js +0 -8
- package/lib/services/project.js +0 -8
- package/lib/services/render_form.js +0 -120
- package/lib/services/render_html.js +0 -8
- package/lib/services/render_markdown.js +0 -9
- package/lib/services/render_table.js +0 -48
- package/lib/services/render_view.js +0 -6
- package/lib/services/repl.js +0 -54
- package/lib/services/run_background_job.js +0 -8
- package/lib/services/run_command.js +0 -8
- package/lib/services/run_in_new_workspace.js +0 -11
- package/lib/services/send_mail.js +0 -47
- package/lib/services/server.js +0 -105
- package/lib/services/trapify.js +0 -8
- package/lib/services/view.js +0 -6
- package/lib/singleton.js +0 -13
- package/lib/string_reader.js +0 -22
- package/lib/unescape_html.js +0 -2
- package/lib/unescape_html.test.js +0 -9
- package/lib/util.js +0 -12
- package/lib/validation_error.js +0 -7
- package/lib/view.js +0 -120
- package/lib/view_file_importers/js.js +0 -38
- package/lib/view_file_importers/md.js +0 -50
- package/lib/views/_file_importer.js +0 -1
- package/lib/views/docs/_404.js +0 -16
- package/lib/views/docs/_footer.js +0 -67
- package/lib/views/docs/_header.js +0 -17
- package/lib/views/docs/_hero.js +0 -59
- package/lib/views/docs/_layout.js +0 -118
- package/lib/views/docs/_navbar.js +0 -99
- package/lib/views/docs/_sidebar.js +0 -31
- package/lib/views/docs/default.js +0 -6
- package/lib/views/docs/docs/default.js +0 -24
- package/lib/views/docs/docs/guides/introduction.md +0 -18
- package/lib/views/docs/images/logo.svg +0 -7
- package/lib/views/docs/index.js +0 -16
- package/lib/views/shared/_button.js +0 -100
- package/lib/views/shared/_content.js +0 -81
- package/lib/views/shared/_danger_area.js +0 -78
- package/lib/views/shared/_editable_area.js +0 -37
- package/lib/views/shared/_form.js +0 -273
- package/lib/views/shared/_navbar.js +0 -110
- package/lib/views/shared/_pagination.js +0 -47
- package/lib/views/shared/_panel.js +0 -69
- package/lib/views/shared/_section.js +0 -45
- package/lib/views/shared/_shell/index.js +0 -26
- package/lib/views/shared/_shell/javascripts/all.js.js +0 -7
- package/lib/views/shared/_shell/javascripts/all.js.map.js +0 -7
- package/lib/views/shared/_shell/stylesheets/all.css +0 -4
- package/lib/views/shared/_shell/stylesheets/global.css +0 -126
- package/lib/views/shared/_shell/stylesheets/reset.css +0 -74
- package/lib/views/shared/_shell/stylesheets/vars.css +0 -25
- package/lib/views/shared/_shell/stylesheets/view.css.js +0 -43
- package/lib/views/shared/_table.js +0 -139
- package/lib/virtual_node.test.js +0 -28
- package/lib/workspace.js +0 -21
package/README.md
CHANGED
package/lib/class.js
CHANGED
|
@@ -1,64 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
static extend(){
|
|
5
|
-
return class extends this {};
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
static include(...includes){
|
|
9
|
-
includes.forEach(include => {
|
|
10
|
-
if(typeof include.meta == 'function') include.meta.call(this);
|
|
11
|
-
this.prototype.assignProps(include, name => name != 'meta');
|
|
12
|
-
});
|
|
13
|
-
return this;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static assignProps(...sources){
|
|
17
|
-
return assignProps(this, ...sources);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static new(...args){
|
|
21
|
-
return new this(...args);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static get parent(){
|
|
25
|
-
return this.__proto__;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
constructor(...args){
|
|
29
|
-
let out = this.initialize(...args);
|
|
30
|
-
if(typeof out?.then == 'function'){
|
|
31
|
-
return out.then(out => out || this);
|
|
32
|
-
}
|
|
33
|
-
return out || this;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
initialize(){
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
assignProps(...sources){
|
|
41
|
-
return assignProps(this, ...sources);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const assignProps = (target, ...sources) => {
|
|
46
|
-
const fn = typeof sources[sources.length - 1] == 'function' ? sources.pop() : () => true;
|
|
47
|
-
|
|
48
|
-
sources.forEach(source => {
|
|
49
|
-
Object.getOwnPropertyNames(source).forEach(name => {
|
|
50
|
-
if(!fn(name)){
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const descriptor = { ...Object.getOwnPropertyDescriptor(source, name) };
|
|
54
|
-
const { get: targetGet, set: targetSet } = (Object.getOwnPropertyDescriptor(target, name) || {});
|
|
55
|
-
const { get = targetGet, set = targetSet } = descriptor;
|
|
56
|
-
|
|
57
|
-
if(get) descriptor.get = get;
|
|
58
|
-
if(set) descriptor.set = set;
|
|
59
|
-
|
|
60
|
-
Object.defineProperty(target, name, descriptor);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
return target;
|
|
64
|
-
};
|
|
2
|
+
export { Class } from '@sintra/utils';
|
package/lib/component.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
import { fileURLToPath } from 'url'; // pinstripe-if-client: const fileURLToPath = undefined;
|
|
3
|
-
|
|
4
2
|
import { Class } from './class.js';
|
|
5
3
|
import { TEXT_ONLY_TAGS } from './constants.js';
|
|
6
4
|
import { Inflector } from './inflector.js';
|
|
7
5
|
import { VirtualNode } from './virtual_node.js';
|
|
8
6
|
import { Registry } from './registry.js';
|
|
9
7
|
import { ComponentEvent } from './component_event.js';
|
|
10
|
-
import { Client } from './client.js'; // pinstripe-if-client: const Client = undefined;
|
|
11
8
|
import { generateProofOfWork } from './proof_of_work.js';
|
|
12
9
|
|
|
13
10
|
export const Component = Class.extend().include({
|
|
@@ -24,7 +21,7 @@ export const Component = Class.extend().include({
|
|
|
24
21
|
node._component.attributes['data-component'] || (node._component.type == '#document' ? 'pinstripe-document' : node._component.type),
|
|
25
22
|
node
|
|
26
23
|
);
|
|
27
|
-
(node._component.attributes.class || '').trim().split(/\s+/).forEach((className) => {
|
|
24
|
+
if(!this.isFromCachedHtml) (node._component.attributes.class || '').trim().split(/\s+/).forEach((className) => {
|
|
28
25
|
const decoratorMethodName = `.${className}`;
|
|
29
26
|
if(typeof node._component[decoratorMethodName] == 'function'){
|
|
30
27
|
node._component[decoratorMethodName]();
|
|
@@ -39,38 +36,11 @@ export const Component = Class.extend().include({
|
|
|
39
36
|
return Inflector.instance.dasherize(name);
|
|
40
37
|
}
|
|
41
38
|
});
|
|
42
|
-
|
|
43
|
-
this.FileImporter.register('js', {
|
|
44
|
-
meta(){
|
|
45
|
-
const { importFile } = this.prototype;
|
|
46
|
-
|
|
47
|
-
this.include({
|
|
48
|
-
async importFile(params){
|
|
49
|
-
const { filePath, relativeFilePathWithoutExtension } = params;
|
|
50
|
-
if((await import(filePath)).default){
|
|
51
|
-
Client.instance.addModule(`
|
|
52
|
-
import { Component } from ${JSON.stringify(fileURLToPath(`${import.meta.url}/../index.js`))};
|
|
53
|
-
import include from ${JSON.stringify(filePath)};
|
|
54
|
-
Component.register(${JSON.stringify(relativeFilePathWithoutExtension)}, include);
|
|
55
|
-
`);
|
|
56
|
-
} else {
|
|
57
|
-
Client.instance.addModule(`
|
|
58
|
-
import ${JSON.stringify(filePath)};
|
|
59
|
-
`);
|
|
60
|
-
}
|
|
61
|
-
return importFile.call(this, params);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
39
|
},
|
|
67
40
|
|
|
68
41
|
initialize(node, skipInit = false){
|
|
69
42
|
this.node = node;
|
|
70
|
-
this.
|
|
71
|
-
this._registeredObservers = [];
|
|
72
|
-
this._registeredTimers = [];
|
|
73
|
-
this._registeredAbortControllers = [];
|
|
43
|
+
this._managedResources = [];
|
|
74
44
|
this._virtualNodeFilters = [];
|
|
75
45
|
|
|
76
46
|
this.addVirtualNodeFilter(function(){
|
|
@@ -84,6 +54,28 @@ export const Component = Class.extend().include({
|
|
|
84
54
|
if(autofocus){
|
|
85
55
|
this.setTimeout(() => this.node.focus());
|
|
86
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);
|
|
87
79
|
},
|
|
88
80
|
|
|
89
81
|
get type(){
|
|
@@ -290,6 +282,14 @@ export const Component = Class.extend().include({
|
|
|
290
282
|
return Component.instanceFor(this.node.shadowRoot);
|
|
291
283
|
},
|
|
292
284
|
|
|
285
|
+
get isFromPlaceholderHtml(){
|
|
286
|
+
return this.frame?.status == 'using-placeholder-html';
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
get isFromCachedHtml(){
|
|
290
|
+
return this.frame?.status == 'using-cached-html';
|
|
291
|
+
},
|
|
292
|
+
|
|
293
293
|
focus(){
|
|
294
294
|
this.node.focus();
|
|
295
295
|
return this;
|
|
@@ -306,6 +306,20 @@ export const Component = Class.extend().include({
|
|
|
306
306
|
}
|
|
307
307
|
},
|
|
308
308
|
|
|
309
|
+
manage(resource){
|
|
310
|
+
const destroy = resource.destroy;
|
|
311
|
+
const that = this;
|
|
312
|
+
Object.assign(resource, {
|
|
313
|
+
destroy(){
|
|
314
|
+
const out = destroy.call(this);
|
|
315
|
+
that._managedResources = that._managedResources.filter(item => item !== this);
|
|
316
|
+
return out;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
this._managedResources.push(resource);
|
|
320
|
+
return resource;
|
|
321
|
+
},
|
|
322
|
+
|
|
309
323
|
on(name, ...args){
|
|
310
324
|
const fn = args.pop()
|
|
311
325
|
const selector = args.pop()
|
|
@@ -323,9 +337,9 @@ export const Component = Class.extend().include({
|
|
|
323
337
|
|
|
324
338
|
this.node.addEventListener(name, wrapperFn);
|
|
325
339
|
|
|
326
|
-
this.
|
|
327
|
-
|
|
328
|
-
|
|
340
|
+
return this.manage({
|
|
341
|
+
destroy: () => this.node.removeEventListener(name, wrapperFn)
|
|
342
|
+
});
|
|
329
343
|
},
|
|
330
344
|
|
|
331
345
|
trigger(name, options = {}){
|
|
@@ -345,16 +359,22 @@ export const Component = Class.extend().include({
|
|
|
345
359
|
return this;
|
|
346
360
|
},
|
|
347
361
|
|
|
348
|
-
setTimeout(...args){
|
|
349
|
-
const
|
|
350
|
-
|
|
362
|
+
setTimeout(fn, ...args){
|
|
363
|
+
const timeout = setTimeout(() => {
|
|
364
|
+
fn();
|
|
365
|
+
out.destroy();
|
|
366
|
+
}, ...args);
|
|
367
|
+
const out = this.manage({
|
|
368
|
+
destroy: () => clearTimeout(timeout)
|
|
369
|
+
});
|
|
351
370
|
return out;
|
|
352
371
|
},
|
|
353
372
|
|
|
354
373
|
setInterval(...args){
|
|
355
|
-
const
|
|
356
|
-
this.
|
|
357
|
-
|
|
374
|
+
const interval = setInterval(...args);
|
|
375
|
+
return this.manage({
|
|
376
|
+
destroy: () => clearInterval(interval)
|
|
377
|
+
});
|
|
358
378
|
},
|
|
359
379
|
|
|
360
380
|
remove(){
|
|
@@ -442,53 +462,57 @@ export const Component = Class.extend().include({
|
|
|
442
462
|
subtree: true
|
|
443
463
|
});
|
|
444
464
|
|
|
445
|
-
this.
|
|
446
|
-
|
|
447
|
-
|
|
465
|
+
return this.manage({
|
|
466
|
+
destroy: () => observer.disconnect()
|
|
467
|
+
});
|
|
448
468
|
},
|
|
449
469
|
|
|
450
|
-
|
|
451
|
-
const { minimumDelay = 0, requiresProofOfWork = false, ...otherOptions } = options;
|
|
452
|
-
const { progressBar } = this.document;
|
|
453
|
-
const frame = this.frame || this;
|
|
454
|
-
const normalizedUrl = new URL(url, frame.url);
|
|
470
|
+
fetch(url, options = {}){
|
|
455
471
|
const abortController = new AbortController();
|
|
456
|
-
this._registeredAbortControllers.push(abortController);
|
|
457
|
-
progressBar.start();
|
|
458
472
|
let minimumDelayTimeout;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
+
let rejectMinimumDelay;
|
|
474
|
+
let isSuccess = false;
|
|
475
|
+
|
|
476
|
+
const promise = (async () => {
|
|
477
|
+
const { minimumDelay = 0, requiresProofOfWork = false, ...otherOptions } = options;
|
|
478
|
+
const frame = this.frame || this;
|
|
479
|
+
const normalizedUrl = new URL(url, frame.url);
|
|
480
|
+
|
|
481
|
+
try {
|
|
482
|
+
if(requiresProofOfWork){
|
|
483
|
+
if(!(otherOptions.body instanceof FormData)) throw new Error(`Proof of work requires form data to be present`);
|
|
484
|
+
const values = {};
|
|
485
|
+
otherOptions.body.forEach((value, key) => values[key] = value);
|
|
486
|
+
otherOptions.body.append('_proofOfWork', await generateProofOfWork(values, {
|
|
487
|
+
abortSignal: abortController.signal,
|
|
488
|
+
onProgress: progress => this.trigger('proofOfWorkProgress', { data: progress, bubbles: false })
|
|
489
|
+
}))
|
|
490
|
+
}
|
|
491
|
+
const promises = [
|
|
492
|
+
fetch(normalizedUrl, { signal: abortController.signal, ...otherOptions }),
|
|
493
|
+
new Promise((resolve, reject) => {
|
|
494
|
+
minimumDelayTimeout = setTimeout(resolve, minimumDelay);
|
|
495
|
+
rejectMinimumDelay = reject;
|
|
496
|
+
})
|
|
497
|
+
];
|
|
498
|
+
const [ out ] = await Promise.all(promises);
|
|
499
|
+
isSuccess = true;
|
|
500
|
+
promise.destroy();
|
|
501
|
+
return out;
|
|
502
|
+
} catch(e){
|
|
503
|
+
promise.destroy();
|
|
504
|
+
throw e;
|
|
473
505
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
},
|
|
486
|
-
|
|
487
|
-
abort(){
|
|
488
|
-
while(this._registeredAbortControllers.length){
|
|
489
|
-
this._registeredAbortControllers.pop().abort();
|
|
490
|
-
}
|
|
491
|
-
return this;
|
|
506
|
+
})();
|
|
507
|
+
|
|
508
|
+
return this.manage(Object.assign(promise, {
|
|
509
|
+
destroy: () => {
|
|
510
|
+
if(isSuccess) return;
|
|
511
|
+
if(!abortController.signal.aborted) abortController.abort(`Request aborted`);
|
|
512
|
+
clearTimeout(minimumDelayTimeout);
|
|
513
|
+
if(rejectMinimumDelay) rejectMinimumDelay();
|
|
514
|
+
}
|
|
515
|
+
}));
|
|
492
516
|
},
|
|
493
517
|
|
|
494
518
|
find(...args){
|
|
@@ -526,29 +550,15 @@ function clean(){
|
|
|
526
550
|
|
|
527
551
|
[...this.node.childNodes].forEach(node => node._component && clean.call(node._component));
|
|
528
552
|
|
|
529
|
-
while(this.
|
|
530
|
-
this.
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
while(this._registeredObservers.length){
|
|
534
|
-
this._registeredObservers.pop().disconnect();
|
|
553
|
+
while(this._managedResources.length){
|
|
554
|
+
this._managedResources.pop().destroy();
|
|
535
555
|
}
|
|
536
556
|
|
|
537
|
-
clearTimers.call(this);
|
|
538
|
-
|
|
539
|
-
this.abort();
|
|
540
|
-
|
|
541
557
|
if(this._overlayChild) this._overlayChild.remove();
|
|
542
558
|
|
|
543
559
|
delete this.node._component;
|
|
544
560
|
}
|
|
545
561
|
|
|
546
|
-
function clearTimers(){
|
|
547
|
-
while(this._registeredTimers.length){
|
|
548
|
-
clearTimeout(this._registeredTimers.pop());
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
562
|
function initChildren(){
|
|
553
563
|
if(this.node.shadowRoot){
|
|
554
564
|
this.shadow.children.forEach(child => initChildren.call(child));
|
|
@@ -577,7 +587,7 @@ function createVirtualNode(html){
|
|
|
577
587
|
function patch(attributes, virtualChildren){
|
|
578
588
|
const isFrame = this.type == 'pinstripe-frame' || this.attributes['data-component'] == 'pinstripe-frame';
|
|
579
589
|
const isEmptyFrame = isFrame && virtualChildren.length == 0;
|
|
580
|
-
if(isEmptyFrame && attributes['data-load-on-init'] === undefined){
|
|
590
|
+
if(isEmptyFrame && attributes['load-on-init'] === undefined && attributes['data-load-on-init'] === undefined){
|
|
581
591
|
attributes['data-load-on-init'] = 'true';
|
|
582
592
|
}
|
|
583
593
|
patchAttributes.call(this, attributes);
|
|
@@ -614,6 +624,8 @@ function patchAttributes(attributes){
|
|
|
614
624
|
}
|
|
615
625
|
|
|
616
626
|
function patchChildren(virtualChildren){
|
|
627
|
+
if(this.type == 'head') return patchHeadChildren.call(this, virtualChildren);
|
|
628
|
+
|
|
617
629
|
const children = [...this.node.childNodes].map(
|
|
618
630
|
node => new Component(node, true)
|
|
619
631
|
);
|
|
@@ -646,6 +658,40 @@ function patchChildren(virtualChildren){
|
|
|
646
658
|
}
|
|
647
659
|
}
|
|
648
660
|
|
|
661
|
+
function patchHeadChildren(virtualChildren){
|
|
662
|
+
const children = [...this.node.childNodes].map(
|
|
663
|
+
node => new Component(node, true)
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
const stylesheets = {};
|
|
667
|
+
for(let i = 0; i < virtualChildren.length; i++){
|
|
668
|
+
const virtualChild = virtualChildren[i];
|
|
669
|
+
if(virtualChild.type != 'link') continue;
|
|
670
|
+
if(virtualChild.attributes.rel != 'stylesheet') continue;
|
|
671
|
+
const href = virtualChild.attributes.href;
|
|
672
|
+
stylesheets[href] = virtualChild;
|
|
673
|
+
}
|
|
674
|
+
while(children.length > 0){
|
|
675
|
+
const child = children.shift();
|
|
676
|
+
if(child.type == 'link' && child.attributes.rel == 'stylesheet'){
|
|
677
|
+
const { href } = child.attributes;
|
|
678
|
+
const stylesheet = stylesheets[href];
|
|
679
|
+
if(stylesheet){
|
|
680
|
+
patch.call(child, stylesheet.attributes, stylesheet.children);
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
remove.call(child);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
for(let i = 0; i < virtualChildren.length; i++){
|
|
688
|
+
const virtualChild = virtualChildren[i];
|
|
689
|
+
if(virtualChild.type == 'script') continue;
|
|
690
|
+
if(virtualChild.type == 'link' && virtualChild.attributes.rel == 'stylesheet' && stylesheets[virtualChild.attributes.href]) continue;
|
|
691
|
+
insert.call(this, virtualChild, null, false);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
649
695
|
function insert(virtualNode, referenceChild, returnComponent = true){
|
|
650
696
|
const { type, attributes, children } = virtualNode;
|
|
651
697
|
|
|
@@ -3,7 +3,7 @@ import { LruCache } from '../lru_cache.js';
|
|
|
3
3
|
|
|
4
4
|
export const loadCache = LruCache.new();
|
|
5
5
|
|
|
6
|
-
export function loadFrame(confirm, target, method, url, placeholderUrl, requiresProofOfWork = false){
|
|
6
|
+
export function loadFrame({ confirm, target, method, url, placeholderUrl, requiresProofOfWork = false, values = this.values }){
|
|
7
7
|
if(confirm && !window.confirm(confirm)){
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
@@ -11,15 +11,17 @@ export function loadFrame(confirm, target, method, url, placeholderUrl, requires
|
|
|
11
11
|
let frame;
|
|
12
12
|
|
|
13
13
|
if(target == '_overlay'){
|
|
14
|
-
this.document.body.clip();
|
|
15
14
|
frame = this.document.descendants.find(node => node.is('body')).append(`<pinstripe-overlay load-on-init="false"></pinstripe-overlay>`).pop();
|
|
16
15
|
frame._parent = this;
|
|
17
16
|
this._overlayChild = frame;
|
|
18
|
-
} else {
|
|
17
|
+
} else if(target) {
|
|
19
18
|
frame = getFrame.call(this, target);
|
|
20
|
-
|
|
19
|
+
} else if(this.isFrame) {
|
|
20
|
+
frame = this;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
if(!frame) return;
|
|
24
|
+
|
|
23
25
|
url = normalizeUrl(url || frame.url, this.frame.url);
|
|
24
26
|
if(url.protocol != 'data:' && (url.host != frame.url.host || url.port != frame.url.port)){
|
|
25
27
|
return;
|
|
@@ -29,7 +31,6 @@ export function loadFrame(confirm, target, method, url, placeholderUrl, requires
|
|
|
29
31
|
|
|
30
32
|
if(method.match(/POST|PUT|PATCH/i)){
|
|
31
33
|
const formData = new FormData();
|
|
32
|
-
const values = this.values;
|
|
33
34
|
Object.keys(values).forEach((name) => formData.append(name, values[name]));
|
|
34
35
|
frame.load(url, { method, body: formData, placeholderUrl, requiresProofOfWork });
|
|
35
36
|
} else {
|
package/lib/components/index.js
CHANGED
|
@@ -1 +1,15 @@
|
|
|
1
1
|
|
|
2
|
+
import './pinstripe_anchor.js';
|
|
3
|
+
import './pinstripe_body.js';
|
|
4
|
+
import './pinstripe_document.js';
|
|
5
|
+
import './pinstripe_form.js';
|
|
6
|
+
import './pinstripe_frame.js';
|
|
7
|
+
import './pinstripe_global_styles.js';
|
|
8
|
+
import './pinstripe_menu.js';
|
|
9
|
+
import './pinstripe_modal.js';
|
|
10
|
+
import './pinstripe_overlay.js';
|
|
11
|
+
import './pinstripe_popover.js';
|
|
12
|
+
import './pinstripe_progress_bar.js';
|
|
13
|
+
import './pinstripe_redirect.js';
|
|
14
|
+
import './pinstripe_script.js';
|
|
15
|
+
import './pinstripe_skeleton.js';
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
|
|
2
|
+
import { Component } from "../component.js";
|
|
2
3
|
import { loadFrame, getFrame, normalizeUrl } from "./helpers.js";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
Component.register('pinstripe-anchor', {
|
|
5
6
|
initialize(...args){
|
|
6
7
|
this.constructor.parent.prototype.initialize.call(this, ...args);
|
|
7
8
|
this.on('click', (event) => {
|
|
8
9
|
const { confirm, target = '_self', method = 'GET', href, placeholder } = this.params;
|
|
10
|
+
if(target == '_blank') return;
|
|
9
11
|
if(normalizeUrl(href, window.location.href).host != window.location.host) return;
|
|
10
12
|
event.preventDefault();
|
|
11
|
-
|
|
12
|
-
loadFrame.call(this, confirm, target, method, href, placeholder);
|
|
13
|
+
loadFrame.call(this, { confirm, target, method, url: href, placeholderUrl: placeholder });
|
|
13
14
|
});
|
|
14
15
|
|
|
15
16
|
const { target = '_self', method = 'GET', href, placeholder, preload } = this.params;
|
|
@@ -21,4 +22,4 @@ export default {
|
|
|
21
22
|
|
|
22
23
|
if(this.is('input, textarea')) this.on('keyup', (event) => this.trigger('click'));
|
|
23
24
|
}
|
|
24
|
-
};
|
|
25
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
import { Component } from "../component.js";
|
|
3
|
+
|
|
4
|
+
Component.register('pinstripe-body', {
|
|
3
5
|
initialize(...args){
|
|
4
6
|
this.constructor.parent.prototype.initialize.call(this, ...args);
|
|
5
7
|
|
|
@@ -8,6 +10,8 @@ export default {
|
|
|
8
10
|
<slot>
|
|
9
11
|
<div class="styles"></div>
|
|
10
12
|
`);
|
|
13
|
+
|
|
14
|
+
this.clipCounter = 0;
|
|
11
15
|
},
|
|
12
16
|
|
|
13
17
|
get progressBar(){
|
|
@@ -18,7 +22,8 @@ export default {
|
|
|
18
22
|
},
|
|
19
23
|
|
|
20
24
|
clip(){
|
|
21
|
-
this.
|
|
25
|
+
this.clipCounter++;
|
|
26
|
+
if(this.clipCounter == 1) this.shadow.find('.styles').patch(`
|
|
22
27
|
<style>
|
|
23
28
|
:host {
|
|
24
29
|
overflow: hidden !important;
|
|
@@ -28,6 +33,10 @@ export default {
|
|
|
28
33
|
},
|
|
29
34
|
|
|
30
35
|
unclip(){
|
|
31
|
-
this.
|
|
36
|
+
this.clipCounter--;
|
|
37
|
+
if(this.clipCounter <= 0){
|
|
38
|
+
this.clipCounter = 0;
|
|
39
|
+
this.shadow.find('.styles').patch('');
|
|
40
|
+
}
|
|
32
41
|
}
|
|
33
|
-
};
|
|
42
|
+
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
|
|
2
|
+
import { Component } from "../component.js";
|
|
2
3
|
import { loadCache, normalizeUrl } from "./helpers.js";
|
|
3
4
|
|
|
4
5
|
const preloading = {};
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Component.register('pinstripe-document', {
|
|
7
8
|
meta(){
|
|
8
9
|
this.include('pinstripe-frame');
|
|
9
10
|
|
|
@@ -51,6 +52,21 @@ export default {
|
|
|
51
52
|
return this.head.find('meta[name="pinstripe-load-cache-namespace"]')?.params.content ?? 'default';
|
|
52
53
|
},
|
|
53
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
|
+
|
|
54
70
|
async load(url = this.url.toString(), options = {}){
|
|
55
71
|
const { replace, method = 'GET' } = options;
|
|
56
72
|
const previousUrl = this.url.toString();
|
|
@@ -77,4 +93,22 @@ export default {
|
|
|
77
93
|
loadCache.put(`${this.document.loadCacheNamespace}:${url}`, html);
|
|
78
94
|
delete preloading[url.toString()];
|
|
79
95
|
}
|
|
80
|
-
};
|
|
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
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
|
|
2
|
+
import { Component } from "../component.js";
|
|
2
3
|
import { loadFrame, getFrame, normalizeUrl } from "./helpers.js";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
Component.register('pinstripe-form', {
|
|
5
6
|
initialize(...args){
|
|
6
7
|
this.constructor.parent.prototype.initialize.call(this, ...args);
|
|
7
8
|
|
|
8
9
|
const { confirm, target = '_self', method = 'GET', action, placeholder, requiresProofOfWork, disabled } = this.params;
|
|
9
|
-
|
|
10
|
+
const frame = target == '_overlay' ? this.frame : getFrame.call(this, target);
|
|
11
|
+
|
|
10
12
|
this.on('submit', (event) => {
|
|
11
13
|
event.preventDefault();
|
|
12
14
|
event.stopPropagation();
|
|
@@ -16,14 +18,31 @@ export default {
|
|
|
16
18
|
...this.attributes,
|
|
17
19
|
[this.params.component ? 'data-loading' : 'loading']: 'true'
|
|
18
20
|
});
|
|
21
|
+
|
|
22
|
+
delete frame._previousHash;
|
|
23
|
+
this._watchInterval?.destroy();
|
|
19
24
|
|
|
20
|
-
loadFrame.call(this, confirm, target, method, action, placeholder, requiresProofOfWork == 'true');
|
|
25
|
+
loadFrame.call(this, { confirm, target, method, url: action, placeholderUrl: placeholder, requiresProofOfWork: requiresProofOfWork == 'true' });
|
|
21
26
|
});
|
|
22
27
|
|
|
23
28
|
this._initialHash = JSON.stringify(this.values);
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
if(this.isFromPlaceholderHtml) return;
|
|
31
|
+
|
|
26
32
|
if(placeholder != undefined) this.document.preload(normalizeUrl(placeholder, frame.url));
|
|
33
|
+
|
|
34
|
+
const hasValuesToWatch = Object.keys(valuesToWatch.call(this)).length > 0;
|
|
35
|
+
if(!hasValuesToWatch) return;
|
|
36
|
+
|
|
37
|
+
frame._previousHash ||= JSON.stringify(valuesToWatch.call(this));
|
|
38
|
+
|
|
39
|
+
this._watchInterval = this.setInterval(() => {
|
|
40
|
+
const currentHash = JSON.stringify(valuesToWatch.call(this));
|
|
41
|
+
if(frame._previousHash == currentHash) return;
|
|
42
|
+
console.log(`${frame._previousHash} != ${currentHash}`)
|
|
43
|
+
frame._previousHash = currentHash;
|
|
44
|
+
loadFrame.call(this, { target, method: 'PATCH', url: action });
|
|
45
|
+
}, 100);
|
|
27
46
|
},
|
|
28
47
|
|
|
29
48
|
isForm: true,
|
|
@@ -31,4 +50,16 @@ export default {
|
|
|
31
50
|
get hasUnsavedChanges(){
|
|
32
51
|
return this.params.hasUnsavedChanges == 'true' || JSON.stringify(this.values) != this._initialHash;
|
|
33
52
|
}
|
|
34
|
-
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
function valuesToWatch(){
|
|
56
|
+
const out = {}
|
|
57
|
+
this.inputs.forEach(input => {
|
|
58
|
+
if(input.params.watch != 'true') return;
|
|
59
|
+
const value = input.value;
|
|
60
|
+
if(value !== undefined){
|
|
61
|
+
out[input.name] = value
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
return out;
|
|
65
|
+
}
|