Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80536 views
1
/**
2
* Copyright 2013-2015, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule EnterLeaveEventPlugin
10
* @typechecks static-only
11
*/
12
13
'use strict';
14
15
var EventConstants = require("./EventConstants");
16
var EventPropagators = require("./EventPropagators");
17
var SyntheticMouseEvent = require("./SyntheticMouseEvent");
18
19
var ReactMount = require("./ReactMount");
20
var keyOf = require("./keyOf");
21
22
var topLevelTypes = EventConstants.topLevelTypes;
23
var getFirstReactDOM = ReactMount.getFirstReactDOM;
24
25
var eventTypes = {
26
mouseEnter: {
27
registrationName: keyOf({onMouseEnter: null}),
28
dependencies: [
29
topLevelTypes.topMouseOut,
30
topLevelTypes.topMouseOver
31
]
32
},
33
mouseLeave: {
34
registrationName: keyOf({onMouseLeave: null}),
35
dependencies: [
36
topLevelTypes.topMouseOut,
37
topLevelTypes.topMouseOver
38
]
39
}
40
};
41
42
var extractedEvents = [null, null];
43
44
var EnterLeaveEventPlugin = {
45
46
eventTypes: eventTypes,
47
48
/**
49
* For almost every interaction we care about, there will be both a top-level
50
* `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
51
* we do not extract duplicate events. However, moving the mouse into the
52
* browser from outside will not fire a `mouseout` event. In this case, we use
53
* the `mouseover` top-level event.
54
*
55
* @param {string} topLevelType Record from `EventConstants`.
56
* @param {DOMEventTarget} topLevelTarget The listening component root node.
57
* @param {string} topLevelTargetID ID of `topLevelTarget`.
58
* @param {object} nativeEvent Native browser event.
59
* @return {*} An accumulation of synthetic events.
60
* @see {EventPluginHub.extractEvents}
61
*/
62
extractEvents: function(
63
topLevelType,
64
topLevelTarget,
65
topLevelTargetID,
66
nativeEvent) {
67
if (topLevelType === topLevelTypes.topMouseOver &&
68
(nativeEvent.relatedTarget || nativeEvent.fromElement)) {
69
return null;
70
}
71
if (topLevelType !== topLevelTypes.topMouseOut &&
72
topLevelType !== topLevelTypes.topMouseOver) {
73
// Must not be a mouse in or mouse out - ignoring.
74
return null;
75
}
76
77
var win;
78
if (topLevelTarget.window === topLevelTarget) {
79
// `topLevelTarget` is probably a window object.
80
win = topLevelTarget;
81
} else {
82
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
83
var doc = topLevelTarget.ownerDocument;
84
if (doc) {
85
win = doc.defaultView || doc.parentWindow;
86
} else {
87
win = window;
88
}
89
}
90
91
var from, to;
92
if (topLevelType === topLevelTypes.topMouseOut) {
93
from = topLevelTarget;
94
to =
95
getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) ||
96
win;
97
} else {
98
from = win;
99
to = topLevelTarget;
100
}
101
102
if (from === to) {
103
// Nothing pertains to our managed components.
104
return null;
105
}
106
107
var fromID = from ? ReactMount.getID(from) : '';
108
var toID = to ? ReactMount.getID(to) : '';
109
110
var leave = SyntheticMouseEvent.getPooled(
111
eventTypes.mouseLeave,
112
fromID,
113
nativeEvent
114
);
115
leave.type = 'mouseleave';
116
leave.target = from;
117
leave.relatedTarget = to;
118
119
var enter = SyntheticMouseEvent.getPooled(
120
eventTypes.mouseEnter,
121
toID,
122
nativeEvent
123
);
124
enter.type = 'mouseenter';
125
enter.target = to;
126
enter.relatedTarget = from;
127
128
EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);
129
130
extractedEvents[0] = leave;
131
extractedEvents[1] = enter;
132
133
return extractedEvents;
134
}
135
136
};
137
138
module.exports = EnterLeaveEventPlugin;
139
140