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

refactor(top-app-bar): Remove [de]registerEventHandler methods from adapters #4701

Merged
merged 21 commits into from
May 17, 2019
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions packages/mdc-top-app-bar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,6 @@ Method Signature | Description
`getViewportScrollY() => number` | Gets the number of pixels that the content of body is scrolled from the top of the page.
`getTotalActionItems() => number` | Gets the number of action items in the top app bar.
`notifyNavigationIconClicked() => void` | Emits a custom event `MDCTopAppBar:nav` when the navigation icon is clicked.
`registerNavigationIconInteractionHandler(evtType: string, handler: EventListener) => void` | Registers an event listener on the native navigation icon element for a given event.
`deregisterNavigationIconInteractionHandler(evtType: string, handler: EventListener) => void` | Deregisters an event listener on the native navigation icon element for a given event.
`registerScrollHandler(handler: EventListener) => void` | Registers a handler to be called when user scrolls. Our default implementation adds the handler as a listener to the window's `scroll` event.
`deregisterScrollHandler(handler: EventListener) => void` | Unregisters a handler to be called when user scrolls. Our default implementation removes the handler as a listener to the window's `scroll` event.
`registerResizeHandler(handler: EventListener) => void` | Registers a handler to be called when the surface (or its viewport) resizes. Our default implementation adds the handler as a listener to the window's `resize` event.
`deregisterResizeHandler(handler: EventListener) => void` | Unregisters a handler to be called when the surface (or its viewport) resizes. Our default implementation removes the handler as a listener to the window's `resize` event.

### Foundations

Expand All @@ -234,8 +228,9 @@ All foundations provide the following methods:

Method Signature | Description
--- | ---
`initScrollHandler(handler: EventListener) => void` | Registers a scroll handler on a specific target element.
`destroyScrollHandler(handler: EventListener) => void` | Deregisters the current scroll handler set by the foundation.
`handleTargetScroll() => void` | Handles `scroll` event on specified scrollTarget (defaults to `window`).
`handleWindowResize() => void` | Handles `resize` event on window.
`handleNavigationClick() => void` | Handles `click` event on navigation icon.

#### `MDCShortTopAppBarFoundation`

Expand Down
20 changes: 0 additions & 20 deletions packages/mdc-top-app-bar/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
* THE SOFTWARE.
*/

import {EventType, SpecificEventListener} from '@material/base/types';

/**
* Defines the shape of the adapter expected by the foundation.
* Implement this adapter for your framework of choice to delegate updates to
Expand Down Expand Up @@ -64,22 +62,4 @@ export interface MDCTopAppBarAdapter {
* Emits an event when the navigation icon is clicked.
*/
notifyNavigationIconClicked(): void;

/**
* Registers an event handler on the navigation icon element for a given event.
*/
registerNavigationIconInteractionHandler<K extends EventType>(type: K, handler: SpecificEventListener<K>): void;

/**
* Deregisters an event handler on the navigation icon element for a given event.
*/
deregisterNavigationIconInteractionHandler<K extends EventType>(type: K, handler: SpecificEventListener<K>): void;

registerScrollHandler(handler: SpecificEventListener<'scroll'>): void;

deregisterScrollHandler(handler: SpecificEventListener<'scroll'>): void;

registerResizeHandler(handler: SpecificEventListener<'resize'>): void;

deregisterResizeHandler(handler: SpecificEventListener<'resize'>): void;
}
55 changes: 39 additions & 16 deletions packages/mdc-top-app-bar/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

import {MDCComponent} from '@material/base/component';
import {SpecificEventListener} from '@material/base/types';
import {MDCRipple, MDCRippleFactory} from '@material/ripple/component';
import {MDCTopAppBarAdapter} from './adapter';
import {cssClasses, strings} from './constants';
Expand All @@ -35,6 +36,9 @@ export class MDCTopAppBar extends MDCComponent<MDCTopAppBarBaseFoundation> {
return new MDCTopAppBar(root);
}

private handleNavigationClick_!: SpecificEventListener<'click'>; // assigned in initialSyncWithDOM()
private handleWindowResize_!: SpecificEventListener<'resize'>; // assigned in initialSyncWithDOM()
private handleTargetScroll_!: SpecificEventListener<'scroll'>; // assigned in initialSyncWithDOM()
private navIcon_!: Element | null;
private iconRipples_!: MDCRipple[];
private scrollTarget_!: EventTarget;
Expand All @@ -57,19 +61,52 @@ export class MDCTopAppBar extends MDCComponent<MDCTopAppBarBaseFoundation> {
this.scrollTarget_ = window;
}

