@lukfel/ng-scaffold 22.1.3 → 22.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { MediaMatcher, BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
|
3
|
+
import { inject, PLATFORM_ID, REQUEST, Injectable, InjectionToken, makeEnvironmentProviders, DOCUMENT, signal, input, output, ChangeDetectionStrategy, Component, effect, DestroyRef, viewChild, computed, model, afterNextRender, linkedSignal, TemplateRef, Directive, contentChild } from '@angular/core';
|
|
4
4
|
import { isPlatformBrowser, NgClass, NgTemplateOutlet, KeyValuePipe } from '@angular/common';
|
|
5
5
|
import { toObservable, toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
6
|
import * as i1$3 from '@angular/router';
|
|
@@ -45,9 +45,89 @@ import { MatRippleModule } from '@angular/material/core';
|
|
|
45
45
|
import * as i8 from '@angular/material/divider';
|
|
46
46
|
import { MatDividerModule } from '@angular/material/divider';
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Viewports assumed during SSR. A request reveals a device class, never an actual viewport, and
|
|
50
|
+
* CDK exposes only query strings, so these are plausible device sizes rather than derived values.
|
|
51
|
+
* They have to keep landing in `Breakpoints.XSmall` and `Breakpoints.Large`, which the spec asserts.
|
|
52
|
+
*/
|
|
53
|
+
const SSR_MOBILE_VIEWPORT = { width: 390, height: 844 };
|
|
54
|
+
const SSR_DESKTOP_VIEWPORT = { width: 1280, height: 800 };
|
|
55
|
+
const MOBILE_USER_AGENT_REGEX = /Android|iPhone|iPod|Windows Phone|IEMobile|BlackBerry|Opera Mini/i;
|
|
56
|
+
/**
|
|
57
|
+
* Answers media queries during SSR from the incoming request rather than matching nothing, so
|
|
58
|
+
* breakpoint driven markup is server rendered for the requesting device class instead of always
|
|
59
|
+
* falling back to desktop. On the browser it defers to the platform implementation.
|
|
60
|
+
*
|
|
61
|
+
* Opt in with `provideScaffold({ ssrBreakpoints: true })`. Doing so makes the SSR response depend
|
|
62
|
+
* on the request, so whatever serves it must `Vary` on `Sec-CH-UA-Mobile` and `User-Agent` or a
|
|
63
|
+
* cached mobile render will be handed to a desktop client.
|
|
64
|
+
*/
|
|
65
|
+
class ScaffoldMediaMatcher extends MediaMatcher {
|
|
66
|
+
constructor() {
|
|
67
|
+
super(...arguments);
|
|
68
|
+
this.platformId = inject(PLATFORM_ID);
|
|
69
|
+
this.request = inject(REQUEST, { optional: true });
|
|
70
|
+
}
|
|
71
|
+
matchMedia(query) {
|
|
72
|
+
if (isPlatformBrowser(this.platformId))
|
|
73
|
+
return super.matchMedia(query);
|
|
74
|
+
const { width, height } = this.isMobileRequest() ? SSR_MOBILE_VIEWPORT : SSR_DESKTOP_VIEWPORT;
|
|
75
|
+
return {
|
|
76
|
+
matches: matchesMediaQuery(query, width, height),
|
|
77
|
+
media: query,
|
|
78
|
+
onchange: null,
|
|
79
|
+
addListener: () => { },
|
|
80
|
+
removeListener: () => { },
|
|
81
|
+
addEventListener: () => { },
|
|
82
|
+
removeEventListener: () => { },
|
|
83
|
+
dispatchEvent: () => false,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Sec-CH-UA-Mobile needs no Accept-CH opt in on Chromium; other browsers only give a User-Agent
|
|
87
|
+
isMobileRequest() {
|
|
88
|
+
const headers = this.request?.headers;
|
|
89
|
+
if (!headers)
|
|
90
|
+
return false;
|
|
91
|
+
const hint = headers.get('sec-ch-ua-mobile');
|
|
92
|
+
if (hint)
|
|
93
|
+
return hint.includes('?1');
|
|
94
|
+
return MOBILE_USER_AGENT_REGEX.test(headers.get('user-agent') ?? '');
|
|
95
|
+
}
|
|
96
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScaffoldMediaMatcher, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
97
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScaffoldMediaMatcher }); }
|
|
98
|
+
}
|
|
99
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ScaffoldMediaMatcher, decorators: [{
|
|
100
|
+
type: Injectable
|
|
101
|
+
}] });
|
|
102
|
+
/**
|
|
103
|
+
* Evaluates the width and orientation parts of a media query against an assumed viewport.
|
|
104
|
+
* Conditions a request cannot answer, such as `prefers-color-scheme`, never match.
|
|
105
|
+
*/
|
|
106
|
+
function matchesMediaQuery(query, width, height) {
|
|
107
|
+
// A comma separated query matches when any of its branches matches
|
|
108
|
+
return query.split(',').some((branch) => branch.split(' and ').every((condition) => {
|
|
109
|
+
const min = condition.match(/min-width:\s*([\d.]+)px/);
|
|
110
|
+
if (min)
|
|
111
|
+
return width >= parseFloat(min[1]);
|
|
112
|
+
const max = condition.match(/max-width:\s*([\d.]+)px/);
|
|
113
|
+
if (max)
|
|
114
|
+
return width <= parseFloat(max[1]);
|
|
115
|
+
if (/orientation:\s*portrait/.test(condition))
|
|
116
|
+
return height >= width;
|
|
117
|
+
if (/orientation:\s*landscape/.test(condition))
|
|
118
|
+
return width > height;
|
|
119
|
+
return false;
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
|
|
48
123
|
const CONFIG = new InjectionToken('config');
|
|
49
124
|
function provideScaffold(config = {}) {
|
|
50
|
-
|
|
125
|
+
const providers = [{ provide: CONFIG, useValue: config }];
|
|
126
|
+
// Opt in, because it makes the SSR response depend on the request and therefore on Vary
|
|
127
|
+
if (config.ssrBreakpoints) {
|
|
128
|
+
providers.push({ provide: MediaMatcher, useClass: ScaffoldMediaMatcher });
|
|
129
|
+
}
|
|
130
|
+
return makeEnvironmentProviders(providers);
|
|
51
131
|
}
|
|
52
132
|
|
|
53
133
|
class BreakpointService {
|
|
@@ -1845,5 +1925,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
1845
1925
|
* Generated bundle index. Do not edit.
|
|
1846
1926
|
*/
|
|
1847
1927
|
|
|
1848
|
-
export { BreakpointService, CONFIG, ColorPickerComponent, DialogService, FileUploadComponent, ListComponent, ListItemAvatarDirective, ListItemButtonsDirective, ListItemSubtitleDirective, ListItemTitleDirective, LocalStorageService, Logger, NotificationComponent, OverlayService, PlaceholderComponent, RouterService, ScaffoldComponent, ScaffoldLoadingInterceptor, ScaffoldService, SeoService, SnackbarService, ThemeService, TranslationService, provideScaffold };
|
|
1928
|
+
export { BreakpointService, CONFIG, ColorPickerComponent, DialogService, FileUploadComponent, ListComponent, ListItemAvatarDirective, ListItemButtonsDirective, ListItemSubtitleDirective, ListItemTitleDirective, LocalStorageService, Logger, NotificationComponent, OverlayService, PlaceholderComponent, RouterService, ScaffoldComponent, ScaffoldLoadingInterceptor, ScaffoldMediaMatcher, ScaffoldService, SeoService, SnackbarService, ThemeService, TranslationService, matchesMediaQuery, provideScaffold };
|
|
1849
1929
|
//# sourceMappingURL=lukfel-ng-scaffold.mjs.map
|