Skip to content

Commit b219820

Browse files
authored
Merge pull request #165 from mike-north/typescript
Typescript
2 parents 518c73b + 119266f commit b219820

File tree

23 files changed

+956
-622
lines changed

23 files changed

+956
-622
lines changed

.eslintrc.js

Lines changed: 0 additions & 51 deletions
This file was deleted.

.vscode/settings.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
{
2-
"javascript.implicitProjectConfig.checkJs": true
3-
}
2+
"javascript.implicitProjectConfig.checkJs": true,
3+
"eslint.validate": [
4+
"javascript",
5+
"typescript"
6+
]
7+
}
Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,55 @@
1-
import Mixin from '@ember/object/mixin';
21
import { readOnly } from '@ember/object/computed';
2+
import Mixin from '@ember/object/mixin';
3+
import ResizeService from 'dummy/services/resize';
34
const { floor } = Math;
45

5-
export default Mixin.create({
6-
resizeEventsEnabled: true,
6+
// tslint:disable-next-line:variable-name
7+
const ResizeAwareMixin = Mixin.create({
78
resizeDebouncedEventsEnabled: true,
9+
resizeEventsEnabled: true,
810

9-
screenWidth: readOnly('resizeService.screenWidth'),
1011
screenHeight: readOnly('resizeService.screenHeight'),
12+
screenWidth: readOnly('resizeService.screenWidth'),
1113

12-
_oldViewWidth: null,
13-
_oldViewHeight: null,
14-
_oldViewWidthDebounced: null,
15-
_oldViewHeightDebounced: null,
16-
resizeWidthSensitive: true,
14+
_oldViewHeight: null as number | null,
15+
_oldViewHeightDebounced: null as number | null,
16+
_oldViewWidth: null as number | null,
17+
_oldViewWidthDebounced: null as number | null,
1718
resizeHeightSensitive: true,
19+
resizeWidthSensitive: true,
1820

1921
didInsertElement() {
2022
this._super(...arguments);
23+
const resizeService: ResizeService = (this as any).get('resizeService');
2124
if (this.get('resizeEventsEnabled')) {
22-
this.get('resizeService').on('didResize', this, this._handleResizeEvent);
25+
resizeService.on('didResize', this, this._handleResizeEvent);
2326
}
2427
if (this.get('resizeDebouncedEventsEnabled')) {
25-
this.get('resizeService').on('debouncedDidResize', this, this._handleDebouncedResizeEvent);
28+
resizeService.on('debouncedDidResize', this, this._handleDebouncedResizeEvent);
2629
}
2730
},
2831

2932
willDestroyElement() {
3033
this._super(...arguments);
34+
const resizeService: ResizeService = (this as any).get('resizeService');
3135
if (this.get('resizeEventsEnabled')) {
32-
this.get('resizeService').off('didResize', this, this._handleResizeEvent);
36+
resizeService.off('didResize', this, this._handleResizeEvent);
3337
}
3438
if (this.get('resizeDebouncedEventsEnabled')) {
35-
this.get('resizeService').off('debouncedDidResize', this, this._handleDebouncedResizeEvent);
39+
resizeService.off('debouncedDidResize', this, this._handleDebouncedResizeEvent);
3640
}
3741
},
3842

39-
didResize(/*width, height, evt*/) {}, // Overridden in subclass
40-
debouncedDidResize(/*width, height, evt*/) {}, // Overridden in subclass
43+
// tslint:disable-next-line:no-empty
44+
didResize(_width: number, _height: number, _evt: UIEvent) {}, // Overridden in subclass
45+
// tslint:disable-next-line:no-empty
46+
debouncedDidResize(_width: number, _height: number, _evt: UIEvent) {}, // Overridden in subclass
4147

42-
_getComponentSize() {
48+
_getComponentSize(this: any) {
4349
return this.element.getClientRects()[0];
4450
},
4551

46-
_handleResizeEvent(evt) {
52+
_handleResizeEvent(evt: UIEvent) {
4753
const w = floor(this._getComponentSize().width);
4854
const h = floor(this._getComponentSize().height);
4955
if (
@@ -52,13 +58,13 @@ export default Mixin.create({
5258
) {
5359
this.didResize(w, h, evt);
5460
this.setProperties({
61+
_oldViewHeight: h,
5562
_oldViewWidth: w,
56-
_oldViewHeight: h
5763
});
5864
}
5965
},
6066

61-
_handleDebouncedResizeEvent(evt) {
67+
_handleDebouncedResizeEvent(evt: UIEvent) {
6268
const w = floor(this._getComponentSize().width);
6369
const h = floor(this._getComponentSize().height);
6470
if (
@@ -67,9 +73,11 @@ export default Mixin.create({
6773
) {
6874
this.debouncedDidResize(w, h, evt);
6975
this.setProperties({
76+
_oldViewHeightDebounced: h,
7077
_oldViewWidthDebounced: w,
71-
_oldViewHeightDebounced: h
7278
});
7379
}
74-
}
80+
},
7581
});
82+
83+
export default ResizeAwareMixin;

addon/services/resize.js

Lines changed: 0 additions & 98 deletions
This file was deleted.

addon/services/resize.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { oneWay, readOnly } from '@ember-decorators/object/computed';
2+
import { getWithDefault, set } from '@ember/object';
3+
import Evented from '@ember/object/evented';
4+
import { cancel, debounce } from '@ember/runloop';
5+
import Service from '@ember/service';
6+
import { classify } from '@ember/string';
7+
8+
declare global {
9+
// tslint:disable-next-line:variable-name
10+
const FastBoot: {} | undefined;
11+
}
12+
13+
export interface ResizeDefaults {
14+
widthSensitive?: boolean;
15+
heightSensitive?: boolean;
16+
debounceTimeout?: number ;
17+
injectionFactories?: string[];
18+
}
19+
20+
class ResizeService extends Service.extend(Evented) {
21+
public _oldWidth = window.innerWidth;
22+
public _oldHeight = window.innerHeight;
23+
public _oldWidthDebounced = window.innerWidth;
24+
public _oldHeightDebounced = window.innerHeight;
25+
26+
@oneWay('defaultDebounceTimeout') public debounceTimeout!: number;
27+
@oneWay('defaultWidthSensitive') public widthSensitive!: boolean;
28+
@oneWay('defaultHeightSensitive') public heightSensitive!: boolean;
29+
30+
public resizeServiceDefaults!: ResizeDefaults;
31+
32+
@readOnly('_oldWidth') public screenWidth!: number;
33+
@readOnly('_oldHeight') public screenHeight!: number;
34+
public _onResizeHandler?: (this: Window, evt: UIEvent) => void;
35+
public _scheduledDebounce?: ReturnType<typeof debounce>;
36+
constructor() {
37+
super(...arguments);
38+
this._setDefaults();
39+
this._onResizeHandler = (evt) => {
40+
this._fireResizeNotification(evt);
41+
const scheduledDebounce = debounce(this, this._fireDebouncedResizeNotification, evt, this.get('debounceTimeout'));
42+
this._scheduledDebounce = scheduledDebounce;
43+
};
44+
if (typeof FastBoot === 'undefined') {
45+
this._installResizeListener();
46+
}
47+
}
48+
49+
public destroy() {
50+
this._super(...arguments);
51+
if (typeof FastBoot === 'undefined') {
52+
this._uninstallResizeListener();
53+
}
54+
this._cancelScheduledDebounce();
55+
return this;
56+
}
57+
58+
public _setDefaults() {
59+
const defaults = getWithDefault(this, 'resizeServiceDefaults', {});
60+
61+
Object.keys(defaults).map((key: keyof ResizeDefaults ) => {
62+
const classifiedKey = classify(key);
63+
const defaultKey = `default${classifiedKey}`;
64+
return set(this as any, defaultKey, defaults[key]);
65+
});
66+
}
67+
68+
public _hasWindowSizeChanged(w: number, h: number, debounced = false) {
69+
const wKey = debounced ? '_oldWidthDebounced' : '_oldWidth';
70+
const hKey = debounced ? '_oldHeightDebounced' : '_oldHeight';
71+
return (
72+
(this.get('widthSensitive') && w !== this.get(wKey)) ||
73+
(this.get('heightSensitive') && h !== this.get(hKey))
74+
);
75+
}
76+
77+
public _updateCachedWindowSize(w: number, h: number, debounced = false) {
78+
const wKey = debounced ? '_oldWidthDebounced' : '_oldWidth';
79+
const hKey = debounced ? '_oldHeightDebounced' : '_oldHeight';
80+
this.set(wKey, w);
81+
this.set(hKey, h);
82+
}
83+
84+
public _installResizeListener() {
85+
if (!this._onResizeHandler) { return; }
86+
window.addEventListener('resize', this._onResizeHandler);
87+
}
88+
89+
public _uninstallResizeListener() {
90+
if (!this._onResizeHandler) { return; }
91+
window.removeEventListener('resize', this._onResizeHandler);
92+
}
93+
94+
public _cancelScheduledDebounce() {
95+
if (!this._scheduledDebounce) { return; }
96+
cancel(this._scheduledDebounce);
97+
}
98+
99+
public _fireResizeNotification(evt: UIEvent) {
100+
const { innerWidth, innerHeight } = window;
101+
if (this._hasWindowSizeChanged(innerWidth, innerHeight)) {
102+
this.trigger('didResize', evt);
103+
this._updateCachedWindowSize(innerWidth, innerHeight);
104+
}
105+
}
106+
public _fireDebouncedResizeNotification(evt: UIEvent) {
107+
const { innerWidth, innerHeight } = window;
108+
if (this._hasWindowSizeChanged(innerWidth, innerHeight, true)) {
109+
this.trigger('debouncedDidResize', evt);
110+
this._updateCachedWindowSize(innerWidth, innerHeight, true);
111+
}
112+
}
113+
}
114+
115+
export default ResizeService;

app/config/environment.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { ResizeDefaults } from 'ember-resize/services/resize';
2+
3+
interface IEnvironment {
4+
resizeServiceDefaults: ResizeDefaults;
5+
}
6+
declare const env: IEnvironment;
7+
export = env;

0 commit comments

Comments
 (0)