Skip to content

Commit

Permalink
fix: make implicit browser platform dependency optional and disallow …
Browse files Browse the repository at this point in the history
…focus tracking on non-browser platforms
  • Loading branch information
MrWolfZ committed Apr 15, 2018
1 parent 00e43b4 commit e7760bc
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#### Bugfixes

* do not focus or blur form elements initially or on state changes when focus tracking is not enabled ([bb52f64](https://github.com/MrWolfZ/ngrx-forms/commit/bb52f64)) (thanks @bufke for helping me find this)
* make implicit browser platform dependency optional and disallow focus tracking on non-browser platforms (thanks @bufke for helping me find this)

<a name="2.3.1"></a>
### 2.3.1
Expand Down
11 changes: 11 additions & 0 deletions src/control/directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,17 @@ describe(NgrxFormControlDirective.name, () => {
});
});

describe('non-browser platforms', () => {
beforeEach(() => {
directive = new NgrxFormControlDirective<string>(elementRef, null, actionsSubject as any, [viewAdapter], []);
directive.ngrxFormControlState = INITIAL_STATE;
});

it('should throw when trying to enable focus tracking', () => {
expect(() => directive.ngrxEnableFocusTracking = true).toThrowError();
});
});

// TODO: throwing error on undefined state
// TODO: mark as touched
// TODO: disabling and enabling
Expand Down
20 changes: 15 additions & 5 deletions src/control/directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const BLUR = 'blur';
})
export class NgrxFormControlDirective<TStateValue extends FormControlValueTypes, TViewValue = TStateValue> implements AfterViewInit, OnInit {
private isInitialized = false;
private focusTrackingIsEnabled = false;

@Input() set ngrxFormControlState(newState: FormControlState<TStateValue>) {
if (!newState) {
Expand All @@ -46,7 +47,14 @@ export class NgrxFormControlDirective<TStateValue extends FormControlValueTypes,
}

@Input() ngrxUpdateOn: 'change' | 'blur' = CHANGE;
@Input() ngrxEnableFocusTracking = false;
@Input() set ngrxEnableFocusTracking(value: boolean) {
if (value && !this.dom) {
throw new Error('focus tracking is only supported on the browser platform');
}

this.focusTrackingIsEnabled = value;
}

@Input() ngrxValueConverter: NgrxValueConverter<TViewValue, TStateValue> = NgrxValueConverters.identity<any>();

// TODO: move this into a separate directive
Expand All @@ -72,7 +80,9 @@ export class NgrxFormControlDirective<TStateValue extends FormControlValueTypes,

constructor(
private el: ElementRef,
@Inject(DOCUMENT) private dom: Document,
// for the dom parameter the `null` type must be last to ensure that in the compiled output
// there is no reference to the Document type to support non-browser platforms
@Optional() @Inject(DOCUMENT) private dom: Document | null,
private actionsSubject: ActionsSubject,
@Self() @Optional() @Inject(NGRX_FORM_VIEW_ADAPTER) viewAdapters: FormViewAdapter[],
@Self() @Optional() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[],
Expand Down Expand Up @@ -125,7 +135,7 @@ export class NgrxFormControlDirective<TStateValue extends FormControlValueTypes,
}

updateViewIfIsFocusedChanged(newState: FormControlState<TStateValue>, oldState: FormControlState<TStateValue> | undefined) {
if (!this.ngrxEnableFocusTracking) {
if (!this.focusTrackingIsEnabled) {
return;
}

Expand Down Expand Up @@ -194,11 +204,11 @@ export class NgrxFormControlDirective<TStateValue extends FormControlValueTypes,
@HostListener('focusin')
@HostListener('focusout')
onFocusChange() {
if (!this.ngrxEnableFocusTracking) {
if (!this.focusTrackingIsEnabled) {
return;
}

const isControlFocused = this.el.nativeElement === this.dom.activeElement;
const isControlFocused = this.el.nativeElement === this.dom!.activeElement;
if (isControlFocused !== this.state.isFocused) {
this.actionsSubject.next(isControlFocused ? new FocusAction(this.state.id) : new UnfocusAction(this.state.id));
}
Expand Down

0 comments on commit e7760bc

Please sign in to comment.