Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit a386fed

Browse files
feat(core): add support for 1..n mediaQuery overrides during printing
When printing developers can now configure how layouts should render by specifying 1..n mediaQuery aliases. This feature allows totally different print outputs without modifying the currently layout. Implement PrintHook service to intercept print mediaQuery activation events. * add fxShow.print and fxHide.print support to show/hide elements during printing * suspend activation changes in MediaMarshaller while print-mode is active * trigger MediaObserver to notify subscribers with print mqAlias(es) * use PrintHook to intercept activation changes in MediaMarshaller while print-mode is active * trigger MediaObserver to notify subscribers with print mqAlias(es) Using the new `printWithBreakpoint` allows developers to specify a breakpoint that should be used to render layouts only during printing. With the configuration below, the breakpoint associated with the **`md`** alias will be used. ```ts FlexLayoutModule.withConfig({ useColumnBasisZero: false, printWithBreakpoints: ['md', 'gt-sm', 'gt-xs'] }) ``` Shown below is the print layout rendered in floating dialog over the normal layout using 'lg' breakpoints. ![angular-layout-printing](https://user-images.githubusercontent.com/210413/50407211-2e04ca00-0798-11e9-8f35-b4e9e2fca864.jpg) Fixes #603.
1 parent 350e753 commit a386fed

22 files changed

+695
-231
lines changed

docs/documentation/BreakPoints.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {BREAKPOINT} from '@angular/flex-layout';
4242
const PRINT_BREAKPOINTS = [{
4343
alias: 'xs.print',
4444
suffix: 'XsPrint',
45-
mediaQuery: 'print and (max-width: 297px)',
45+
mediaQuery: 'screen and (max-width: 297px)',
4646
overlapping: false
4747
}];
4848

@@ -73,7 +73,7 @@ export class MyAppModule {
7373
}
7474
```
7575

76-
With the above changes, when printing on mobile-sized viewports the **`xs.print`** mediaQuery will activate. Please note
76+
With the above changes, when printing on mobile-sized viewports the **`xs.print`** mediaQuery will onMediaChange. Please note
7777
that the provider is a **multi-provider**, meaning it can be provided multiple times and in a variety of
7878
presentations. The type signature of `BREAKPOINT` is the following:
7979

@@ -157,4 +157,4 @@ export class CustomShowHideDirective extends ShowHideDirective {
157157
this._cacheInput("showXsPrint", negativeOf(val));
158158
}
159159
}
160-
```
160+
```

docs/documentation/fxHide-API.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ e.g.
2424
2525
### Using Responsive API
2626

27-
When a mediaQuery range activates, the directive instances will be notified. If the current activate mediaQuery range
27+
When a mediaQuery range activates, the directive instances will be notified. If the current activated mediaQuery range
2828
(and its associated alias) are not used, then the static API value is restored as the fallback value.
2929

3030
The *fallback* solution uses a **`largest_range-to-smallest_range`** search algorithm. Consider the following:

docs/documentation/fxShow-API.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ e.g.
2424
2525
### Using Responsive API
2626

27-
When a mediaQuery range activates, the directive instances will be notified. If the current activate mediaQuery range
27+
When a mediaQuery range activates, the directive instances will be notified. If the current activated mediaQuery range
2828
(and its associated alias) are not used, then the static API value is restored as the fallback value.
2929

3030
The *fallback* solution uses a **`largest_range-to-smallest_range`** search algorithm. Consider the following:
+5-10
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
import {BrowserModule} from '@angular/platform-browser';
22
import {NgModule} from '@angular/core';
33
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
4-
import {FlexLayoutModule, BREAKPOINT} from '@angular/flex-layout';
4+
import {FlexLayoutModule} from '@angular/flex-layout';
55

66
import {RoutingModule} from './routing.module';
77
import {AppComponent} from './app.component';
88
import {DemoMaterialModule} from './material.module';
99

10-
const PRINT_BREAKPOINTS = [{
11-
alias: 'xs.print',
12-
suffix: 'XsPrint',
13-
mediaQuery: 'print and (max-width: 297px)',
14-
overlapping: false
15-
}];
16-
1710
@NgModule({
1811
declarations: [
1912
AppComponent,
@@ -23,9 +16,11 @@ const PRINT_BREAKPOINTS = [{
2316
BrowserAnimationsModule,
2417
RoutingModule,
2518
DemoMaterialModule,
26-
FlexLayoutModule.withConfig({useColumnBasisZero: false}),
19+
FlexLayoutModule.withConfig({
20+
useColumnBasisZero: false,
21+
printWithBreakpoints: ['md', 'gt-sm', 'gt-xs']
22+
}),
2723
],
28-
providers: [{provide: BREAKPOINT, useValue: PRINT_BREAKPOINTS, multi: true}],
2924
bootstrap: [AppComponent]
3025
})
3126
export class AppModule { }

src/apps/demo-app/src/styles.scss

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ body {
88
font-size: 16px;
99
line-height: 1.4;
1010
-webkit-font-smoothing: antialiased;
11+
-webkit-print-color-adjust: exact !important;
12+
}
13+
14+
@page {
15+
size: auto; /* auto is the initial value */
16+
margin: 2cm;
1117
}
1218

1319
h3 {

src/lib/core/add-alias.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {extendObject} from '../utils/object-extend';
1414
* and suffix (if available).
1515
*/
1616
export function mergeAlias(dest: MediaChange, source: BreakPoint | null): MediaChange {
17-
return extendObject(dest, source ? {
17+
return extendObject(dest || {}, source ? {
1818
mqAlias: source.alias,
1919
suffix: source.suffix
2020
} : {});

src/lib/core/base/base2.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export abstract class BaseDirective2 implements OnChanges, OnDestroy {
3737
}
3838
set activatedValue(value: string) {
3939
this.marshal.setValue(this.nativeElement, this.DIRECTIVE_KEY, value,
40-
this.marshal.activatedBreakpoint);
40+
this.marshal.activatedAlias);
4141
}
4242

4343
/** Cache map for style computation */

src/lib/core/breakpoints/break-point-registry.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {BreakPoint} from './break-point';
1111
import {BREAKPOINTS} from './break-points-token';
1212
import {sortAscendingPriority} from './breakpoint-tools';
1313

14-
type OptionalBreakPoint = BreakPoint | null;
14+
export type OptionalBreakPoint = BreakPoint | null;
1515

1616
/**
1717
* Registry of 1..n MediaQuery breakpoint ranges
@@ -30,7 +30,7 @@ export class BreakPointRegistry {
3030
* Search breakpoints by alias (e.g. gt-xs)
3131
*/
3232
findByAlias(alias: string): OptionalBreakPoint {
33-
return this.findWithPredicate(alias, (bp) => bp.alias == alias);
33+
return !alias ? null : this.findWithPredicate(alias, (bp) => bp.alias == alias);
3434
}
3535

3636
findByQuery(query: string): OptionalBreakPoint {

src/lib/core/match-media/match-media.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('match-media', () => {
2525

2626
// Single async inject to save references; which are used in all tests below
2727
beforeEach(async(inject([MatchMedia], (service: MockMatchMedia) => {
28-
matchMedia = service; // inject only to manually activate mediaQuery ranges
28+
matchMedia = service; // inject only to manually onMediaChange mediaQuery ranges
2929
})));
3030
afterEach(() => {
3131
matchMedia.clearAll();
@@ -121,7 +121,7 @@ describe('match-media-observable', () => {
121121
[MediaObserver, MatchMedia, BreakPointRegistry],
122122
(_mediaObserver: MediaObserver, _matchMedia: MockMatchMedia,
123123
_breakPoints: BreakPointRegistry) => {
124-
matchMedia = _matchMedia; // inject only to manually activate mediaQuery ranges
124+
matchMedia = _matchMedia; // inject only to manually onMediaChange mediaQuery ranges
125125
breakPoints = _breakPoints;
126126
mediaObserver = _mediaObserver;
127127
})));

src/lib/core/match-media/match-media.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ export class MatchMedia {
6565
const matches: Array<MediaChange> = this.registerQuery(mqList);
6666
if (matches.length) {
6767
const lastChange = matches.pop()!;
68-
69-
matches.forEach(observer.next);
68+
matches.forEach((e: MediaChange) => {
69+
observer.next(e);
70+
});
7071
this._source.next(lastChange); // last match is cached
7172
}
7273
observer.complete();

src/lib/core/match-media/mock/mock-match-media.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ describe('mock-match-media', () => {
183183
subscription.unsubscribe();
184184
});
185185

186-
it('can activate with either a mediaQuery or an alias', () => {
186+
it('can onMediaChange with either a mediaQuery or an alias', () => {
187187
let activates = 0;
188188
let bpGtSM = breakPoints.findByAlias('gt-sm'),
189189
bpLg = breakPoints.findByAlias('lg');

src/lib/core/match-media/mock/mock-match-media.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export class MockMatchMedia extends MatchMedia {
6868
}
6969

7070
/**
71-
* Manually activate any overlapping mediaQueries to simulate
71+
* Manually onMediaChange any overlapping mediaQueries to simulate
7272
* similar functionality in the window.matchMedia()
7373
*/
7474
private _activateWithOverlaps(mediaQuery: string, useOverlaps: boolean): boolean {
@@ -92,7 +92,7 @@ export class MockMatchMedia extends MatchMedia {
9292
break;
9393
}
9494

95-
// Simulate activate of overlapping gt-<xxxx> mediaQuery ranges
95+
// Simulate onMediaChange of overlapping gt-<xxxx> mediaQuery ranges
9696
switch (alias) {
9797
case 'xl' :
9898
this._activateByAlias('gt-lg, gt-md, gt-sm, gt-xs');
@@ -223,7 +223,7 @@ export class MockMediaQueryList implements MediaQueryList {
223223
return this;
224224
}
225225

226-
/** Add a listener to our internal list to activate later */
226+
/** Add a listener to our internal list to onMediaChange later */
227227
addListener(listener: MediaQueryListListener) {
228228
if (this._listeners.indexOf(listener) === -1) {
229229
this._listeners.push(listener);

src/lib/core/match-media/server-match-media.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export class ServerMediaQueryList implements MediaQueryList {
6363
return this;
6464
}
6565

66-
/** Add a listener to our internal list to activate later */
66+
/** Add a listener to our internal list to onMediaChange later */
6767
addListener(listener: MediaQueryListListener) {
6868
if (this._listeners.indexOf(listener) === -1) {
6969
this._listeners.push(listener);
@@ -109,7 +109,7 @@ export class ServerMediaQueryList implements MediaQueryList {
109109
* Special server-only implementation of MatchMedia that uses the above
110110
* ServerMediaQueryList as its internal representation
111111
*
112-
* Also contains methods to activate and deactivate breakpoints
112+
* Also contains methods to onMediaChange and deactivate breakpoints
113113
*/
114114
@Injectable()
115115
export class ServerMatchMedia extends MatchMedia {

0 commit comments

Comments
 (0)