@sdcorejs/angular 21.1.3 → 21.1.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.
- package/README.md +17 -14
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +14 -14
- package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-audit-diff.mjs +332 -0
- package/fesm2022/sdcorejs-angular-components-audit-diff.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-badge.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs +121 -0
- package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-data-state.mjs +68 -0
- package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +18 -23
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-editor.mjs +6 -4
- package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +495 -838
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +24 -34
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-job-progress.mjs +97 -0
- package/fesm2022/sdcorejs-angular-components-job-progress.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +10 -20
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal.mjs +61 -4
- package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +1438 -218
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +39 -2
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +16 -22
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +48 -4
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +96 -63
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs +186 -17
- package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -22
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +4 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +29 -41
- package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +7 -7
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +20 -71
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +6 -3
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +6 -3
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +16 -13
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +42 -65
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +51 -66
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +384 -0
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +7 -5
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +290 -56
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-models.mjs +155 -2
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +44 -66
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +6 -20
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +19 -64
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +6 -5
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs +277 -0
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-time.mjs +307 -0
- package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +210 -0
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms.mjs +73 -4
- package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +355 -10
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +12 -17
- package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +861 -80
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-pipes.mjs +5 -7
- package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-api.mjs +407 -137
- package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-cache.mjs +515 -105
- package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +5 -7
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-docx.mjs +7 -10
- package/fesm2022/sdcorejs-angular-services-docx.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-loading.mjs +339 -74
- package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-notify.mjs +7 -10
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-persistence.mjs +899 -0
- package/fesm2022/sdcorejs-angular-services-persistence.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services-storage.mjs +324 -122
- package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-task.mjs +389 -0
- package/fesm2022/sdcorejs-angular-services-task.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs +255 -0
- package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services-viewport.mjs +76 -0
- package/fesm2022/sdcorejs-angular-services-viewport.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-services.mjs +4 -0
- package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
- package/package.json +49 -1
- package/types/sdcorejs-angular-components-audit-diff.d.ts +74 -0
- package/types/sdcorejs-angular-components-badge.d.ts +1 -1
- package/types/sdcorejs-angular-components-breadcrumb.d.ts +53 -0
- package/types/sdcorejs-angular-components-data-state.d.ts +44 -0
- package/types/sdcorejs-angular-components-document-builder.d.ts +5 -5
- package/types/sdcorejs-angular-components-form-generic.d.ts +67 -104
- package/types/sdcorejs-angular-components-import-excel.d.ts +4 -14
- package/types/sdcorejs-angular-components-job-progress.d.ts +38 -0
- package/types/sdcorejs-angular-components-mini-editor.d.ts +9 -9
- package/types/sdcorejs-angular-components-modal.d.ts +7 -1
- package/types/sdcorejs-angular-components-preview.d.ts +181 -28
- package/types/sdcorejs-angular-components-side-drawer.d.ts +7 -1
- package/types/sdcorejs-angular-components-tab.d.ts +9 -2
- package/types/sdcorejs-angular-components-table.d.ts +8 -7
- package/types/sdcorejs-angular-components-tree.d.ts +24 -2
- package/types/sdcorejs-angular-components-upload-file.d.ts +5 -4
- package/types/sdcorejs-angular-components.d.ts +4 -0
- package/types/sdcorejs-angular-directives.d.ts +10 -8
- package/types/sdcorejs-angular-forms-autocomplete.d.ts +3 -4
- package/types/sdcorejs-angular-forms-checkbox.d.ts +4 -8
- package/types/sdcorejs-angular-forms-date-range.d.ts +6 -7
- package/types/sdcorejs-angular-forms-date.d.ts +2 -2
- package/types/sdcorejs-angular-forms-datetime.d.ts +2 -2
- package/types/sdcorejs-angular-forms-entity-picker.d.ts +128 -0
- package/types/sdcorejs-angular-forms-input-number.d.ts +1 -1
- package/types/sdcorejs-angular-forms-input.d.ts +74 -11
- package/types/sdcorejs-angular-forms-models.d.ts +86 -3
- package/types/sdcorejs-angular-forms-radio.d.ts +12 -8
- package/types/sdcorejs-angular-forms-switch.d.ts +4 -7
- package/types/sdcorejs-angular-forms-time-range.d.ts +98 -0
- package/types/sdcorejs-angular-forms-time.d.ts +117 -0
- package/types/sdcorejs-angular-forms-tree-select.d.ts +76 -0
- package/types/sdcorejs-angular-forms.d.ts +15 -5
- package/types/sdcorejs-angular-i18n.d.ts +68 -2
- package/types/sdcorejs-angular-interceptors.d.ts +5 -6
- package/types/sdcorejs-angular-modules-layout.d.ts +288 -15
- package/types/sdcorejs-angular-pipes.d.ts +2 -2
- package/types/sdcorejs-angular-services-api.d.ts +68 -24
- package/types/sdcorejs-angular-services-cache.d.ts +52 -16
- package/types/sdcorejs-angular-services-confirm.d.ts +3 -2
- package/types/sdcorejs-angular-services-docx.d.ts +2 -3
- package/types/sdcorejs-angular-services-loading.d.ts +16 -8
- package/types/sdcorejs-angular-services-persistence.d.ts +159 -0
- package/types/sdcorejs-angular-services-storage.d.ts +26 -8
- package/types/sdcorejs-angular-services-task.d.ts +104 -0
- package/types/sdcorejs-angular-services-unsaved-changes.d.ts +83 -0
- package/types/sdcorejs-angular-services-viewport.d.ts +42 -0
- package/types/sdcorejs-angular-services.d.ts +4 -0
|
@@ -1,97 +1,362 @@
|
|
|
1
|
+
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
+
import { inject, DestroyRef, PLATFORM_ID, RendererFactory2, Injectable } from '@angular/core';
|
|
3
4
|
|
|
5
|
+
var _a;
|
|
6
|
+
const SD_LOADING_STYLE_ATTRIBUTE = 'data-sd-loading-styles';
|
|
7
|
+
const SD_LOADING_STYLES = `
|
|
8
|
+
.sd-loading {
|
|
9
|
+
position: absolute;
|
|
10
|
+
inset: 0;
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
opacity: 0.6;
|
|
14
|
+
background: #fff;
|
|
15
|
+
z-index: 99999;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.sd-loading-spinner {
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: calc(50% - 2.5rem);
|
|
21
|
+
left: calc(50% - 2.5rem);
|
|
22
|
+
width: 5rem;
|
|
23
|
+
height: 5rem;
|
|
24
|
+
border: 0.5rem solid var(--sd-primary);
|
|
25
|
+
border-top-color: var(--sd-border);
|
|
26
|
+
border-radius: 50%;
|
|
27
|
+
animation: sd-loading-spin 1s linear infinite;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@keyframes sd-loading-spin {
|
|
31
|
+
from { transform: rotate(0deg); }
|
|
32
|
+
to { transform: rotate(360deg); }
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
const CLOSED_LOADING_REF = Object.freeze({
|
|
36
|
+
closed: true,
|
|
37
|
+
close() {
|
|
38
|
+
// A closed ref deliberately has no work to release.
|
|
39
|
+
},
|
|
40
|
+
});
|
|
4
41
|
class SdLoadingService {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
document
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
42
|
+
static documentRecords = new WeakMap();
|
|
43
|
+
#document;
|
|
44
|
+
#renderer;
|
|
45
|
+
#isBrowser;
|
|
46
|
+
#destroyRef = inject(DestroyRef);
|
|
47
|
+
#handleQueue = [];
|
|
48
|
+
#styleRegistered = false;
|
|
49
|
+
#destroyed = false;
|
|
50
|
+
constructor() {
|
|
51
|
+
this.#document = inject(DOCUMENT);
|
|
52
|
+
this.#isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
53
|
+
const rendererFactory = inject(RendererFactory2);
|
|
54
|
+
this.#renderer = this.#isBrowser ? rendererFactory.createRenderer(null, null) : null;
|
|
55
|
+
this.#destroyRef.onDestroy(() => this.#destroy());
|
|
56
|
+
}
|
|
57
|
+
/** Starts loading for every current selector match and returns ownership of those exact hosts. */
|
|
58
|
+
start = (selector = 'body') => {
|
|
59
|
+
const renderer = this.#renderer;
|
|
60
|
+
if (this.#destroyed || !this.#isBrowser || !renderer)
|
|
61
|
+
return CLOSED_LOADING_REF;
|
|
62
|
+
const hosts = Array.from(this.#document.querySelectorAll(selector));
|
|
63
|
+
if (hosts.length === 0)
|
|
64
|
+
return CLOSED_LOADING_REF;
|
|
65
|
+
const documentRecord = this.#getOrCreateDocumentRecord();
|
|
66
|
+
this.#ensureStyles(documentRecord, renderer);
|
|
67
|
+
const state = { selector, contributions: [], closed: false };
|
|
68
|
+
for (const host of hosts) {
|
|
69
|
+
const contribution = {
|
|
70
|
+
host,
|
|
71
|
+
owner: state,
|
|
72
|
+
service: this,
|
|
73
|
+
released: false,
|
|
74
|
+
};
|
|
75
|
+
state.contributions.push(contribution);
|
|
76
|
+
this.#acquireHost(documentRecord, contribution, renderer);
|
|
77
|
+
}
|
|
78
|
+
this.#handleQueue.push(state);
|
|
79
|
+
return {
|
|
80
|
+
get closed() {
|
|
81
|
+
return state.closed;
|
|
82
|
+
},
|
|
83
|
+
close: () => this.#closeHandle(state, renderer),
|
|
84
|
+
};
|
|
21
85
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!
|
|
86
|
+
/** Returns the first matched globally loading host, `false` for idle matches, or `null` when unavailable. */
|
|
87
|
+
isLoading = (selector = 'body') => {
|
|
88
|
+
if (this.#destroyed || !this.#isBrowser)
|
|
25
89
|
return null;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
90
|
+
const hosts = this.#document.querySelectorAll(selector);
|
|
91
|
+
if (hosts.length === 0)
|
|
92
|
+
return null;
|
|
93
|
+
const documentRecord = _a.documentRecords.get(this.#document);
|
|
94
|
+
for (const host of Array.from(hosts)) {
|
|
95
|
+
const state = documentRecord?.hostStates.get(host);
|
|
96
|
+
if (state && state.count > 0 && state.overlay.parentNode === host)
|
|
97
|
+
return host;
|
|
29
98
|
}
|
|
30
99
|
return false;
|
|
31
100
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
101
|
+
/** Releases the oldest exact-selector start, with a current-host fallback for legacy cross-selector calls. */
|
|
102
|
+
stop = (selector = 'body') => {
|
|
103
|
+
const renderer = this.#renderer;
|
|
104
|
+
if (this.#destroyed || !this.#isBrowser || !renderer)
|
|
105
|
+
return;
|
|
106
|
+
const exactHandle = this.#handleQueue.find(state => !state.closed && state.selector === selector);
|
|
107
|
+
if (exactHandle) {
|
|
108
|
+
this.#closeHandle(exactHandle, renderer);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const documentRecord = _a.documentRecords.get(this.#document);
|
|
112
|
+
if (!documentRecord)
|
|
113
|
+
return;
|
|
114
|
+
for (const host of Array.from(this.#document.querySelectorAll(selector))) {
|
|
115
|
+
const contribution = documentRecord.hostStates
|
|
116
|
+
.get(host)
|
|
117
|
+
?.contributions.find(candidate => !candidate.released && candidate.service === this);
|
|
118
|
+
if (contribution)
|
|
119
|
+
this.#releaseContribution(documentRecord, contribution, renderer);
|
|
120
|
+
}
|
|
39
121
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
122
|
+
/** Runs a task inside a loading lifetime and always releases it without replacing the task result or error. */
|
|
123
|
+
async run(task, selector = 'body') {
|
|
124
|
+
const ref = this.start(selector);
|
|
125
|
+
try {
|
|
126
|
+
const result = typeof task === 'function' ? task() : task;
|
|
127
|
+
return await result;
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
ref.close();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
#getOrCreateDocumentRecord() {
|
|
134
|
+
let record = _a.documentRecords.get(this.#document);
|
|
135
|
+
if (!record) {
|
|
136
|
+
record = {
|
|
137
|
+
hostStates: new WeakMap(),
|
|
138
|
+
liveHosts: new Set(),
|
|
139
|
+
style: undefined,
|
|
140
|
+
};
|
|
141
|
+
_a.documentRecords.set(this.#document, record);
|
|
142
|
+
}
|
|
143
|
+
return record;
|
|
144
|
+
}
|
|
145
|
+
#acquireHost(documentRecord, contribution, renderer) {
|
|
146
|
+
const host = contribution.host;
|
|
147
|
+
const existing = documentRecord.hostStates.get(host);
|
|
148
|
+
if (existing) {
|
|
149
|
+
this.#repairOverlay(host, existing, renderer);
|
|
150
|
+
existing.count += 1;
|
|
151
|
+
existing.contributions.push(contribution);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const state = {
|
|
155
|
+
overlay: this.#createOverlay(renderer),
|
|
156
|
+
previousAriaBusy: host.getAttribute('aria-busy'),
|
|
157
|
+
contributions: [contribution],
|
|
158
|
+
count: 1,
|
|
64
159
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
160
|
+
renderer.setAttribute(host, 'aria-busy', 'true');
|
|
161
|
+
renderer.appendChild(host, state.overlay);
|
|
162
|
+
documentRecord.hostStates.set(host, state);
|
|
163
|
+
documentRecord.liveHosts.add(host);
|
|
164
|
+
}
|
|
165
|
+
#repairOverlay(host, state, renderer) {
|
|
166
|
+
const currentParent = state.overlay.parentNode;
|
|
167
|
+
if (currentParent !== host) {
|
|
168
|
+
if (currentParent)
|
|
169
|
+
renderer.removeChild(currentParent, state.overlay);
|
|
170
|
+
renderer.appendChild(host, state.overlay);
|
|
171
|
+
}
|
|
172
|
+
if (host.getAttribute('aria-busy') !== 'true')
|
|
173
|
+
renderer.setAttribute(host, 'aria-busy', 'true');
|
|
174
|
+
}
|
|
175
|
+
#releaseContribution(documentRecord, contribution, renderer) {
|
|
176
|
+
if (contribution.released)
|
|
177
|
+
return;
|
|
178
|
+
contribution.released = true;
|
|
179
|
+
const state = documentRecord.hostStates.get(contribution.host);
|
|
180
|
+
if (state) {
|
|
181
|
+
const contributionIndex = state.contributions.indexOf(contribution);
|
|
182
|
+
if (contributionIndex >= 0)
|
|
183
|
+
state.contributions.splice(contributionIndex, 1);
|
|
184
|
+
state.count -= 1;
|
|
185
|
+
if (state.count <= 0)
|
|
186
|
+
this.#removeHost(documentRecord, contribution.host, state, renderer);
|
|
187
|
+
}
|
|
188
|
+
contribution.service.#closeOwnerWhenReleased(contribution.owner);
|
|
189
|
+
}
|
|
190
|
+
#removeHost(documentRecord, host, state, renderer) {
|
|
191
|
+
const parent = state.overlay.parentNode;
|
|
192
|
+
if (parent)
|
|
193
|
+
renderer.removeChild(parent, state.overlay);
|
|
194
|
+
if (host.getAttribute('aria-busy') === 'true') {
|
|
195
|
+
if (state.previousAriaBusy === null)
|
|
196
|
+
renderer.removeAttribute(host, 'aria-busy');
|
|
197
|
+
else
|
|
198
|
+
renderer.setAttribute(host, 'aria-busy', state.previousAriaBusy);
|
|
199
|
+
}
|
|
200
|
+
documentRecord.hostStates.delete(host);
|
|
201
|
+
documentRecord.liveHosts.delete(host);
|
|
202
|
+
this.#deleteDocumentRecordWhenEmpty(documentRecord);
|
|
203
|
+
}
|
|
204
|
+
#closeHandle(state, renderer) {
|
|
205
|
+
if (state.closed)
|
|
206
|
+
return;
|
|
207
|
+
state.closed = true;
|
|
208
|
+
this.#dequeueHandle(state);
|
|
209
|
+
const documentRecord = _a.documentRecords.get(this.#document);
|
|
210
|
+
if (documentRecord) {
|
|
211
|
+
for (const contribution of [...state.contributions]) {
|
|
212
|
+
this.#releaseContribution(documentRecord, contribution, renderer);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
for (const contribution of state.contributions)
|
|
217
|
+
contribution.released = true;
|
|
218
|
+
}
|
|
219
|
+
state.contributions.length = 0;
|
|
220
|
+
}
|
|
221
|
+
#closeOwnerWhenReleased(state) {
|
|
222
|
+
if (state.closed || state.contributions.some(contribution => !contribution.released))
|
|
223
|
+
return;
|
|
224
|
+
state.closed = true;
|
|
225
|
+
this.#dequeueHandle(state);
|
|
226
|
+
state.contributions.length = 0;
|
|
227
|
+
}
|
|
228
|
+
#dequeueHandle(state) {
|
|
229
|
+
const handleIndex = this.#handleQueue.indexOf(state);
|
|
230
|
+
if (handleIndex >= 0)
|
|
231
|
+
this.#handleQueue.splice(handleIndex, 1);
|
|
232
|
+
}
|
|
233
|
+
#createOverlay(renderer) {
|
|
234
|
+
const container = renderer.createElement('div');
|
|
235
|
+
const spinner = renderer.createElement('div');
|
|
71
236
|
renderer.addClass(container, 'sd-loading');
|
|
72
|
-
renderer.setAttribute(container, '
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
237
|
+
renderer.setAttribute(container, 'role', 'status');
|
|
238
|
+
renderer.setAttribute(container, 'aria-live', 'polite');
|
|
239
|
+
renderer.setAttribute(container, 'aria-label', 'Loading');
|
|
76
240
|
renderer.addClass(spinner, 'sd-loading-spinner');
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
});
|
|
80
|
-
const styleElement = this.renderer.createElement('style');
|
|
81
|
-
this.renderer.appendChild(styleElement, this.renderer.createText(keyframes));
|
|
82
|
-
document.head.appendChild(styleElement);
|
|
83
|
-
container.appendChild(spinner);
|
|
241
|
+
renderer.setAttribute(spinner, 'aria-hidden', 'true');
|
|
242
|
+
renderer.appendChild(container, spinner);
|
|
84
243
|
return container;
|
|
85
|
-
}
|
|
86
|
-
|
|
244
|
+
}
|
|
245
|
+
#ensureStyles(documentRecord, renderer) {
|
|
246
|
+
let record = documentRecord.style;
|
|
247
|
+
if (record && !this.#isCurrentStyle(record.element)) {
|
|
248
|
+
const owners = record.owners;
|
|
249
|
+
this.#detachOwnedStyleContent(record, renderer);
|
|
250
|
+
record = this.#createStyleRecord(renderer, owners);
|
|
251
|
+
documentRecord.style = record;
|
|
252
|
+
}
|
|
253
|
+
else if (!record) {
|
|
254
|
+
record = this.#createStyleRecord(renderer, new Set());
|
|
255
|
+
documentRecord.style = record;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.#ensureRequiredStyleText(record, renderer);
|
|
259
|
+
}
|
|
260
|
+
record.owners.add(this);
|
|
261
|
+
this.#styleRegistered = true;
|
|
262
|
+
}
|
|
263
|
+
#isCurrentStyle(element) {
|
|
264
|
+
return element.isConnected && element.parentNode === this.#document.head && element.hasAttribute(SD_LOADING_STYLE_ATTRIBUTE);
|
|
265
|
+
}
|
|
266
|
+
#createStyleRecord(renderer, owners) {
|
|
267
|
+
const existing = this.#document.head.querySelector(`style[${SD_LOADING_STYLE_ATTRIBUTE}]`);
|
|
268
|
+
if (existing) {
|
|
269
|
+
const record = {
|
|
270
|
+
element: existing,
|
|
271
|
+
libraryOwned: false,
|
|
272
|
+
owners,
|
|
273
|
+
ownedText: null,
|
|
274
|
+
};
|
|
275
|
+
this.#ensureRequiredStyleText(record, renderer);
|
|
276
|
+
return record;
|
|
277
|
+
}
|
|
278
|
+
const style = renderer.createElement('style');
|
|
279
|
+
const ownedText = renderer.createText(SD_LOADING_STYLES);
|
|
280
|
+
renderer.setAttribute(style, SD_LOADING_STYLE_ATTRIBUTE, '');
|
|
281
|
+
renderer.appendChild(style, ownedText);
|
|
282
|
+
renderer.appendChild(this.#document.head, style);
|
|
283
|
+
return { element: style, libraryOwned: true, owners, ownedText };
|
|
284
|
+
}
|
|
285
|
+
#ensureRequiredStyleText(record, renderer) {
|
|
286
|
+
const currentText = record.element.textContent ?? '';
|
|
287
|
+
const hasRequiredRules = currentText.includes('.sd-loading {') &&
|
|
288
|
+
currentText.includes('.sd-loading-spinner') &&
|
|
289
|
+
currentText.includes('@keyframes sd-loading-spin');
|
|
290
|
+
if (hasRequiredRules)
|
|
291
|
+
return;
|
|
292
|
+
if (record.ownedText && record.ownedText.parentNode !== record.element)
|
|
293
|
+
record.ownedText = null;
|
|
294
|
+
if (!record.ownedText) {
|
|
295
|
+
record.ownedText = renderer.createText(SD_LOADING_STYLES);
|
|
296
|
+
renderer.appendChild(record.element, record.ownedText);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
#detachOwnedStyleContent(record, renderer) {
|
|
300
|
+
if (record.libraryOwned) {
|
|
301
|
+
const parent = record.element.parentNode;
|
|
302
|
+
if (parent)
|
|
303
|
+
renderer.removeChild(parent, record.element);
|
|
304
|
+
}
|
|
305
|
+
else if (record.ownedText) {
|
|
306
|
+
const textParent = record.ownedText.parentNode;
|
|
307
|
+
if (textParent)
|
|
308
|
+
renderer.removeChild(textParent, record.ownedText);
|
|
309
|
+
}
|
|
310
|
+
record.ownedText = null;
|
|
311
|
+
}
|
|
312
|
+
#destroy() {
|
|
313
|
+
if (this.#destroyed)
|
|
314
|
+
return;
|
|
315
|
+
this.#destroyed = true;
|
|
316
|
+
const renderer = this.#renderer;
|
|
317
|
+
if (renderer) {
|
|
318
|
+
for (const state of [...this.#handleQueue])
|
|
319
|
+
this.#closeHandle(state, renderer);
|
|
320
|
+
this.#unregisterStyles(renderer);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
for (const state of this.#handleQueue) {
|
|
324
|
+
state.closed = true;
|
|
325
|
+
state.contributions.length = 0;
|
|
326
|
+
}
|
|
327
|
+
this.#handleQueue.length = 0;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
#unregisterStyles(renderer) {
|
|
331
|
+
if (!this.#styleRegistered)
|
|
332
|
+
return;
|
|
333
|
+
this.#styleRegistered = false;
|
|
334
|
+
const documentRecord = _a.documentRecords.get(this.#document);
|
|
335
|
+
const record = documentRecord?.style;
|
|
336
|
+
if (!documentRecord || !record)
|
|
337
|
+
return;
|
|
338
|
+
record.owners.delete(this);
|
|
339
|
+
if (record.owners.size === 0) {
|
|
340
|
+
this.#detachOwnedStyleContent(record, renderer);
|
|
341
|
+
documentRecord.style = undefined;
|
|
342
|
+
}
|
|
343
|
+
this.#deleteDocumentRecordWhenEmpty(documentRecord);
|
|
344
|
+
}
|
|
345
|
+
#deleteDocumentRecordWhenEmpty(documentRecord) {
|
|
346
|
+
if (documentRecord.liveHosts.size === 0 && !documentRecord.style) {
|
|
347
|
+
_a.documentRecords.delete(this.#document);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdLoadingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
87
351
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdLoadingService, providedIn: 'root' });
|
|
88
352
|
}
|
|
353
|
+
_a = SdLoadingService;
|
|
89
354
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdLoadingService, decorators: [{
|
|
90
355
|
type: Injectable,
|
|
91
356
|
args: [{
|
|
92
357
|
providedIn: 'root',
|
|
93
358
|
}]
|
|
94
|
-
}], ctorParameters: () => [
|
|
359
|
+
}], ctorParameters: () => [] });
|
|
95
360
|
|
|
96
361
|
/**
|
|
97
362
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdcorejs-angular-services-loading.mjs","sources":["../../../projects/sdcorejs-angular/services/loading/src/loading.service.ts","../../../projects/sdcorejs-angular/services/loading/sdcorejs-angular-services-loading.ts"],"sourcesContent":["import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdLoadingService {\n private loadingId = 'L8d556b9b-f6dd-46e9-9710-757e65d82839';\n\n private renderer: Renderer2;\n\n private loadingMap = new WeakMap<Element, HTMLElement>();\n constructor(rendererFactory: RendererFactory2) {\n this.renderer = rendererFactory.createRenderer(null, null);\n }\n\n start = (element = 'body') => {\n // why: router tabs can leave multiple hosts with the same selector in the DOM;\n // querySelector would only overlay the first match.\n document.querySelectorAll(element).forEach(ele => {\n if (!this.loadingMap.has(ele)) {\n const loadingElement = this.#createLoading();\n ele.appendChild(loadingElement);\n this.loadingMap.set(ele, loadingElement);\n }\n });\n };\n\n isLoading = (element = 'body') => {\n const nodes = document.querySelectorAll(element);\n if (!nodes.length) return null;\n for (const ele of Array.from(nodes)) {\n if (this.loadingMap.has(ele)) return ele;\n }\n return false;\n };\n\n stop = (element = 'body') => {\n document.querySelectorAll(element).forEach(ele => {\n if (this.loadingMap.has(ele)) {\n this.loadingMap.get(ele)?.remove();\n this.loadingMap.delete(ele);\n }\n });\n };\n\n #createLoading = (): HTMLElement => {\n const renderer = this.renderer;\n const container: HTMLElement = this.renderer.createElement('div');\n const spinner: HTMLElement = this.renderer.createElement('div');\n const containerStyle = {\n position: 'absolute',\n top: 0,\n left: 0,\n height: '100%',\n width: '100%',\n opacity: 0.6,\n background: '#FFFFFF',\n 'z-index': 99999,\n };\n const spinnerStyle = {\n position: 'absolute',\n top: 'calc(50% - 2.5rem)',\n left: 'calc(50% - 2.5rem)',\n width: '5rem',\n height: '5rem',\n border: '0.5rem solid var(--sd-primary)',\n 'border-top': '0.5rem solid var(--sd-border)',\n 'border-radius': '50%',\n animation: 'spin 1s linear infinite',\n };\n const keyframes = `\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `;\n\n renderer.addClass(container, 'sd-loading');\n renderer.setAttribute(container, 'id', this.loadingId);\n\n Object.entries(containerStyle).forEach(entry => {\n renderer.setStyle(container, entry[0], entry[1]);\n });\n\n renderer.addClass(spinner, 'sd-loading-spinner');\n Object.entries(spinnerStyle).forEach(entry => {\n renderer.setStyle(spinner, entry[0], entry[1]);\n });\n\n const styleElement = this.renderer.createElement('style');\n this.renderer.appendChild(styleElement, this.renderer.createText(keyframes));\n document.head.appendChild(styleElement);\n\n container.appendChild(spinner);\n return container;\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sdcorejs-angular-services-loading.mjs","sources":["../../../projects/sdcorejs-angular/services/loading/src/loading.service.ts","../../../projects/sdcorejs-angular/services/loading/sdcorejs-angular-services-loading.ts"],"sourcesContent":["import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, Injectable, PLATFORM_ID, Renderer2, RendererFactory2, inject } from '@angular/core';\n\nexport interface SdLoadingRef {\n readonly closed: boolean;\n close(): void;\n}\n\ninterface SdLoadingDocumentRecord {\n readonly hostStates: WeakMap<Element, SdLoadingHostState>;\n readonly liveHosts: Set<Element>;\n style: SdLoadingStyleRecord | undefined;\n}\n\ninterface SdLoadingHostState {\n readonly overlay: HTMLElement;\n readonly previousAriaBusy: string | null;\n readonly contributions: SdLoadingContribution[];\n count: number;\n}\n\ninterface SdLoadingHandleState {\n readonly selector: string;\n readonly contributions: SdLoadingContribution[];\n closed: boolean;\n}\n\ninterface SdLoadingContribution {\n readonly host: Element;\n readonly owner: SdLoadingHandleState;\n readonly service: SdLoadingService;\n released: boolean;\n}\n\ninterface SdLoadingStyleRecord {\n readonly element: HTMLStyleElement;\n readonly libraryOwned: boolean;\n readonly owners: Set<SdLoadingService>;\n ownedText: Text | null;\n}\n\nconst SD_LOADING_STYLE_ATTRIBUTE = 'data-sd-loading-styles';\nconst SD_LOADING_STYLES = `\n.sd-loading {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n opacity: 0.6;\n background: #fff;\n z-index: 99999;\n}\n\n.sd-loading-spinner {\n position: absolute;\n top: calc(50% - 2.5rem);\n left: calc(50% - 2.5rem);\n width: 5rem;\n height: 5rem;\n border: 0.5rem solid var(--sd-primary);\n border-top-color: var(--sd-border);\n border-radius: 50%;\n animation: sd-loading-spin 1s linear infinite;\n}\n\n@keyframes sd-loading-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n`;\n\nconst CLOSED_LOADING_REF: SdLoadingRef = Object.freeze({\n closed: true,\n close(): void {\n // A closed ref deliberately has no work to release.\n },\n});\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdLoadingService {\n private static readonly documentRecords = new WeakMap<Document, SdLoadingDocumentRecord>();\n\n readonly #document: Document;\n readonly #renderer: Renderer2 | null;\n readonly #isBrowser: boolean;\n readonly #destroyRef = inject(DestroyRef);\n readonly #handleQueue: SdLoadingHandleState[] = [];\n\n #styleRegistered = false;\n #destroyed = false;\n\n /** Inserted by Angular inject() migration for backwards compatibility. */\n constructor(...args: unknown[]);\n constructor() {\n this.#document = inject(DOCUMENT);\n this.#isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n const rendererFactory = inject(RendererFactory2);\n this.#renderer = this.#isBrowser ? rendererFactory.createRenderer(null, null) : null;\n this.#destroyRef.onDestroy(() => this.#destroy());\n }\n\n /** Starts loading for every current selector match and returns ownership of those exact hosts. */\n start = (selector = 'body'): SdLoadingRef => {\n const renderer = this.#renderer;\n if (this.#destroyed || !this.#isBrowser || !renderer) return CLOSED_LOADING_REF;\n\n const hosts = Array.from(this.#document.querySelectorAll(selector));\n if (hosts.length === 0) return CLOSED_LOADING_REF;\n\n const documentRecord = this.#getOrCreateDocumentRecord();\n this.#ensureStyles(documentRecord, renderer);\n const state: SdLoadingHandleState = { selector, contributions: [], closed: false };\n for (const host of hosts) {\n const contribution: SdLoadingContribution = {\n host,\n owner: state,\n service: this,\n released: false,\n };\n state.contributions.push(contribution);\n this.#acquireHost(documentRecord, contribution, renderer);\n }\n this.#handleQueue.push(state);\n\n return {\n get closed(): boolean {\n return state.closed;\n },\n close: () => this.#closeHandle(state, renderer),\n };\n };\n\n /** Returns the first matched globally loading host, `false` for idle matches, or `null` when unavailable. */\n isLoading = (selector = 'body'): Element | false | null => {\n if (this.#destroyed || !this.#isBrowser) return null;\n\n const hosts = this.#document.querySelectorAll(selector);\n if (hosts.length === 0) return null;\n\n const documentRecord = SdLoadingService.documentRecords.get(this.#document);\n for (const host of Array.from(hosts)) {\n const state = documentRecord?.hostStates.get(host);\n if (state && state.count > 0 && state.overlay.parentNode === host) return host;\n }\n return false;\n };\n\n /** Releases the oldest exact-selector start, with a current-host fallback for legacy cross-selector calls. */\n stop = (selector = 'body'): void => {\n const renderer = this.#renderer;\n if (this.#destroyed || !this.#isBrowser || !renderer) return;\n\n const exactHandle = this.#handleQueue.find(state => !state.closed && state.selector === selector);\n if (exactHandle) {\n this.#closeHandle(exactHandle, renderer);\n return;\n }\n\n const documentRecord = SdLoadingService.documentRecords.get(this.#document);\n if (!documentRecord) return;\n\n for (const host of Array.from(this.#document.querySelectorAll(selector))) {\n const contribution = documentRecord.hostStates\n .get(host)\n ?.contributions.find(candidate => !candidate.released && candidate.service === this);\n if (contribution) this.#releaseContribution(documentRecord, contribution, renderer);\n }\n };\n\n run<T>(task: () => T | PromiseLike<T>, selector?: string): Promise<T>;\n run<T>(task: PromiseLike<T>, selector?: string): Promise<T>;\n /** Runs a task inside a loading lifetime and always releases it without replacing the task result or error. */\n async run<T>(task: (() => T | PromiseLike<T>) | PromiseLike<T>, selector = 'body'): Promise<T> {\n const ref = this.start(selector);\n try {\n const result = typeof task === 'function' ? task() : task;\n return await result;\n } finally {\n ref.close();\n }\n }\n\n #getOrCreateDocumentRecord(): SdLoadingDocumentRecord {\n let record = SdLoadingService.documentRecords.get(this.#document);\n if (!record) {\n record = {\n hostStates: new WeakMap<Element, SdLoadingHostState>(),\n liveHosts: new Set<Element>(),\n style: undefined,\n };\n SdLoadingService.documentRecords.set(this.#document, record);\n }\n return record;\n }\n\n #acquireHost(documentRecord: SdLoadingDocumentRecord, contribution: SdLoadingContribution, renderer: Renderer2): void {\n const host = contribution.host;\n const existing = documentRecord.hostStates.get(host);\n if (existing) {\n this.#repairOverlay(host, existing, renderer);\n existing.count += 1;\n existing.contributions.push(contribution);\n return;\n }\n\n const state: SdLoadingHostState = {\n overlay: this.#createOverlay(renderer),\n previousAriaBusy: host.getAttribute('aria-busy'),\n contributions: [contribution],\n count: 1,\n };\n renderer.setAttribute(host, 'aria-busy', 'true');\n renderer.appendChild(host, state.overlay);\n documentRecord.hostStates.set(host, state);\n documentRecord.liveHosts.add(host);\n }\n\n #repairOverlay(host: Element, state: SdLoadingHostState, renderer: Renderer2): void {\n const currentParent = state.overlay.parentNode;\n if (currentParent !== host) {\n if (currentParent) renderer.removeChild(currentParent, state.overlay);\n renderer.appendChild(host, state.overlay);\n }\n if (host.getAttribute('aria-busy') !== 'true') renderer.setAttribute(host, 'aria-busy', 'true');\n }\n\n #releaseContribution(documentRecord: SdLoadingDocumentRecord, contribution: SdLoadingContribution, renderer: Renderer2): void {\n if (contribution.released) return;\n contribution.released = true;\n\n const state = documentRecord.hostStates.get(contribution.host);\n if (state) {\n const contributionIndex = state.contributions.indexOf(contribution);\n if (contributionIndex >= 0) state.contributions.splice(contributionIndex, 1);\n state.count -= 1;\n\n if (state.count <= 0) this.#removeHost(documentRecord, contribution.host, state, renderer);\n }\n\n contribution.service.#closeOwnerWhenReleased(contribution.owner);\n }\n\n #removeHost(documentRecord: SdLoadingDocumentRecord, host: Element, state: SdLoadingHostState, renderer: Renderer2): void {\n const parent = state.overlay.parentNode;\n if (parent) renderer.removeChild(parent, state.overlay);\n\n if (host.getAttribute('aria-busy') === 'true') {\n if (state.previousAriaBusy === null) renderer.removeAttribute(host, 'aria-busy');\n else renderer.setAttribute(host, 'aria-busy', state.previousAriaBusy);\n }\n\n documentRecord.hostStates.delete(host);\n documentRecord.liveHosts.delete(host);\n this.#deleteDocumentRecordWhenEmpty(documentRecord);\n }\n\n #closeHandle(state: SdLoadingHandleState, renderer: Renderer2): void {\n if (state.closed) return;\n\n state.closed = true;\n this.#dequeueHandle(state);\n const documentRecord = SdLoadingService.documentRecords.get(this.#document);\n if (documentRecord) {\n for (const contribution of [...state.contributions]) {\n this.#releaseContribution(documentRecord, contribution, renderer);\n }\n } else {\n for (const contribution of state.contributions) contribution.released = true;\n }\n state.contributions.length = 0;\n }\n\n #closeOwnerWhenReleased(state: SdLoadingHandleState): void {\n if (state.closed || state.contributions.some(contribution => !contribution.released)) return;\n\n state.closed = true;\n this.#dequeueHandle(state);\n state.contributions.length = 0;\n }\n\n #dequeueHandle(state: SdLoadingHandleState): void {\n const handleIndex = this.#handleQueue.indexOf(state);\n if (handleIndex >= 0) this.#handleQueue.splice(handleIndex, 1);\n }\n\n #createOverlay(renderer: Renderer2): HTMLElement {\n const container: HTMLElement = renderer.createElement('div');\n const spinner: HTMLElement = renderer.createElement('div');\n\n renderer.addClass(container, 'sd-loading');\n renderer.setAttribute(container, 'role', 'status');\n renderer.setAttribute(container, 'aria-live', 'polite');\n renderer.setAttribute(container, 'aria-label', 'Loading');\n\n renderer.addClass(spinner, 'sd-loading-spinner');\n renderer.setAttribute(spinner, 'aria-hidden', 'true');\n renderer.appendChild(container, spinner);\n return container;\n }\n\n #ensureStyles(documentRecord: SdLoadingDocumentRecord, renderer: Renderer2): void {\n let record = documentRecord.style;\n if (record && !this.#isCurrentStyle(record.element)) {\n const owners = record.owners;\n this.#detachOwnedStyleContent(record, renderer);\n record = this.#createStyleRecord(renderer, owners);\n documentRecord.style = record;\n } else if (!record) {\n record = this.#createStyleRecord(renderer, new Set<SdLoadingService>());\n documentRecord.style = record;\n } else {\n this.#ensureRequiredStyleText(record, renderer);\n }\n\n record.owners.add(this);\n this.#styleRegistered = true;\n }\n\n #isCurrentStyle(element: HTMLStyleElement): boolean {\n return element.isConnected && element.parentNode === this.#document.head && element.hasAttribute(SD_LOADING_STYLE_ATTRIBUTE);\n }\n\n #createStyleRecord(renderer: Renderer2, owners: Set<SdLoadingService>): SdLoadingStyleRecord {\n const existing = this.#document.head.querySelector<HTMLStyleElement>(`style[${SD_LOADING_STYLE_ATTRIBUTE}]`);\n if (existing) {\n const record: SdLoadingStyleRecord = {\n element: existing,\n libraryOwned: false,\n owners,\n ownedText: null,\n };\n this.#ensureRequiredStyleText(record, renderer);\n return record;\n }\n\n const style: HTMLStyleElement = renderer.createElement('style');\n const ownedText: Text = renderer.createText(SD_LOADING_STYLES);\n renderer.setAttribute(style, SD_LOADING_STYLE_ATTRIBUTE, '');\n renderer.appendChild(style, ownedText);\n renderer.appendChild(this.#document.head, style);\n return { element: style, libraryOwned: true, owners, ownedText };\n }\n\n #ensureRequiredStyleText(record: SdLoadingStyleRecord, renderer: Renderer2): void {\n const currentText = record.element.textContent ?? '';\n const hasRequiredRules =\n currentText.includes('.sd-loading {') &&\n currentText.includes('.sd-loading-spinner') &&\n currentText.includes('@keyframes sd-loading-spin');\n if (hasRequiredRules) return;\n\n if (record.ownedText && record.ownedText.parentNode !== record.element) record.ownedText = null;\n if (!record.ownedText) {\n record.ownedText = renderer.createText(SD_LOADING_STYLES);\n renderer.appendChild(record.element, record.ownedText);\n }\n }\n\n #detachOwnedStyleContent(record: SdLoadingStyleRecord, renderer: Renderer2): void {\n if (record.libraryOwned) {\n const parent = record.element.parentNode;\n if (parent) renderer.removeChild(parent, record.element);\n } else if (record.ownedText) {\n const textParent = record.ownedText.parentNode;\n if (textParent) renderer.removeChild(textParent, record.ownedText);\n }\n record.ownedText = null;\n }\n\n #destroy(): void {\n if (this.#destroyed) return;\n this.#destroyed = true;\n\n const renderer = this.#renderer;\n if (renderer) {\n for (const state of [...this.#handleQueue]) this.#closeHandle(state, renderer);\n this.#unregisterStyles(renderer);\n } else {\n for (const state of this.#handleQueue) {\n state.closed = true;\n state.contributions.length = 0;\n }\n this.#handleQueue.length = 0;\n }\n }\n\n #unregisterStyles(renderer: Renderer2): void {\n if (!this.#styleRegistered) return;\n this.#styleRegistered = false;\n\n const documentRecord = SdLoadingService.documentRecords.get(this.#document);\n const record = documentRecord?.style;\n if (!documentRecord || !record) return;\n\n record.owners.delete(this);\n if (record.owners.size === 0) {\n this.#detachOwnedStyleContent(record, renderer);\n documentRecord.style = undefined;\n }\n this.#deleteDocumentRecordWhenEmpty(documentRecord);\n }\n\n #deleteDocumentRecordWhenEmpty(documentRecord: SdLoadingDocumentRecord): void {\n if (documentRecord.liveHosts.size === 0 && !documentRecord.style) {\n SdLoadingService.documentRecords.delete(this.#document);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, computed, SecurityContext, HostListener, Input, ChangeDetectionStrategy, Component,
|
|
3
|
+
import { inject, signal, computed, SecurityContext, HostListener, Input, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, createComponent, Injectable } from '@angular/core';
|
|
4
4
|
import { Utilities } from '@sdcorejs/utils/fns';
|
|
5
5
|
import { TranslatePipe, I18nService } from '@sdcorejs/angular/i18n';
|
|
6
|
-
import
|
|
6
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
7
7
|
|
|
8
8
|
const TOAST_EXIT_ANIMATION_MS = 200;
|
|
9
9
|
class ToastComponent {
|
|
10
|
-
notifyService;
|
|
11
|
-
sanitizer;
|
|
10
|
+
notifyService = inject(SdNotifyService);
|
|
11
|
+
sanitizer = inject(DomSanitizer);
|
|
12
12
|
data;
|
|
13
13
|
isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : /* istanbul ignore next */ []));
|
|
14
14
|
isClosing = signal(false, ...(ngDevMode ? [{ debugName: "isClosing" }] : /* istanbul ignore next */ []));
|
|
@@ -18,10 +18,7 @@ class ToastComponent {
|
|
|
18
18
|
closeTimer = null;
|
|
19
19
|
start = 0;
|
|
20
20
|
remaining = 0;
|
|
21
|
-
constructor(
|
|
22
|
-
this.notifyService = notifyService;
|
|
23
|
-
this.sanitizer = sanitizer;
|
|
24
|
-
}
|
|
21
|
+
constructor() { }
|
|
25
22
|
ngOnInit() {
|
|
26
23
|
this.remaining = this.data.duration;
|
|
27
24
|
this.resumeTimer();
|
|
@@ -108,7 +105,7 @@ class ToastComponent {
|
|
|
108
105
|
clearTimeout(this.closeTimer);
|
|
109
106
|
this.closeTimer = null;
|
|
110
107
|
}
|
|
111
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ToastComponent, deps: [
|
|
108
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
112
109
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ToastComponent, isStandalone: true, selector: "toast", inputs: { data: "data" }, host: { listeners: { "mouseenter": "pauseTimer()", "mouseleave": "resumeTimer()" }, properties: { "class": "hostClasses()", "attr.data-autoid": "autoId", "attr.data-type": "data.type", "attr.data-title": "data.title ?? null", "attr.data-message": "dataMessage" } }, ngImport: i0, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\n\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\n @switch (data.type) {\n @case ('success') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\n }\n @case ('info') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\n }\n @case ('warning') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\n }\n @case ('error') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\n }\n }\n</div>\n\n<div class=\"sd-toast__content\">\n <div class=\"sd-toast__header\">\n <strong class=\"sd-toast__title\">{{ data.title || ('core.notify.type.' + data.type | translate) }}</strong>\n <button class=\"sd-toast__close\" (click)=\"close()\">×</button>\n </div>\n\n <div class=\"sd-toast__body\">\n @if (!isMultiMessage) {\n <!-- Text rendering is the default safe path; HTML is opt-in and sanitized. -->\n @if (data.html) {\n <div [innerHTML]=\"sanitizeHtml(singleMessage)\"></div>\n } @else {\n <div>{{ singleMessage }}</div>\n }\n } @else {\n <ul class=\"msg-list\">\n @for (msg of displayMessages; track msg) {\n @if (data.html) {\n <li [innerHTML]=\"sanitizeHtml('- ' + msg)\"></li>\n } @else {\n <li>{{ '- ' + msg }}</li>\n }\n }\n </ul>\n\n @if (hasMore) {\n <button\n type=\"button\"\n class=\"toggle-more btn-link\"\n [class]=\"'text-' + data.type\"\n (click)=\"toggleExpand()\">\n {{ isExpanded() ? ('core.notify.show-less' | translate) : ('core.notify.show-more' | translate: { count: restCount }) }}\n </button>\n }\n }\n </div>\n\n @if (data.actionLabel) {\n <div class=\"sd-toast__actions\">\n <button\n class=\"btn-action\"\n [class]=\"'bg-' + data.type + '-light text-' + data.type\"\n (click)=\"onActionClick()\">\n {{ data.actionLabel }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto;animation:sd-toast-enter .3s ease-out}:host(.sd-toast--closing){pointer-events:none;animation:sd-toast-leave .2s ease-in forwards}@keyframes sd-toast-enter{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes sd-toast-leave{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:0}}@media(prefers-reduced-motion:reduce){:host,:host(.sd-toast--closing){animation:none}}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4;word-break:break-word}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
113
110
|
}
|
|
114
111
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ToastComponent, decorators: [{
|
|
@@ -120,7 +117,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
120
117
|
'[attr.data-title]': 'data.title ?? null',
|
|
121
118
|
'[attr.data-message]': 'dataMessage',
|
|
122
119
|
}, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\n\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\n @switch (data.type) {\n @case ('success') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\n }\n @case ('info') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\n }\n @case ('warning') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\n }\n @case ('error') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\n }\n }\n</div>\n\n<div class=\"sd-toast__content\">\n <div class=\"sd-toast__header\">\n <strong class=\"sd-toast__title\">{{ data.title || ('core.notify.type.' + data.type | translate) }}</strong>\n <button class=\"sd-toast__close\" (click)=\"close()\">×</button>\n </div>\n\n <div class=\"sd-toast__body\">\n @if (!isMultiMessage) {\n <!-- Text rendering is the default safe path; HTML is opt-in and sanitized. -->\n @if (data.html) {\n <div [innerHTML]=\"sanitizeHtml(singleMessage)\"></div>\n } @else {\n <div>{{ singleMessage }}</div>\n }\n } @else {\n <ul class=\"msg-list\">\n @for (msg of displayMessages; track msg) {\n @if (data.html) {\n <li [innerHTML]=\"sanitizeHtml('- ' + msg)\"></li>\n } @else {\n <li>{{ '- ' + msg }}</li>\n }\n }\n </ul>\n\n @if (hasMore) {\n <button\n type=\"button\"\n class=\"toggle-more btn-link\"\n [class]=\"'text-' + data.type\"\n (click)=\"toggleExpand()\">\n {{ isExpanded() ? ('core.notify.show-less' | translate) : ('core.notify.show-more' | translate: { count: restCount }) }}\n </button>\n }\n }\n </div>\n\n @if (data.actionLabel) {\n <div class=\"sd-toast__actions\">\n <button\n class=\"btn-action\"\n [class]=\"'bg-' + data.type + '-light text-' + data.type\"\n (click)=\"onActionClick()\">\n {{ data.actionLabel }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto;animation:sd-toast-enter .3s ease-out}:host(.sd-toast--closing){pointer-events:none;animation:sd-toast-leave .2s ease-in forwards}@keyframes sd-toast-enter{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes sd-toast-leave{0%{transform:translate(0);opacity:1}to{transform:translate(100%);opacity:0}}@media(prefers-reduced-motion:reduce){:host,:host(.sd-toast--closing){animation:none}}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4;word-break:break-word}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"] }]
|
|
123
|
-
}], ctorParameters: () => [
|
|
120
|
+
}], ctorParameters: () => [], propDecorators: { data: [{
|
|
124
121
|
type: Input,
|
|
125
122
|
args: [{ required: true }]
|
|
126
123
|
}], pauseTimer: [{
|