Skip to content

Commit e52ef83

Browse files
committed
fix: Check passive support cause memo leak
fix ant-design/ant-design#20903
1 parent 02f8f8d commit e52ef83

File tree

2 files changed

+112
-56
lines changed

2 files changed

+112
-56
lines changed

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"endOfLine": "lf",
3+
"semi": true,
4+
"singleQuote": true,
5+
"tabWidth": 2,
6+
"trailingComma": "all"
7+
}

src/DrawerChild.tsx

Lines changed: 105 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ interface IState {
3030
class DrawerChild extends React.Component<IDrawerChildProps, IState> {
3131
static defaultProps = {
3232
switchScrollingEffect: () => {},
33-
}
33+
};
3434

35-
public static getDerivedStateFromProps(props: IDrawerChildProps,
36-
{ prevProps, _self }: { prevProps: IDrawerChildProps, _self: DrawerChild }) {
35+
public static getDerivedStateFromProps(
36+
props: IDrawerChildProps,
37+
{ prevProps, _self }: { prevProps: IDrawerChildProps; _self: DrawerChild },
38+
) {
3739
const nextState = {
3840
prevProps: props,
3941
};
@@ -69,8 +71,8 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
6971
private passive: { passive: boolean } | boolean;
7072

7173
private startPos: {
72-
x: number,
73-
y: number,
74+
x: number;
75+
y: number;
7476
};
7577

7678
constructor(props: IDrawerChildProps) {
@@ -83,24 +85,26 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
8385
public componentDidMount() {
8486
if (!windowIsUndefined) {
8587
let passiveSupported = false;
86-
window.addEventListener(
87-
'test',
88-
() => { },
89-
Object.defineProperty({}, 'passive', {
90-
get: () => {
91-
passiveSupported = true;
92-
return null;
93-
},
94-
}),
95-
);
88+
try {
89+
window.addEventListener(
90+
'test',
91+
null,
92+
Object.defineProperty({}, 'passive', {
93+
get: () => {
94+
passiveSupported = true;
95+
return null;
96+
},
97+
}),
98+
);
99+
} catch (err) {}
96100
this.passive = passiveSupported ? { passive: false } : false;
97101
}
98102
const { open } = this.props;
99-
this.drawerId = `drawer_id_${
100-
Number(
101-
(Date.now() + Math.random()).toString().replace('.', Math.round(Math.random() * 9).toString()),
102-
).toString(16)
103-
}`;
103+
this.drawerId = `drawer_id_${Number(
104+
(Date.now() + Math.random())
105+
.toString()
106+
.replace('.', Math.round(Math.random() * 9).toString()),
107+
).toString(16)}`;
104108
this.getLevelDom(this.props);
105109
if (open) {
106110
currentDrawer[this.drawerId] = open;
@@ -125,7 +129,7 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
125129

126130
public componentWillUnmount() {
127131
const { getOpenCount, open, switchScrollingEffect } = this.props;
128-
const openCount = typeof getOpenCount === 'function' && getOpenCount()
132+
const openCount = typeof getOpenCount === 'function' && getOpenCount();
129133
delete currentDrawer[this.drawerId];
130134
if (open) {
131135
this.setLevelTransform(false);
@@ -141,7 +145,7 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
141145
if (this.dom) {
142146
this.dom.focus();
143147
}
144-
}
148+
};
145149

146150
private removeStartHandler = (e: React.TouchEvent | TouchEvent) => {
147151
if (e.touches.length > 1) {
@@ -151,7 +155,7 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
151155
x: e.touches[0].clientX,
152156
y: e.touches[0].clientY,
153157
};
154-
}
158+
};
155159

156160
private removeMoveHandler = (e: React.TouchEvent | TouchEvent) => {
157161
if (e.changedTouches.length > 1) {
@@ -164,17 +168,22 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
164168
currentTarget === this.maskDom ||
165169
currentTarget === this.handlerDom ||
166170
(currentTarget === this.contentDom &&
167-
getTouchParentScroll(currentTarget, e.target as HTMLElement, differX, differY))
171+
getTouchParentScroll(
172+
currentTarget,
173+
e.target as HTMLElement,
174+
differX,
175+
differY,
176+
))
168177
) {
169178
e.preventDefault();
170179
}
171-
}
180+
};
172181

173182
private transitionEnd = (e: TransitionEvent) => {
174183
const dom: HTMLElement = e.target as HTMLElement;
175184
removeEventListener(dom, transitionEnd, this.transitionEnd);
176185
dom.style.transition = '';
177-
}
186+
};
178187

179188
private onKeyDown = (e: React.KeyboardEvent) => {
180189
if (e.keyCode === KeyCode.ESC) {
@@ -184,11 +193,14 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
184193
onClose(e as any);
185194
}
186195
}
187-
}
196+
};
188197