initialSyncWithDOM() {
this.handleNavigationClick_ = this.foundation_.handleNavigationClick.bind(this.foundation_);
this.handleWindowResize_ = this.foundation_.handleWindowResize.bind(this.foundation_);
this.handleTargetScroll_ = this.foundation_.handleTargetScroll.bind(this.foundation_);

this.scrollTarget_.addEventListener('scroll', this.handleTargetScroll_ as EventListener);

if (this.navIcon_) {
this.navIcon_.addEventListener('click', this.handleNavigationClick_ as EventListener);
}

const isFixed = this.root_.classList.contains(cssClasses.FIXED_CLASS);
const isShort = this.root_.classList.contains(cssClasses.SHORT_CLASS);
if (!isShort && !isFixed) {
window.addEventListener('resize', this.handleWindowResize_ as EventListener);
}
}

destroy() {
this.iconRipples_.forEach((iconRipple) => iconRipple.destroy());
this.scrollTarget_.removeEventListener('scroll', this.handleTargetScroll_ as EventListener);
if (this.navIcon_) {
this.navIcon_.removeEventListener('click', this.handleNavigationClick_ as EventListener);
}
const isFixed = this.root_.classList.contains(cssClasses.FIXED_CLASS);
const isShort = this.root_.classList.contains(cssClasses.SHORT_CLASS);
if (!isShort && !isFixed) {
window.removeEventListener('resize', this.handleWindowResize_ as EventListener);
}
super.destroy();
}

setScrollTarget(target: EventTarget) {
// Remove scroll handler from the previous scroll target
this.foundation_.destroyScrollHandler();
if (this.handleTargetScroll_) {
this.scrollTarget_.removeEventListener('scroll', this.handleTargetScroll_ as EventListener);
}

this.scrollTarget_ = target;

// Initialize scroll handler on the new scroll target
this.foundation_.initScrollHandler();
if (this.handleTargetScroll_) {
this.handleTargetScroll_
= this.foundation_.handleTargetScroll && this.foundation_.handleTargetScroll.bind(this.foundation_);
this.scrollTarget_.addEventListener('scroll', this.handleTargetScroll_ as EventListener);
}
}

