1
- import { getComponentFromProp } from '../_util/props-util' ;
1
+ import { getComponentFromProp , initDefaultProps } from '../_util/props-util' ;
2
2
import KeyCode from '../_util/KeyCode' ;
3
3
import contains from '../_util/Dom/contains' ;
4
4
import LazyRenderBox from './LazyRenderBox' ;
5
5
import BaseMixin from '../_util/BaseMixin' ;
6
6
import getTransitionProps from '../_util/getTransitionProps' ;
7
- import getScrollBarSize from '../_util/getScrollBarSize ' ;
7
+ import switchScrollingEffect from '../_util/switchScrollingEffect ' ;
8
8
import getDialogPropTypes from './IDialogPropTypes' ;
9
9
const IDialogPropTypes = getDialogPropTypes ( ) ;
10
10
11
11
let uuid = 0 ;
12
- let openCount = 0 ;
13
12
14
13
/* eslint react/no-is-mounted:0 */
15
14
function noop ( ) { }
@@ -46,23 +45,19 @@ function offset(el) {
46
45
pos . top += getScroll ( w , true ) ;
47
46
return pos ;
48
47
}
49
- const initDefaultProps = ( propTypes , defaultProps ) => {
50
- return Object . keys ( defaultProps ) . map ( k => propTypes [ k ] . def ( defaultProps [ k ] ) ) ;
51
- } ;
48
+
52
49
export default {
53
50
mixins : [ BaseMixin ] ,
54
- props : {
55
- ...IDialogPropTypes ,
56
- ...initDefaultProps ( IDialogPropTypes , {
57
- mask : true ,
58
- visible : false ,
59
- keyboard : true ,
60
- closable : true ,
61
- maskClosable : true ,
62
- destroyOnClose : false ,
63
- prefixCls : 'rc-dialog' ,
64
- } ) ,
65
- } ,
51
+ props : initDefaultProps ( IDialogPropTypes , {
52
+ mask : true ,
53
+ visible : false ,
54
+ keyboard : true ,
55
+ closable : true ,
56
+ maskClosable : true ,
57
+ destroyOnClose : false ,
58
+ prefixCls : 'rc-dialog' ,
59
+ getOpenCount : ( ) => null ,
60
+ } ) ,
66
61
data ( ) {
67
62
return {
68
63
destroyPopup : false ,
@@ -97,12 +92,18 @@ export default {
97
92
mounted ( ) {
98
93
this . $nextTick ( ( ) => {
99
94
this . updatedCallback ( false ) ;
95
+ // if forceRender is true, set element style display to be none;
96
+ if ( ( this . forceRender || ( this . getContainer === false && ! this . visible ) ) && this . $refs . wrap ) {
97
+ this . $refs . wrap . style . display = 'none' ;
98
+ }
100
99
} ) ;
101
100
} ,
102
101
beforeDestroy ( ) {
103
- if ( this . visible || this . inTransition ) {
102
+ const { visible, getOpenCount } = this ;
103
+ if ( ( visible || this . inTransition ) && ! getOpenCount ( ) ) {
104
104
this . removeScrollingEffect ( ) ;
105
105
}
106
+ clearTimeout ( this . timeoutId ) ;
106
107
} ,
107
108
methods : {
108
109
updatedCallback ( visible ) {
@@ -160,12 +161,23 @@ export default {
160
161
afterClose ( ) ;
161
162
}
162
163
} ,
164
+ onDialogMouseDown ( ) {
165
+ this . dialogMouseDown = true ;
166
+ } ,
167
+
168
+ onMaskMouseUp ( ) {
169
+ if ( this . dialogMouseDown ) {
170
+ this . timeoutId = setTimeout ( ( ) => {
171
+ this . dialogMouseDown = false ;
172
+ } , 0 ) ;
173
+ }
174
+ } ,
163
175
onMaskClick ( e ) {
164
176
// android trigger click on open (fastclick??)
165
177
if ( Date . now ( ) - this . openTime < 300 ) {
166
178
return ;
167
179
}
168
- if ( e . target === e . currentTarget ) {
180
+ if ( e . target === e . currentTarget && ! this . dialogMouseDown ) {
169
181
this . close ( e ) ;
170
182
}
171
183
} ,
@@ -236,6 +248,7 @@ export default {
236
248
const closeIcon = getComponentFromProp ( this , 'closeIcon' ) ;
237
249
closer = (
238
250
< button
251
+ type = "button"
239
252
key = "close"
240
253
onClick = { this . close || noop }
241
254
aria-label = "Close"
@@ -261,10 +274,9 @@ export default {
261
274
ref = "dialog"
262
275
style = { style }
263
276
class = { cls }
277
+ onMousedown = { this . onDialogMouseDown }
264
278
>
265
- < div tabIndex = { 0 } ref = "sentinelStart" style = { sentinelStyle } >
266
- sentinelStart
267
- </ div >
279
+ < div tabIndex = { 0 } ref = "sentinelStart" style = { sentinelStyle } aria-hidden = "true" />
268
280
< div class = { `${ prefixCls } -content` } >
269
281
{ closer }
270
282
{ header }
@@ -273,9 +285,7 @@ export default {
273
285
</ div >
274
286
{ footer }
275
287
</ div >
276
- < div tabIndex = { 0 } ref = "sentinelEnd" style = { sentinelStyle } >
277
- sentinelEnd
278
- </ div >
288
+ < div tabIndex = { 0 } ref = "sentinelEnd" style = { sentinelStyle } aria-hidden = "true" />
279
289
</ LazyRenderBox >
280
290
) ;
281
291
const dialogTransitionProps = getTransitionProps ( transitionName , {
@@ -344,65 +354,65 @@ export default {
344
354
}
345
355
return transitionName ;
346
356
} ,
347
- setScrollbar ( ) {
348
- if ( this . bodyIsOverflowing && this . scrollbarWidth !== undefined ) {
349
- document . body . style . paddingRight = `${ this . scrollbarWidth } px` ;
350
- }
351
- } ,
357
+ // setScrollbar() {
358
+ // if (this.bodyIsOverflowing && this.scrollbarWidth !== undefined) {
359
+ // document.body.style.paddingRight = `${this.scrollbarWidth}px`;
360
+ // }
361
+ // },
352
362
addScrollingEffect ( ) {
353
- openCount ++ ;
363
+ const { getOpenCount } = this ;
364
+ const openCount = getOpenCount ( ) ;
354
365
if ( openCount !== 1 ) {
355
366
return ;
356
367
}
357
- this . checkScrollbar ( ) ;
358
- this . setScrollbar ( ) ;
368
+ switchScrollingEffect ( ) ;
359
369
document . body . style . overflow = 'hidden' ;
360
- // this.adjustDialog();
361
370
} ,
362
371
removeScrollingEffect ( ) {
363
- openCount -- ;
372
+ const { getOpenCount } = this ;
373
+ const openCount = getOpenCount ( ) ;
364
374
if ( openCount !== 0 ) {
365
375
return ;
366
376
}
367
377
document . body . style . overflow = '' ;
368
- this . resetScrollbar ( ) ;
378
+ switchScrollingEffect ( true ) ;
369
379
// this.resetAdjustments();
370
380
} ,
371
381
close ( e ) {
372
382
this . __emit ( 'close' , e ) ;
373
383
} ,
374
- checkScrollbar ( ) {
375
- let fullWindowWidth = window . innerWidth ;
376
- if ( ! fullWindowWidth ) {
377
- // workaround for missing window.innerWidth in IE8
378
- const documentElementRect = document . documentElement . getBoundingClientRect ( ) ;
379
- fullWindowWidth = documentElementRect . right - Math . abs ( documentElementRect . left ) ;
380
- }
381
- this . bodyIsOverflowing = document . body . clientWidth < fullWindowWidth ;
382
- if ( this . bodyIsOverflowing ) {
383
- this . scrollbarWidth = getScrollBarSize ( ) ;
384
- }
385
- } ,
386
- resetScrollbar ( ) {
387
- document . body . style . paddingRight = '' ;
388
- } ,
389
- adjustDialog ( ) {
390
- if ( this . $refs . wrap && this . scrollbarWidth !== undefined ) {
391
- const modalIsOverflowing =
392
- this . $refs . wrap . scrollHeight > document . documentElement . clientHeight ;
393
- this . $refs . wrap . style . paddingLeft = `${
394
- ! this . bodyIsOverflowing && modalIsOverflowing ? this . scrollbarWidth : ''
395
- } px`;
396
- this . $refs . wrap . style . paddingRight = `${
397
- this . bodyIsOverflowing && ! modalIsOverflowing ? this . scrollbarWidth : ''
398
- } px`;
399
- }
400
- } ,
401
- resetAdjustments ( ) {
402
- if ( this . $refs . wrap ) {
403
- this . $refs . wrap . style . paddingLeft = this . $refs . wrap . style . paddingLeft = '' ;
404
- }
405
- } ,
384
+ // checkScrollbar() {
385
+ // let fullWindowWidth = window.innerWidth;
386
+ // if (!fullWindowWidth) {
387
+ // // workaround for missing window.innerWidth in IE8
388
+ // const documentElementRect = document.documentElement.getBoundingClientRect();
389
+ // fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
390
+ // }
391
+ // this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
392
+ // if (this.bodyIsOverflowing) {
393
+ // this.scrollbarWidth = getScrollBarSize();
394
+ // }
395
+ // },
396
+ // resetScrollbar() {
397
+ // document.body.style.paddingRight = '';
398
+ // },
399
+ // adjustDialog() {
400
+ // if (this.$refs.wrap && this.scrollbarWidth !== undefined) {
401
+ // const modalIsOverflowing =
402
+ // this.$refs.wrap.scrollHeight > document.documentElement.clientHeight;
403
+ // this.$refs.wrap.style.paddingLeft = `${
404
+ // !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : ''
405
+ // }px`;
406
+ // this.$refs.wrap.style.paddingRight = `${
407
+ // this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
408
+ // }px`;
409
+ // }
410
+ // },
411
+ // resetAdjustments() {
412
+ // if (this.$refs.wrap) {
413
+ // this.$refs.wrap.style.paddingLeft = this.$refs.wrap.style.paddingLeft = '';
414
+ // }
415
+ // },
406
416
} ,
407
417
render ( ) {
408
418
const { prefixCls, maskClosable, visible, wrapClassName, title, wrapProps } = this ;
@@ -421,6 +431,7 @@ export default {
421
431
class = { `${ prefixCls } -wrap ${ wrapClassName || '' } ` }
422
432
ref = "wrap"
423
433
onClick = { maskClosable ? this . onMaskClick : noop }
434
+ onMouseup = { maskClosable ? this . onMaskMouseUp : noop }
424
435
role = "dialog"
425
436
aria-labelledby = { title ? this . titleId : null }
426
437
style = { style }
0 commit comments