189198
private onWrapperTransitionEnd = (e: React.TransitionEvent) => {
190199
const { open, afterVisibleChange } = this.props;
191-
if (e.target === this.contentWrapper && e.propertyName.match(/transform$/)) {
200+
if (
201+
e.target === this.contentWrapper &&
202+
e.propertyName.match(/transform$/)
203+
) {
192204
this.dom.style.transition = '';
193205
if (!open && this.getCurrentDrawerSome()) {
194206
document.body.style.overflowX = '';
@@ -201,17 +213,22 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
201213
afterVisibleChange(!!open);
202214
}
203215
}
204-
}
216+
};
205217

206218
private openLevelTransition = () => {
207219
const { open, width, height } = this.props;
208-
const { isHorizontal, placementName } = this.getHorizontalBoolAndPlacementName();
220+
const {
221+
isHorizontal,
222+
placementName,
223+
} = this.getHorizontalBoolAndPlacementName();
209224
const contentValue = this.contentDom
210-
? this.contentDom.getBoundingClientRect()[isHorizontal ? 'width' : 'height']
225+
? this.contentDom.getBoundingClientRect()[
226+
isHorizontal ? 'width' : 'height'
227+
]
211228
: 0;
212229
const value = (isHorizontal ? width : height) || contentValue;
213230
this.setLevelAndScrolling(open, placementName, value);
214-
}
231+
};
215232

216233
private setLevelTransform = (
217234
open?: boolean,
@@ -229,13 +246,19 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
229246
const $levelMove = transformArguments(levelMove, { target: dom, open });
230247
levelValue = open ? $levelMove[0] : $levelMove[1] || 0;
231248
}
232-
const $value = typeof levelValue === 'number' ? `${levelValue}px` : levelValue;
233-
let placementPos = placement === 'left' || placement === 'top' ? $value : `-${$value}`;
234-
placementPos = showMask && placement === 'right' && right ?
235-
`calc(${placementPos} + ${right}px)` : placementPos;
236-
dom.style.transform = levelValue ? `${placementName}(${placementPos})` : '';
249+
const $value =
250+
typeof levelValue === 'number' ? `${levelValue}px` : levelValue;
251+
let placementPos =
252+
placement === 'left' || placement === 'top' ? $value : `-${$value}`;
253+
placementPos =
254+
showMask && placement === 'right' && right
255+
? `calc(${placementPos} + ${right}px)`
256+
: placementPos;
257+
dom.style.transform = levelValue
258+
? `${placementName}(${placementPos})`
259+
: '';
237260
});
238-
}
261+
};
239262

240263
private setLevelAndScrolling = (
241264
open?: boolean,
@@ -244,16 +267,19 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
244267
) => {
245268
const { onChange } = this.props;
246269
if (!windowIsUndefined) {
247-
const right = document.body.scrollHeight >
248-
(window.innerHeight || document.documentElement.clientHeight) &&
249-
window.innerWidth > document.body.offsetWidth ? getScrollBarSize(true) : 0;
270+
const right =
271+
document.body.scrollHeight >
272+
(window.innerHeight || document.documentElement.clientHeight) &&
273+
window.innerWidth > document.body.offsetWidth
274+
? getScrollBarSize(true)
275+
: 0;
250276
this.setLevelTransform(open, placementName, value, right);
251277
this.toggleScrollingToDrawerAndBody(right);
252278
}
253279
if (onChange) {
254280
onChange(open);
255281
}
256-
}
282+
};
257283

258284
private toggleScrollingToDrawerAndBody = (right: number) => {
259285
const { getOpenCount, getContainer, showMask, open } = this.props;
@@ -262,7 +288,12 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
262288
// 处理 body 滚动
263289
if (container && container.parentNode === document.body && showMask) {
264290
const eventArray = ['touchstart'];
265-
const domArray = [document.body, this.maskDom, this.handlerDom, this.contentDom];
291+
const domArray = [
292+
document.body,
293+
this.maskDom,
294+
this.handlerDom,
295+
this.contentDom,
296+
];
266297
if (open && document.body.style.overflow !== 'hidden') {
267298
if (right) {
268299
this.addScrollingEffect(right);
@@ -306,10 +337,16 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
306337
});
307338
}
308339
}
309-
}
340+
};
310341

