-
Notifications
You must be signed in to change notification settings - Fork 773
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): add centralized media marshal service
This design change marks a number of departures from the current Angular Layout configuration: 1. A number of APIs are deprecated in favor of a more polished, integrated API 2. A new semantics for creating custom breakpoint directives is introduced 3. A number of bugs caught along the way and design changes missed in past PRs are rectified > **PLEASE NOTE**: There will be **no end-user API changes** as a result of this PR. Unless custom breakpoints are configured, devs should see no change in how the library usage. These changes will deliver notice significant size & performance improvements. * `MediaMarshaller` A centralized data store for elements, breakpoints, and key-value pairs. The `MediaMarshaller` responds to mediaQuery changes and triggers appropriate Layout directives. This class also introduces a way to track changes for arbitrary elements and directive types * `BaseDirective2` A new directive with stripped-down functionality from the old `BaseDirective` that is designed to work in symbiosis with the `MediaMarshaller` The custom breakpoints story has changed significantly. Instead of extending directives that contain the default breakpoints and writing lengthy constructors, the process has been paired down to the following (i.e. for `fxFlexOffset`): ```ts const inputs = ['fxFlexOffset.xss']; const selector = `[fxFlexOffset.xss]`; @directive({selector, inputs}) export class XssFlexOffsetDirective extends FlexOffsetDirective { protected inputs = inputs; } ``` Never again will a change in the base directive constructor require an entire rewrite of custom breakpoint directives. And registering a new directive no longer brings collisions and double-registrations competing with the default directives. Everything is separated and improved. * All of the Grid and extended Flex directives have been updated to the new standards; namely, they have been refactored to the new API with `StyleBuilder`s. The notable exception is `show-hide`, which uses a `StyleBuilder`, but does not have a cache for the results. > FxShowHide does not use a stylebuilder cache as to avoid complexity for cache-shifting based on the host `display` property. If needed, an internal cache can be easily added later. * A number of APIs had the default values calculated in the directives instead of the `StyleBuilder`, meaning that it would be much harder to override by end-users. This has been fixed * An issue where `fxLayoutGap` was canceling out `fxFlexOffset` has been corrected * `MediaMonitor` (use `MediaMarshaller`) * `ResponsiveActivation` * `BreakpointX` * `KeyOptions` * `negativeOf` * `BaseDirective` (use `BaseDirective2`) * `BaseAdapter` The minified size of the Angular Layout library has decreased *~38%* from **132KB** to **82KB**, a total savings of 50KB. After the deprecated APIs are deleted (Beta.21), the build size will be reduced yet again. It should also bring about performance improvements as a result of fewer RxJS subscriptions, memoized style lookups, and other API processing. It is our hope that along with the added `StyleBuilder` functionality, and migration away from `ObservableMedia`, this represents the end-stage towards stability for Angular Layout. Closes #903 Fixes #692
- Loading branch information
1 parent
21151b0
commit 6db5c65
Showing
54 changed files
with
2,386 additions
and
2,742 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
import {ElementRef, OnChanges, OnDestroy, SimpleChanges} from '@angular/core'; | ||
import {Subject} from 'rxjs'; | ||
|
||
import {StyleDefinition, StyleUtils} from '../style-utils/style-utils'; | ||
import {StyleBuilder} from '../style-builder/style-builder'; | ||
import {MediaMarshaller} from '../media-marshaller/media-marshaller'; | ||
import {buildLayoutCSS} from '../../utils/layout-validator'; | ||
|
||
export abstract class BaseDirective2 implements OnChanges, OnDestroy { | ||
|
||
protected DIRECTIVE_KEY = ''; | ||
protected inputs: string[] = []; | ||
protected destroySubject: Subject<void> = new Subject(); | ||
|
||
/** Access to host element's parent DOM node */ | ||
protected get parentElement(): HTMLElement | null { | ||
return this.elementRef.nativeElement.parentElement; | ||
} | ||
|
||
/** Access to the HTMLElement for the directive */ | ||
protected get nativeElement(): HTMLElement { | ||
return this.elementRef.nativeElement; | ||
} | ||
|
||
/** Access to the activated value for the directive */ | ||
get activatedValue(): string { | ||
return this.marshal.getValue(this.nativeElement, this.DIRECTIVE_KEY); | ||
} | ||
set activatedValue(value: string) { | ||
this.marshal.setValue(this.nativeElement, this.DIRECTIVE_KEY, value, | ||
this.marshal.activatedBreakpoint); | ||
} | ||
|
||
/** Cache map for style computation */ | ||
protected styleCache: Map<string, StyleDefinition> = new Map(); | ||
|
||
protected constructor(protected elementRef: ElementRef, | ||
protected styleBuilder: StyleBuilder, | ||
protected styler: StyleUtils, | ||
protected marshal: MediaMarshaller) { | ||
} | ||
|
||
/** For @Input changes */ | ||
ngOnChanges(changes: SimpleChanges) { | ||
Object.keys(changes).forEach(key => { | ||
if (this.inputs.indexOf(key) !== -1) { | ||
const bp = key.split('.')[1] || ''; | ||
const val = changes[key].currentValue; | ||
this.setValue(val, bp); | ||
} | ||
}); | ||
} | ||
|
||
ngOnDestroy(): void { | ||
this.destroySubject.next(); | ||
this.destroySubject.complete(); | ||
this.marshal.releaseElement(this.nativeElement); | ||
} | ||
|
||
/** Add styles to the element using predefined style builder */ | ||
protected addStyles(input: string, parent?: Object) { | ||
const builder = this.styleBuilder; | ||
const useCache = builder.shouldCache; | ||
|
||
let genStyles: StyleDefinition | undefined = this.styleCache.get(input); | ||
|
||
if (!genStyles || !useCache) { | ||
genStyles = builder.buildStyles(input, parent); | ||
if (useCache) { | ||
this.styleCache.set(input, genStyles); | ||
} | ||
} | ||
|
||
this.applyStyleToElement(genStyles); | ||
builder.sideEffect(input, genStyles, parent); | ||
} | ||
|
||
protected triggerUpdate() { | ||
const val = this.marshal.getValue(this.nativeElement, this.DIRECTIVE_KEY); | ||
this.marshal.updateElement(this.nativeElement, this.DIRECTIVE_KEY, val); | ||
} | ||
|
||
/** | ||
* Determine the DOM element's Flexbox flow (flex-direction). | ||
* | ||
* Check inline style first then check computed (stylesheet) style. | ||
* And optionally add the flow value to element's inline style. | ||
*/ | ||
protected getFlexFlowDirection(target: HTMLElement, addIfMissing = false): string { | ||
if (target) { | ||
const [value, hasInlineValue] = this.styler.getFlowDirection(target); | ||
|
||
if (!hasInlineValue && addIfMissing) { | ||
const style = buildLayoutCSS(value); | ||
const elements = [target]; | ||
this.styler.applyStyleToElements(style, elements); | ||
} | ||
|
||
return value.trim(); | ||
} | ||
|
||
return 'row'; | ||
} | ||
|
||
/** Applies styles given via string pair or object map to the directive element */ | ||
protected applyStyleToElement(style: StyleDefinition, | ||
value?: string | number, | ||
element: HTMLElement = this.nativeElement) { | ||
this.styler.applyStyleToElement(element, style, value); | ||
} | ||
|
||
protected setValue(val: any, bp: string): void { | ||
this.marshal.setValue(this.nativeElement, this.DIRECTIVE_KEY, val, bp); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ | |
|
||
export * from './base'; | ||
export * from './base-adapter'; | ||
export * from './base2'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.