getDefaultFoundation() {
Expand All @@ -82,21 +119,7 @@ export class MDCTopAppBar extends MDCComponent<MDCTopAppBarBaseFoundation> {
removeClass: (className) => this.root_.classList.remove(className),
setStyle: (property, value) => (this.root_ as HTMLElement).style.setProperty(property, value),
getTopAppBarHeight: () => this.root_.clientHeight,
registerNavigationIconInteractionHandler: (evtType, handler) => {
if (this.navIcon_) {
this.navIcon_.addEventListener(evtType, handler);
}
},
deregisterNavigationIconInteractionHandler: (evtType, handler) => {
if (this.navIcon_) {
this.navIcon_.removeEventListener(evtType, handler);
}
},
notifyNavigationIconClicked: () => this.emit(strings.NAVIGATION_EVENT, {}),
registerScrollHandler: (handler) => this.scrollTarget_.addEventListener('scroll', handler as EventListener),
deregisterScrollHandler: (handler) => this.scrollTarget_.removeEventListener('scroll', handler as EventListener),
registerResizeHandler: (handler) => window.addEventListener('resize', handler),
deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler),
getViewportScrollY: () => {
const win = this.scrollTarget_ as Window;
const el = this.scrollTarget_ as Element;
Expand Down
10 changes: 1 addition & 9 deletions packages/mdc-top-app-bar/fixed/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
* THE SOFTWARE.
*/

import {MDCTopAppBarAdapter} from '../adapter';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the coverage score went down, can we aim to have 100% test coverage?

image

import {cssClasses} from '../constants';
import {MDCTopAppBarFoundation} from '../standard/foundation';

Expand All @@ -31,17 +30,10 @@ export class MDCFixedTopAppBarFoundation extends MDCTopAppBarFoundation {
*/
private wasScrolled_ = false;

/* istanbul ignore next: optional argument is not a branch statement */
constructor(adapter?: Partial<MDCTopAppBarAdapter>) {
super(adapter);

this.scrollHandler_ = () => this.fixedScrollHandler_();
}

/**
* Scroll handler for applying/removing the modifier class on the fixed top app bar.
*/
private fixedScrollHandler_() {
handleTargetScroll() {
const currentScroll = this.adapter_.getViewportScrollY();

if (currentScroll <= 0) {
Expand Down
50 changes: 4 additions & 46 deletions packages/mdc-top-app-bar/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
*/

import {MDCFoundation} from '@material/base/foundation';
import {SpecificEventListener} from '@material/base/types';
import {MDCTopAppBarAdapter} from './adapter';
import {cssClasses, numbers, strings} from './constants';

Expand Down Expand Up @@ -50,64 +49,23 @@ export class MDCTopAppBarBaseFoundation extends MDCFoundation<MDCTopAppBarAdapte
hasClass: () => false,
setStyle: () => undefined,
getTopAppBarHeight: () => 0,
registerNavigationIconInteractionHandler: () => undefined,
deregisterNavigationIconInteractionHandler: () => undefined,
notifyNavigationIconClicked: () => undefined,
registerScrollHandler: () => undefined,
deregisterScrollHandler: () => undefined,
registerResizeHandler: () => undefined,
deregisterResizeHandler: () => undefined,
getViewportScrollY: () => 0,
getTotalActionItems: () => 0,
};
// tslint:enable:object-literal-sort-keys
}

protected scrollHandler_?: SpecificEventListener<'scroll'>;
protected resizeHandler_?: SpecificEventListener<'resize'>;
private readonly navClickHandler_: SpecificEventListener<'click'>;

/* istanbul ignore next: optional argument is not a branch statement */
constructor(adapter?: Partial<MDCTopAppBarAdapter>) {
super({...MDCTopAppBarBaseFoundation.defaultAdapter, ...adapter});

this.navClickHandler_ = () => this.adapter_.notifyNavigationIconClicked();
}

init() {
this.initScrollHandler();
this.initResizeHandler_();
this.adapter_.registerNavigationIconInteractionHandler('click', this.navClickHandler_);
}

destroy() {
this.destroyScrollHandler();
this.destroyResizeHandler_();
this.adapter_.deregisterNavigationIconInteractionHandler('click', this.navClickHandler_);
}

initScrollHandler() {
if (this.scrollHandler_) {
this.adapter_.registerScrollHandler(this.scrollHandler_);
}
}

destroyScrollHandler() {
if (this.scrollHandler_) {
this.adapter_.deregisterScrollHandler(this.scrollHandler_);
}
}

private initResizeHandler_() {
if (this.resizeHandler_) {
this.adapter_.registerResizeHandler(this.resizeHandler_);
}
}
handleTargetScroll() {} // tslint:disable-line:no-empty
handleWindowResize() {} // tslint:disable-line:no-empty

private destroyResizeHandler_() {
if (this.resizeHandler_) {
this.adapter_.deregisterResizeHandler(this.resizeHandler_);
}
handleNavigationClick() {
this.adapter_.notifyNavigationIconClicked();
}
}

Expand Down
15 changes: 5 additions & 10 deletions packages/mdc-top-app-bar/short/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,16 @@ export class MDCShortTopAppBarFoundation extends MDCTopAppBarBaseFoundation {
this.adapter_.addClass(cssClasses.SHORT_HAS_ACTION_ITEM_CLASS);
}

if (!this.adapter_.hasClass(cssClasses.SHORT_COLLAPSED_CLASS)) {
this.scrollHandler_ = () => this.shortAppBarScrollHandler_();
this.adapter_.registerScrollHandler(this.scrollHandler_);
this.shortAppBarScrollHandler_();
}
}

destroy() {
super.destroy();
this.handleTargetScroll();
}

/**
* Scroll handler for applying/removing the collapsed modifier class on the short top app bar.
*/
private shortAppBarScrollHandler_() {
handleTargetScroll() {
if (this.adapter_.hasClass(cssClasses.SHORT_COLLAPSED_CLASS)) {
return;
}
const currentScroll = this.adapter_.getViewportScrollY();

if (currentScroll <= 0) {
Expand Down
Loading