311342
private addScrollingEffect = (right: number) => {
312-
const { placement, duration, ease, getOpenCount, switchScrollingEffect } = this.props;
343+
const {
344+
placement,
345+
duration,
346+
ease,
347+
getOpenCount,
348+
switchScrollingEffect,
349+
} = this.props;
313350
const openCount = getOpenCount && getOpenCount();
314351
if (openCount === 1) {
315352
switchScrollingEffect();
@@ -337,10 +374,16 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
337374
this.dom.style.transform = '';
338375
}
339376
});
340-
}
377+
};
341378

342379
private remScrollingEffect = (right: number) => {
343-
const { placement, duration, ease, getOpenCount, switchScrollingEffect } = this.props;
380+
const {
381+
placement,
382+
duration,
383+
ease,
384+
getOpenCount,
385+
switchScrollingEffect,
386+
} = this.props;
344387
const openCount = getOpenCount && getOpenCount();
345388
if (!openCount) {
346389
switchScrollingEffect(true);
@@ -384,25 +427,28 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
384427
if (this.dom) {
385428
this.dom.style.transition = `${transformTransition},${
386429
heightTransition ? `${heightTransition},` : ''
387-
}${widthTransition}`;
430+
}${widthTransition}`;
388431
this.dom.style.transform = '';
389432
this.dom.style.width = '';
390433
this.dom.style.height = '';
391434
}
392435
});
393-
}
436+
};
394437

395-
private getCurrentDrawerSome = () => !Object.keys(currentDrawer).some(key => currentDrawer[key]);
438+
private getCurrentDrawerSome = () =>
439+
!Object.keys(currentDrawer).some(key => currentDrawer[key]);
396440

397441
private getLevelDom = ({ level, getContainer }: IDrawerChildProps) => {
398442
if (windowIsUndefined) {
399443
return;
400444
}
401445
const container = getContainer && getContainer();
402-
const parent = container ? container.parentNode as HTMLElement : null;
446+
const parent = container ? (container.parentNode as HTMLElement) : null;
403447
this.levelDom = [];
404448
if (level === 'all') {
405-
const children: HTMLElement[] = parent ? Array.prototype.slice.call(parent.children) : [];
449+
const children: HTMLElement[] = parent
450+
? Array.prototype.slice.call(parent.children)
451+
: [];
406452
children.forEach((child: HTMLElement) => {
407453
if (
408454
child.nodeName !== 'SCRIPT' &&
@@ -420,7 +466,7 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
420466
});
421467
});
422468
}
423-
}
469+
};
424470

425471
private getHorizontalBoolAndPlacementName = () => {
426472
const { placement } = this.props;
@@ -430,7 +476,7 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
430476
isHorizontal,
431477
placementName,
432478
};
433-
}
479+
};
434480

435481
// tslint:disable-next-line:member-ordering
436482
public render() {
@@ -474,7 +520,8 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
474520
const { placementName } = this.getHorizontalBoolAndPlacementName();
475521
// 百分比与像素动画不同步,第一次打用后全用像素动画。
476522
// const defaultValue = !this.contentDom || !level ? '100%' : `${value}px`;
477-
const placementPos = placement === 'left' || placement === 'top' ? '-100%' : '100%';
523+
const placementPos =
524+
placement === 'left' || placement === 'top' ? '-100%' : '100%';
478525
const transform = open ? '' : `${placementName}(${placementPos})`;
479526

480527
const handlerChildren =
@@ -531,7 +578,9 @@ class DrawerChild extends React.Component<IDrawerChildProps, IState> {
531578
ref={c => {
532579
this.contentDom = c as HTMLElement;
533580
}}
534-
onTouchStart={open && showMask ? this.removeStartHandler : undefined} // 跑用例用
581+
onTouchStart={
582+
open && showMask ? this.removeStartHandler : undefined
583+
} // 跑用例用
535584
onTouchMove={open && showMask ? this.removeMoveHandler : undefined} // 跑用例用
536585
>
537586
{children}

0 commit comments

Comments
 (0)