wacom 21.1.8 → 21.1.9
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/fesm2022/wacom.mjs +305 -155
- package/fesm2022/wacom.mjs.map +1 -1
- package/package.json +1 -1
- package/types/wacom.d.ts +218 -64
package/fesm2022/wacom.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, Inject, Optional, Injectable, signal, inject, ChangeDetectorRef, output, ElementRef, DestroyRef, Directive, input, effect, Pipe, isSignal, ApplicationRef, EnvironmentInjector, createComponent, makeEnvironmentProviders, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/router';
|
|
4
|
+
import { NavigationEnd } from '@angular/router';
|
|
5
|
+
import { filter, first, catchError } from 'rxjs/operators';
|
|
4
6
|
import * as i2 from '@angular/platform-browser';
|
|
5
7
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
6
|
-
import { take, firstValueFrom, Subject, skip, takeUntil, share, filter, map, Observable, merge, combineLatest, timeout, ReplaySubject, EMPTY } from 'rxjs';
|
|
8
|
+
import { take, firstValueFrom, Subject, skip, takeUntil, share, filter as filter$1, map, Observable, merge, combineLatest, timeout, ReplaySubject, EMPTY } from 'rxjs';
|
|
7
9
|
import { toObservable } from '@angular/core/rxjs-interop';
|
|
8
10
|
import * as i1$1 from '@angular/common/http';
|
|
9
11
|
import { HttpHeaders, HttpErrorResponse, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
|
10
|
-
import { first, catchError } from 'rxjs/operators';
|
|
11
12
|
import * as i1$2 from '@angular/common';
|
|
12
13
|
import { CommonModule } from '@angular/common';
|
|
13
14
|
import { FormsModule } from '@angular/forms';
|
|
@@ -19,7 +20,6 @@ const DEFAULT_CONFIG = {
|
|
|
19
20
|
},
|
|
20
21
|
meta: {
|
|
21
22
|
useTitleSuffix: false,
|
|
22
|
-
warnMissingGuard: false,
|
|
23
23
|
defaults: { links: {} },
|
|
24
24
|
},
|
|
25
25
|
socket: false,
|
|
@@ -51,216 +51,366 @@ const NETWORK_CONFIG = new InjectionToken('NETWORK_CONFIG', {
|
|
|
51
51
|
factory: () => DEFAULT_NETWORK_CONFIG,
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Utility helpers for meta management.
|
|
56
|
+
*
|
|
57
|
+
* We intentionally treat `undefined` as "missing" and everything else as "provided".
|
|
58
|
+
* This lets callers pass empty strings to intentionally clear a value:
|
|
59
|
+
* - isDefined(undefined) -> false (use defaults)
|
|
60
|
+
* - isDefined('') -> true (explicitly set empty string)
|
|
61
|
+
* - isDefined(null) -> true (explicitly provided, will stringify if used)
|
|
62
|
+
*/
|
|
54
63
|
const isDefined = (val) => typeof val !== 'undefined';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Centralized page meta management for SPA navigation.
|
|
67
|
+
*
|
|
68
|
+
* Goals:
|
|
69
|
+
* - Static SEO pages: route-driven meta via `data.meta`
|
|
70
|
+
* - Dynamic/id pages: manual meta via `applyMeta(...)`
|
|
71
|
+
* - No stale meta: tags set for one page must not "leak" to another page
|
|
72
|
+
* - Simple inputs: only title/description/image/index/robots (everything else auto-generated)
|
|
73
|
+
* - Links handled separately: `setLink({ canonical: '...' })` updates, never duplicates
|
|
74
|
+
*
|
|
75
|
+
* Generated tags:
|
|
76
|
+
* - Title:
|
|
77
|
+
* - <title>
|
|
78
|
+
* - <meta itemprop="name" ...>
|
|
79
|
+
* - <meta property="og:title" ...>
|
|
80
|
+
* - <meta name="twitter:title" ...>
|
|
81
|
+
* - Description:
|
|
82
|
+
* - <meta name="description" ...>
|
|
83
|
+
* - <meta itemprop="description" ...>
|
|
84
|
+
* - <meta property="og:description" ...>
|
|
85
|
+
* - <meta name="twitter:description" ...>
|
|
86
|
+
* - Image:
|
|
87
|
+
* - <meta itemprop="image" ...>
|
|
88
|
+
* - <meta property="og:image" ...>
|
|
89
|
+
* - <meta name="twitter:image:src" ...>
|
|
90
|
+
* - Robots:
|
|
91
|
+
* - <meta name="robots" ...> (derived from `robots` or `index`)
|
|
92
|
+
*/
|
|
55
93
|
class MetaService {
|
|
56
|
-
constructor(config, router, meta, titleService) {
|
|
94
|
+
constructor(config, router, activatedRoute, meta, titleService) {
|
|
57
95
|
this.config = config;
|
|
58
96
|
this.router = router;
|
|
97
|
+
this.activatedRoute = activatedRoute;
|
|
59
98
|
this.meta = meta;
|
|
60
99
|
this.titleService = titleService;
|
|
100
|
+
/**
|
|
101
|
+
* Meta tags that are "owned" by this service.
|
|
102
|
+
* We remove these on every `applyMeta()` so stale tags never survive SPA navigation.
|
|
103
|
+
*
|
|
104
|
+
* Stored as selectors compatible with Angular Meta.removeTag(), e.g.:
|
|
105
|
+
* - name="description"
|
|
106
|
+
* - property="og:title"
|
|
107
|
+
* - itemprop="image"
|
|
108
|
+
*/
|
|
109
|
+
this.managedTagSelectors = new Set();
|
|
110
|
+
/**
|
|
111
|
+
* Link rels that are managed by this service.
|
|
112
|
+
* Used to update links without duplicates and optionally remove them via resetLinks().
|
|
113
|
+
*/
|
|
114
|
+
this.managedLinkRels = new Set();
|
|
61
115
|
this.config = this.config || DEFAULT_CONFIG;
|
|
62
|
-
this.
|
|
63
|
-
|
|
116
|
+
this.metaConfig = this.config.meta || {};
|
|
117
|
+
// Recommended default: keep meta in sync with route changes automatically.
|
|
118
|
+
const applyFromRoutes = !isDefined(this.metaConfig.applyFromRoutes) ||
|
|
119
|
+
!!this.metaConfig.applyFromRoutes;
|
|
120
|
+
if (applyFromRoutes) {
|
|
121
|
+
this.router.events
|
|
122
|
+
.pipe(filter((e) => e instanceof NavigationEnd))
|
|
123
|
+
.subscribe(() => {
|
|
124
|
+
const page = this._readDeepestRouteMeta();
|
|
125
|
+
if (page)
|
|
126
|
+
this.applyMeta(page);
|
|
127
|
+
else
|
|
128
|
+
this.reset();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
64
131
|
}
|
|
65
132
|
/**
|
|
66
|
-
*
|
|
133
|
+
* Merge and set defaults.
|
|
67
134
|
*
|
|
68
|
-
*
|
|
135
|
+
* Defaults are used when a page does not provide a given field.
|
|
136
|
+
* This affects:
|
|
137
|
+
* - applyMeta() fallbacks
|
|
138
|
+
* - reset()
|
|
69
139
|
*/
|
|
70
140
|
setDefaults(defaults) {
|
|
71
|
-
this.
|
|
72
|
-
...this.
|
|
141
|
+
this.metaConfig.defaults = {
|
|
142
|
+
...(this.metaConfig.defaults || {}),
|
|
73
143
|
...defaults,
|
|
74
144
|
};
|
|
75
145
|
}
|
|
76
146
|
/**
|
|
77
|
-
*
|
|
147
|
+
* Apply metadata for the current page.
|
|
148
|
+
*
|
|
149
|
+
* Use cases:
|
|
150
|
+
* - Static SEO pages: route data (`data.meta`) when applyFromRoutes = true
|
|
151
|
+
* - Dynamic / id pages: call manually after loading entity data
|
|
152
|
+
*
|
|
153
|
+
* Rules:
|
|
154
|
+
* 1) remove tags previously managed by this service
|
|
155
|
+
* 2) start from defaults
|
|
156
|
+
* 3) override with page values
|
|
157
|
+
* 4) generate OG/Twitter/itemprop variants
|
|
158
|
+
*/
|
|
159
|
+
applyMeta(page = {}) {
|
|
160
|
+
if (page.disableUpdate)
|
|
161
|
+
return;
|
|
162
|
+
// 1) Clean managed tags to prevent leaks between pages.
|
|
163
|
+
this._removeManagedTags();
|
|
164
|
+
// 2) Resolve values with defaults.
|
|
165
|
+
const defaults = this.metaConfig.defaults || {};
|
|
166
|
+
const title = this._resolveTitle(page, defaults);
|
|
167
|
+
const description = this._resolveValue(page.description, defaults.description);
|
|
168
|
+
const image = this._resolveValue(page.image, defaults.image);
|
|
169
|
+
const robots = this._resolveRobots(page, defaults);
|
|
170
|
+
// 3) Apply generated tags.
|
|
171
|
+
this._setTitleTriplet(title);
|
|
172
|
+
this._setDescriptionTriplet(description);
|
|
173
|
+
this._setImageTriplet(image);
|
|
174
|
+
// 4) Robots support (index/noindex).
|
|
175
|
+
if (isDefined(robots)) {
|
|
176
|
+
this._updateTag('robots', robots, 'name');
|
|
177
|
+
}
|
|
178
|
+
// Links are intentionally not applied here.
|
|
179
|
+
// Canonical strategy depends on your routing/domain policy, so use setLink(...) explicitly.
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Reset page meta back to defaults.
|
|
78
183
|
*
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
: this._meta.defaults?.['title'] || '';
|
|
87
|
-
if (this._meta.useTitleSuffix) {
|
|
88
|
-
titleContent += isDefined(titleSuffix)
|
|
89
|
-
? titleSuffix
|
|
90
|
-
: this._meta.defaults?.['titleSuffix'] || '';
|
|
91
|
-
}
|
|
92
|
-
this._updateMetaTag('title', titleContent);
|
|
93
|
-
this._updateMetaTag('og:title', titleContent);
|
|
94
|
-
this._updateMetaTag('twitter:title', titleContent);
|
|
95
|
-
this.titleService.setTitle(titleContent);
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Sets link tags.
|
|
184
|
+
* Removes all managed tags and re-applies defaults-only meta.
|
|
185
|
+
*/
|
|
186
|
+
reset() {
|
|
187
|
+
this.applyMeta({});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Sets link tags (canonical, alternate, etc.) without duplicates.
|
|
100
191
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
192
|
+
* For each rel:
|
|
193
|
+
* - if link[rel=rel] exists -> update href
|
|
194
|
+
* - else -> create it
|
|
195
|
+
* - if duplicates exist -> remove extras
|
|
103
196
|
*/
|
|
104
197
|
setLink(links) {
|
|
105
|
-
Object.keys(links).
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
document.head.
|
|
110
|
-
|
|
111
|
-
|
|
198
|
+
if (!links || !Object.keys(links).length)
|
|
199
|
+
return;
|
|
200
|
+
for (const rel of Object.keys(links)) {
|
|
201
|
+
const href = links[rel];
|
|
202
|
+
const all = Array.from(document.head.querySelectorAll(`link[rel="${rel}"]`));
|
|
203
|
+
let link = all[0];
|
|
204
|
+
if (!link) {
|
|
205
|
+
link = document.createElement('link');
|
|
206
|
+
link.setAttribute('rel', rel);
|
|
207
|
+
document.head.appendChild(link);
|
|
208
|
+
}
|
|
209
|
+
else if (all.length > 1) {
|
|
210
|
+
for (let i = 1; i < all.length; i++)
|
|
211
|
+
all[i].remove();
|
|
212
|
+
}
|
|
213
|
+
link.setAttribute('href', href);
|
|
214
|
+
this.managedLinkRels.add(rel);
|
|
215
|
+
}
|
|
112
216
|
}
|
|
113
217
|
/**
|
|
114
|
-
*
|
|
218
|
+
* Removes link tags that were managed by this service via setLink().
|
|
115
219
|
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
220
|
+
* Note:
|
|
221
|
+
* - Not called by reset() because canonical often should persist for the whole app shell.
|
|
222
|
+
* - Call explicitly if you want to remove canonical/alternate links.
|
|
119
223
|
*/
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
224
|
+
resetLinks() {
|
|
225
|
+
for (const rel of this.managedLinkRels) {
|
|
226
|
+
const all = Array.from(document.head.querySelectorAll(`link[rel="${rel}"]`));
|
|
227
|
+
all.forEach((it) => it.remove());
|
|
123
228
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
229
|
+
this.managedLinkRels.clear();
|
|
230
|
+
}
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Internals: route meta extraction
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
/**
|
|
235
|
+
* Reads `data.meta` from the deepest activated route.
|
|
236
|
+
* This matches the common Angular pattern where child routes override parent routes.
|
|
237
|
+
*/
|
|
238
|
+
_readDeepestRouteMeta() {
|
|
239
|
+
let route = this.activatedRoute;
|
|
240
|
+
while (route?.firstChild)
|
|
241
|
+
route = route.firstChild;
|
|
242
|
+
const data = route?.snapshot?.data;
|
|
243
|
+
const meta = data && data['meta'];
|
|
244
|
+
return meta || null;
|
|
245
|
+
}
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// Internals: resolving values
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
/**
|
|
250
|
+
* Resolves title with optional suffix behavior.
|
|
251
|
+
*/
|
|
252
|
+
_resolveTitle(page, defaults) {
|
|
253
|
+
let titleContent = this._resolveValue(page.title, defaults.title) || '';
|
|
254
|
+
if (this.metaConfig.useTitleSuffix) {
|
|
255
|
+
const suffix = isDefined(page.titleSuffix)
|
|
256
|
+
? page.titleSuffix
|
|
257
|
+
: defaults.titleSuffix;
|
|
258
|
+
titleContent += suffix || '';
|
|
131
259
|
}
|
|
260
|
+
return titleContent;
|
|
132
261
|
}
|
|
133
262
|
/**
|
|
134
|
-
*
|
|
263
|
+
* Resolves robots value.
|
|
135
264
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
265
|
+
* Precedence:
|
|
266
|
+
* - explicit robots (page) > explicit robots (defaults)
|
|
267
|
+
* - index flag (page/defaults) -> generates "index, follow" or "noindex, follow"
|
|
268
|
+
* - undefined -> no robots tag set by this service
|
|
269
|
+
*/
|
|
270
|
+
_resolveRobots(page, defaults) {
|
|
271
|
+
if (isDefined(page.robots))
|
|
272
|
+
return (page.robots || '') + '';
|
|
273
|
+
if (isDefined(defaults.robots))
|
|
274
|
+
return (defaults.robots || '') + '';
|
|
275
|
+
const index = isDefined(page.index) ? page.index : defaults.index;
|
|
276
|
+
if (!isDefined(index))
|
|
277
|
+
return undefined;
|
|
278
|
+
return index ? 'index, follow' : 'noindex, follow';
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Resolves value with "undefined means missing" semantics.
|
|
282
|
+
* - undefined -> fallback
|
|
283
|
+
* - empty string -> explicit empty
|
|
284
|
+
*/
|
|
285
|
+
_resolveValue(val, fallback) {
|
|
286
|
+
if (isDefined(val))
|
|
287
|
+
return (val || '') + '';
|
|
288
|
+
if (isDefined(fallback))
|
|
289
|
+
return (fallback || '') + '';
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
// Internals: generated tag groups
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
/**
|
|
296
|
+
* Applies title to:
|
|
297
|
+
* - document <title>
|
|
298
|
+
* - itemprop="name"
|
|
299
|
+
* - og:title
|
|
300
|
+
* - twitter:title
|
|
301
|
+
*/
|
|
302
|
+
_setTitleTriplet(title) {
|
|
303
|
+
this.titleService.setTitle(title);
|
|
304
|
+
this._updateTag('og:title', title, 'property');
|
|
305
|
+
this._updateTag('twitter:title', title, 'name');
|
|
306
|
+
this._updateTag('name', title, 'itemprop');
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Applies description to:
|
|
310
|
+
* - name="description"
|
|
311
|
+
* - itemprop="description"
|
|
312
|
+
* - og:description
|
|
313
|
+
* - twitter:description
|
|
314
|
+
*/
|
|
315
|
+
_setDescriptionTriplet(description) {
|
|
316
|
+
if (!isDefined(description))
|
|
317
|
+
return;
|
|
318
|
+
const content = description;
|
|
319
|
+
this._updateTag('description', content, 'name');
|
|
320
|
+
this._updateTag('og:description', content, 'property');
|
|
321
|
+
this._updateTag('twitter:description', content, 'name');
|
|
322
|
+
this._updateTag('description', content, 'itemprop');
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Applies image to:
|
|
326
|
+
* - itemprop="image"
|
|
327
|
+
* - og:image
|
|
328
|
+
* - twitter:image:src
|
|
139
329
|
*/
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
this.
|
|
330
|
+
_setImageTriplet(image) {
|
|
331
|
+
if (!isDefined(image))
|
|
332
|
+
return;
|
|
333
|
+
const content = image;
|
|
334
|
+
this._updateTag('og:image', content, 'property');
|
|
335
|
+
this._updateTag('twitter:image:src', content, 'name');
|
|
336
|
+
this._updateTag('image', content, 'itemprop');
|
|
147
337
|
}
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
// Internals: tag update + ownership tracking
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
148
341
|
/**
|
|
149
|
-
*
|
|
342
|
+
* Update a meta tag with deterministic selector.
|
|
343
|
+
*
|
|
344
|
+
* Why selector:
|
|
345
|
+
* - prevents duplicates
|
|
346
|
+
* - ensures updates target the correct attribute variant (name/property/itemprop)
|
|
150
347
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
348
|
+
* Ownership tracking:
|
|
349
|
+
* - Every selector we touch is remembered in managedTagSelectors.
|
|
350
|
+
* - On next apply/reset we remove them to avoid stale meta across pages.
|
|
153
351
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
this.
|
|
352
|
+
_updateTag(key, content, attr) {
|
|
353
|
+
const selector = attr === 'itemprop' ? `itemprop="${key}"` : `${attr}="${key}"`;
|
|
354
|
+
const tagDef = attr === 'itemprop'
|
|
355
|
+
? { itemprop: key, content }
|
|
356
|
+
: { [attr]: key, content };
|
|
357
|
+
this.meta.updateTag(tagDef, selector);
|
|
358
|
+
this.managedTagSelectors.add(selector);
|
|
161
359
|
}
|
|
162
360
|
/**
|
|
163
|
-
*
|
|
361
|
+
* Remove all meta tags managed by this service.
|
|
362
|
+
* Called on each apply/reset to prevent tags from a previous page persisting.
|
|
164
363
|
*/
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
const hasDefaultMeta = !!Object.keys(this._meta.defaults ?? {}).length;
|
|
171
|
-
const hasMetaGuardInArr = (it) => it && it.IDENTIFIER === 'MetaGuard';
|
|
172
|
-
let hasShownWarnings = false;
|
|
173
|
-
const checkRoute = (route) => {
|
|
174
|
-
const hasRouteMeta = route.data && route.data['meta'];
|
|
175
|
-
const showWarning = !isDefined(route.redirectTo) &&
|
|
176
|
-
(hasDefaultMeta || hasRouteMeta) &&
|
|
177
|
-
!(route.canActivate || []).some(hasMetaGuardInArr);
|
|
178
|
-
if (showWarning) {
|
|
179
|
-
console.warn(`Route with path "${route.path}" has ${hasRouteMeta ? '' : 'default '}meta tags, but does not use MetaGuard. Please add MetaGuard to the canActivate array in your route configuration`);
|
|
180
|
-
hasShownWarnings = true;
|
|
181
|
-
}
|
|
182
|
-
(route.children || []).forEach(checkRoute);
|
|
183
|
-
};
|
|
184
|
-
this.router.config.forEach(checkRoute);
|
|
185
|
-
if (hasShownWarnings) {
|
|
186
|
-
console.warn(`To disable these warnings, set metaConfig.warnMissingGuard: false in your MetaConfig passed to MetaModule.forRoot()`);
|
|
364
|
+
_removeManagedTags() {
|
|
365
|
+
for (const selector of this.managedTagSelectors) {
|
|
366
|
+
this.meta.removeTag(selector);
|
|
187
367
|
}
|
|
368
|
+
this.managedTagSelectors.clear();
|
|
188
369
|
}
|
|
189
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaService, deps: [{ token: CONFIG_TOKEN, optional: true }, { token: i1.Router }, { token: i2.Meta }, { token: i2.Title }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
370
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaService, deps: [{ token: CONFIG_TOKEN, optional: true }, { token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.Meta }, { token: i2.Title }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
190
371
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaService, providedIn: 'root' }); }
|
|
191
372
|
}
|
|
192
373
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaService, decorators: [{
|
|
193
374
|
type: Injectable,
|
|
194
|
-
args: [{
|
|
195
|
-
providedIn: 'root',
|
|
196
|
-
}]
|
|
375
|
+
args: [{ providedIn: 'root' }]
|
|
197
376
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
198
377
|
type: Inject,
|
|
199
378
|
args: [CONFIG_TOKEN]
|
|
200
379
|
}, {
|
|
201
380
|
type: Optional
|
|
202
|
-
}] }, { type: i1.Router }, { type: i2.Meta }, { type: i2.Title }] });
|
|
381
|
+
}] }, { type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.Meta }, { type: i2.Title }] });
|
|
203
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Applies route-level metadata from `route.data.meta`.
|
|
385
|
+
*
|
|
386
|
+
* Usage:
|
|
387
|
+
* - Add this guard to routes that define `data.meta` to ensure meta is applied
|
|
388
|
+
* as early as possible during activation.
|
|
389
|
+
*
|
|
390
|
+
* Note:
|
|
391
|
+
* - If `MetaConfig.applyFromRoutes` is enabled (recommended), the service will
|
|
392
|
+
* also apply route meta automatically on NavigationEnd — even if this guard
|
|
393
|
+
* is missing from some route definitions.
|
|
394
|
+
*/
|
|
204
395
|
class MetaGuard {
|
|
205
|
-
|
|
206
|
-
constructor(metaService, config) {
|
|
396
|
+
constructor(metaService) {
|
|
207
397
|
this.metaService = metaService;
|
|
208
|
-
this.config = config;
|
|
209
|
-
if (!this.config)
|
|
210
|
-
this.config = DEFAULT_CONFIG;
|
|
211
|
-
this._meta = this.config.meta || {};
|
|
212
|
-
this._meta.defaults = this._meta.defaults || {};
|
|
213
398
|
}
|
|
214
|
-
canActivate(route
|
|
215
|
-
|
|
399
|
+
canActivate(route) {
|
|
400
|
+
const pageMeta = (route.data && route.data['meta']) || null;
|
|
401
|
+
if (pageMeta)
|
|
402
|
+
this.metaService.applyMeta(pageMeta);
|
|
403
|
+
else
|
|
404
|
+
this.metaService.reset();
|
|
216
405
|
return true;
|
|
217
406
|
}
|
|
218
|
-
|
|
219
|
-
if (meta.disableUpdate) {
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
if (meta.title) {
|
|
223
|
-
this.metaService.setTitle(meta.title, meta.titleSuffix);
|
|
224
|
-
}
|
|
225
|
-
if (meta.links && Object.keys(meta.links).length) {
|
|
226
|
-
this.metaService.setLink(meta.links);
|
|
227
|
-
}
|
|
228
|
-
if (this._meta.defaults?.links &&
|
|
229
|
-
Object.keys(this._meta.defaults.links).length) {
|
|
230
|
-
this.metaService.setLink(this._meta.defaults.links);
|
|
231
|
-
}
|
|
232
|
-
Object.keys(meta).forEach((prop) => {
|
|
233
|
-
if (prop === 'title' ||
|
|
234
|
-
prop === 'titleSuffix' ||
|
|
235
|
-
prop === 'links') {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
Object.keys(meta[prop]).forEach((key) => {
|
|
239
|
-
this.metaService.setTag(key, meta[prop][key], prop);
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
Object.keys(this._meta.defaults).forEach((key) => {
|
|
243
|
-
if (key in meta ||
|
|
244
|
-
key === 'title' ||
|
|
245
|
-
key === 'titleSuffix' ||
|
|
246
|
-
key === 'links') {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
this.metaService.setTag(key, this._meta.defaults[key]);
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaGuard, deps: [{ token: MetaService }, { token: CONFIG_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
407
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaGuard, deps: [{ token: MetaService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
253
408
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaGuard, providedIn: 'root' }); }
|
|
254
409
|
}
|
|
255
410
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: MetaGuard, decorators: [{
|
|
256
411
|
type: Injectable,
|
|
257
412
|
args: [{ providedIn: 'root' }]
|
|
258
|
-
}], ctorParameters: () => [{ type: MetaService }
|
|
259
|
-
type: Inject,
|
|
260
|
-
args: [CONFIG_TOKEN]
|
|
261
|
-
}, {
|
|
262
|
-
type: Optional
|
|
263
|
-
}] }] });
|
|
413
|
+
}], ctorParameters: () => [{ type: MetaService }] });
|
|
264
414
|
|
|
265
415
|
// Core utilities and helpers for the Wacom app
|
|
266
416
|
// Add capitalize method to String prototype if it doesn't already exist
|
|
@@ -1446,7 +1596,7 @@ class EmitterService {
|
|
|
1446
1596
|
}
|
|
1447
1597
|
onComplete(tasks, opts) {
|
|
1448
1598
|
const list = (Array.isArray(tasks) ? tasks : [tasks]).filter(Boolean);
|
|
1449
|
-
const streams = list.map((id) => toObservable(this._getDoneSignal(id)).pipe(filter((v) => v !== undefined), map((v) => v)));
|
|
1599
|
+
const streams = list.map((id) => toObservable(this._getDoneSignal(id)).pipe(filter$1((v) => v !== undefined), map((v) => v)));
|
|
1450
1600
|
let source$;
|
|
1451
1601
|
if (list.length <= 1) {
|
|
1452
1602
|
// single-task await
|