Merge pull request #4370 from blainekasten/video-events

Add Video/Audio Media Events
This commit is contained in:
Jim
2015-07-29 21:57:25 -07:00
5 changed files with 318 additions and 39 deletions

View File

@@ -195,3 +195,11 @@ Number deltaX
Number deltaY
Number deltaZ
```
### Media Events
Event names:
```
onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting
```

View File

@@ -84,7 +84,10 @@ var reactTopListenersCounter = 0;
// lower node than `document`), binding at `document` would cause duplicate
// events so we don't include them here
var topEventMapping = {
topAbort: 'abort',
topBlur: 'blur',
topCanPlay: 'canplay',
topCanPlayThrough: 'canplaythrough',
topChange: 'change',
topClick: 'click',
topCompositionEnd: 'compositionend',
@@ -102,24 +105,44 @@ var topEventMapping = {
topDragOver: 'dragover',
topDragStart: 'dragstart',
topDrop: 'drop',
topDurationChange: 'durationchange',
topEmptied: 'emptied',
topEnded: 'ended',
topError: 'error',
topFocus: 'focus',
topInput: 'input',
topKeyDown: 'keydown',
topKeyPress: 'keypress',
topKeyUp: 'keyup',
topLoadedData: 'loadeddata',
topLoadedMetadata: 'loadedmetadata',
topLoadStart: 'loadstart',
topMouseDown: 'mousedown',
topMouseMove: 'mousemove',
topMouseOut: 'mouseout',
topMouseOver: 'mouseover',
topMouseUp: 'mouseup',
topOnEncrypted: 'onencrypted',
topPause: 'pause',
topPaste: 'paste',
topPlay: 'play',
topPlaying: 'playing',
topProgress: 'progress',
topRateChange: 'ratechange',
topSeeking: 'seeking',
topSeeked: 'seeked',
topScroll: 'scroll',
topSelectionChange: 'selectionchange',
topStalled: 'stalled',
topSuspend: 'suspend',
topTextInput: 'textInput',
topTimeUpdate: 'timeupdate',
topTouchCancel: 'touchcancel',
topTouchEnd: 'touchend',
topTouchMove: 'touchmove',
topTouchStart: 'touchstart',
topVolumeChange: 'volumechange',
topWaiting: 'waiting',
topWheel: 'wheel',
};

View File

@@ -35,12 +35,30 @@ var warning = require('warning');
var topLevelTypes = EventConstants.topLevelTypes;
var eventTypes = {
abort: {
phasedRegistrationNames: {
bubbled: keyOf({onAbort: true}),
captured: keyOf({onAbortCapture: true}),
},
},
blur: {
phasedRegistrationNames: {
bubbled: keyOf({onBlur: true}),
captured: keyOf({onBlurCapture: true}),
},
},
canPlay: {
phasedRegistrationNames: {
bubbled: keyOf({onCanPlay: true}),
captured: keyOf({onCanPlayCapture: true}),
},
},
canPlayThrough: {
phasedRegistrationNames: {
bubbled: keyOf({onCanPlayThrough: true}),
captured: keyOf({onCanPlayThroughCapture: true}),
},
},
click: {
phasedRegistrationNames: {
bubbled: keyOf({onClick: true}),
@@ -119,6 +137,30 @@ var eventTypes = {
captured: keyOf({onDropCapture: true}),
},
},
durationChange: {
phasedRegistrationNames: {
bubbled: keyOf({onDurationChange: true}),
captured: keyOf({onDurationChangeCapture: true}),
},
},
emptied: {
phasedRegistrationNames: {
bubbled: keyOf({onEmptied: true}),
captured: keyOf({onEmptiedCapture: true}),
},
},
ended: {
phasedRegistrationNames: {
bubbled: keyOf({onEnded: true}),
captured: keyOf({onEndedCapture: true}),
},
},
error: {
phasedRegistrationNames: {
bubbled: keyOf({onError: true}),
captured: keyOf({onErrorCapture: true}),
},
},
focus: {
phasedRegistrationNames: {
bubbled: keyOf({onFocus: true}),
@@ -155,10 +197,22 @@ var eventTypes = {
captured: keyOf({onLoadCapture: true}),
},
},
error: {
loadedData: {
phasedRegistrationNames: {
bubbled: keyOf({onError: true}),
captured: keyOf({onErrorCapture: true}),
bubbled: keyOf({onLoadedData: true}),
captured: keyOf({onLoadedDataCapture: true}),
},
},
loadedMetadata: {
phasedRegistrationNames: {
bubbled: keyOf({onLoadedMetadata: true}),
captured: keyOf({onLoadedMetadataCapture: true}),
},
},
loadStart: {
phasedRegistrationNames: {
bubbled: keyOf({onLoadStart: true}),
captured: keyOf({onLoadStartCapture: true}),
},
},
// Note: We do not allow listening to mouseOver events. Instead, use the
@@ -193,12 +247,48 @@ var eventTypes = {
captured: keyOf({onMouseUpCapture: true}),
},
},
onEncrypted: {
phasedRegistrationNames: {
bubbled: keyOf({onEncrypted: true}),
captured: keyOf({onEncryptedCapture: true}),
},
},
paste: {
phasedRegistrationNames: {
bubbled: keyOf({onPaste: true}),
captured: keyOf({onPasteCapture: true}),
},
},
pause: {
phasedRegistrationNames: {
bubbled: keyOf({onPause: true}),
captured: keyOf({onPauseCapture: true}),
},
},
play: {
phasedRegistrationNames: {
bubbled: keyOf({onPlay: true}),
captured: keyOf({onPlayCapture: true}),
},
},
playing: {
phasedRegistrationNames: {
bubbled: keyOf({onPlaying: true}),
captured: keyOf({onPlayingCapture: true}),
},
},
progress: {
phasedRegistrationNames: {
bubbled: keyOf({onProgress: true}),
captured: keyOf({onProgressCapture: true}),
},
},
rateChange: {
phasedRegistrationNames: {
bubbled: keyOf({onRateChange: true}),
captured: keyOf({onRateChangeCapture: true}),
},
},
reset: {
phasedRegistrationNames: {
bubbled: keyOf({onReset: true}),
@@ -211,12 +301,42 @@ var eventTypes = {
captured: keyOf({onScrollCapture: true}),
},
},
seeked: {
phasedRegistrationNames: {
bubbled: keyOf({onSeeked: true}),
captured: keyOf({onSeekedCapture: true}),
},
},
seeking: {
phasedRegistrationNames: {
bubbled: keyOf({onSeeking: true}),
captured: keyOf({onSeekingCapture: true}),
},
},
stalled: {
phasedRegistrationNames: {
bubbled: keyOf({onStalled: true}),
captured: keyOf({onStalledCapture: true}),
},
},
submit: {
phasedRegistrationNames: {
bubbled: keyOf({onSubmit: true}),
captured: keyOf({onSubmitCapture: true}),
},
},
suspend: {
phasedRegistrationNames: {
bubbled: keyOf({onSuspend: true}),
captured: keyOf({onSuspendCapture: true}),
},
},
timeUpdate: {
phasedRegistrationNames: {
bubbled: keyOf({onTimeUpdate: true}),
captured: keyOf({onTimeUpdateCapture: true}),
},
},
touchCancel: {
phasedRegistrationNames: {
bubbled: keyOf({onTouchCancel: true}),
@@ -241,6 +361,18 @@ var eventTypes = {
captured: keyOf({onTouchStartCapture: true}),
},
},
volumeChange: {
phasedRegistrationNames: {
bubbled: keyOf({onVolumeChange: true}),
captured: keyOf({onVolumeChangeCapture: true}),
},
},
waiting: {
phasedRegistrationNames: {
bubbled: keyOf({onWaiting: true}),
captured: keyOf({onWaitingCapture: true}),
},
},
wheel: {
phasedRegistrationNames: {
bubbled: keyOf({onWheel: true}),
@@ -250,41 +382,63 @@ var eventTypes = {
};
var topLevelEventsToDispatchConfig = {
topBlur: eventTypes.blur,
topClick: eventTypes.click,
topContextMenu: eventTypes.contextMenu,
topCopy: eventTypes.copy,
topCut: eventTypes.cut,
topDoubleClick: eventTypes.doubleClick,
topDrag: eventTypes.drag,
topDragEnd: eventTypes.dragEnd,
topDragEnter: eventTypes.dragEnter,
topDragExit: eventTypes.dragExit,
topDragLeave: eventTypes.dragLeave,
topDragOver: eventTypes.dragOver,
topDragStart: eventTypes.dragStart,
topDrop: eventTypes.drop,
topError: eventTypes.error,
topFocus: eventTypes.focus,
topInput: eventTypes.input,
topKeyDown: eventTypes.keyDown,
topKeyPress: eventTypes.keyPress,
topKeyUp: eventTypes.keyUp,
topLoad: eventTypes.load,
topMouseDown: eventTypes.mouseDown,
topMouseMove: eventTypes.mouseMove,
topMouseOut: eventTypes.mouseOut,
topMouseOver: eventTypes.mouseOver,
topMouseUp: eventTypes.mouseUp,
topPaste: eventTypes.paste,
topReset: eventTypes.reset,
topScroll: eventTypes.scroll,
topSubmit: eventTypes.submit,
topTouchCancel: eventTypes.touchCancel,
topTouchEnd: eventTypes.touchEnd,
topTouchMove: eventTypes.touchMove,
topTouchStart: eventTypes.touchStart,
topWheel: eventTypes.wheel,
topAbort: eventTypes.abort,
topBlur: eventTypes.blur,
topCanPlay: eventTypes.canPlay,
topCanPlayThrough: eventTypes.canPlayThrough,
topClick: eventTypes.click,
topContextMenu: eventTypes.contextMenu,
topCopy: eventTypes.copy,
topCut: eventTypes.cut,
topDoubleClick: eventTypes.doubleClick,
topDrag: eventTypes.drag,
topDragEnd: eventTypes.dragEnd,
topDragEnter: eventTypes.dragEnter,
topDragExit: eventTypes.dragExit,
topDragLeave: eventTypes.dragLeave,
topDragOver: eventTypes.dragOver,
topDragStart: eventTypes.dragStart,
topDrop: eventTypes.drop,
topDurationChange: eventTypes.durationChange,
topEmptied: eventTypes.emptied,
topEnded: eventTypes.ended,
topError: eventTypes.error,
topFocus: eventTypes.focus,
topInput: eventTypes.input,
topKeyDown: eventTypes.keyDown,
topKeyPress: eventTypes.keyPress,
topKeyUp: eventTypes.keyUp,
topLoad: eventTypes.load,
topLoadedData: eventTypes.loadedData,
topLoadedMetadata: eventTypes.loadedMetadata,
topLoadStart: eventTypes.loadStart,
topMouseDown: eventTypes.mouseDown,
topMouseMove: eventTypes.mouseMove,
topMouseOut: eventTypes.mouseOut,
topMouseOver: eventTypes.mouseOver,
topMouseUp: eventTypes.mouseUp,
topOnEncrypted: eventTypes.onEncrypted,
topPause: eventTypes.pause,
topPaste: eventTypes.paste,
topPlay: eventTypes.play,
topPlaying: eventTypes.playing,
topProgress: eventTypes.progress,
topRateChange: eventTypes.rateChange,
topReset: eventTypes.reset,
topSeeked: eventTypes.seeked,
topSeeking: eventTypes.seeking,
topScroll: eventTypes.scroll,
topStalled: eventTypes.stalled,
topSubmit: eventTypes.submit,
topSuspend: eventTypes.suspend,
topTimeUpdate: eventTypes.timeUpdate,
topTouchCancel: eventTypes.touchCancel,
topTouchEnd: eventTypes.touchEnd,
topTouchMove: eventTypes.touchMove,
topTouchStart: eventTypes.touchStart,
topVolumeChange: eventTypes.volumeChange,
topWaiting: eventTypes.waiting,
topWheel: eventTypes.wheel,
};
for (var type in topLevelEventsToDispatchConfig) {
@@ -342,11 +496,33 @@ var SimpleEventPlugin = {
}
var EventConstructor;
switch (topLevelType) {
case topLevelTypes.topAbort:
case topLevelTypes.topCanPlay:
case topLevelTypes.topCanPlayThrough:
case topLevelTypes.topDurationChange:
case topLevelTypes.topEmptied:
case topLevelTypes.topEnded:
case topLevelTypes.topError:
case topLevelTypes.topInput:
case topLevelTypes.topLoad:
case topLevelTypes.topError:
case topLevelTypes.topLoadedData:
case topLevelTypes.topLoadedMetadata:
case topLevelTypes.topLoadStart:
case topLevelTypes.topOnEncrypted:
case topLevelTypes.topPause:
case topLevelTypes.topPlay:
case topLevelTypes.topPlaying:
case topLevelTypes.topProgress:
case topLevelTypes.topRateChange:
case topLevelTypes.topReset:
case topLevelTypes.topSeeked:
case topLevelTypes.topSeeking:
case topLevelTypes.topStalled:
case topLevelTypes.topSubmit:
case topLevelTypes.topSuspend:
case topLevelTypes.topTimeUpdate:
case topLevelTypes.topVolumeChange:
case topLevelTypes.topWaiting:
// HTML Events
// @see http://www.w3.org/TR/html5/index.html#events-0
EventConstructor = SyntheticEvent;

View File

@@ -301,6 +301,34 @@ function putListener() {
);
}
// There are so many media events, it makes sense to just
// maintain a list rather than create a `trapBubbledEvent` for each
var mediaEvents = {
topAbort: 'abort',
topCanPlay: 'canplay',
topCanPlayThrough: 'canplaythrough',
topDurationChange: 'durationchange',
topEmptied: 'emptied',
topEnded: 'ended',
topError: 'error',
topLoadedData: 'loadeddata',
topLoadedMetadata: 'loadedmetadata',
topLoadStart: 'loadstart',
topOnEncrypted: 'onencrypted',
topPause: 'pause',
topPlay: 'play',
topPlaying: 'playing',
topProgress: 'progress',
topRateChange: 'ratechange',
topSeeked: 'seeked',
topSeeking: 'seeking',
topStalled: 'stalled',
topSuspend: 'suspend',
topTimeUpdate: 'timeupdate',
topVolumeChange: 'volumechange',
topWaiting: 'waiting',
};
function trapBubbledEventsLocal() {
var inst = this;
// If a component renders to null or if another component fatals and causes
@@ -321,6 +349,24 @@ function trapBubbledEventsLocal() {
node
),
];
break;
case 'video':
case 'audio':
inst._wrapperState.listeners = [];
// create listener for each media event
for (var event in mediaEvents) {
if (mediaEvents.hasOwnProperty(event)) {
inst._wrapperState.listeners.push(
ReactBrowserEventEmitter.trapBubbledEvent(
EventConstants.topLevelTypes[event],
mediaEvents[event],
node
)
);
}
}
break;
case 'img':
inst._wrapperState.listeners = [
@@ -475,6 +521,8 @@ ReactDOMComponent.Mixin = {
case 'iframe':
case 'img':
case 'form':
case 'video':
case 'audio':
this._wrapperState = {
listeners: null,
};
@@ -902,6 +950,8 @@ ReactDOMComponent.Mixin = {
case 'iframe':
case 'img':
case 'form':
case 'video':
case 'audio':
var listeners = this._wrapperState.listeners;
if (listeners) {
for (var i = 0; i < listeners.length; i++) {

View File

@@ -19,7 +19,10 @@ var PropagationPhases = keyMirror({bubbled: null, captured: null});
* Types of raw signals from the browser caught at the top level.
*/
var topLevelTypes = keyMirror({
topAbort: null,
topBlur: null,
topCanPlay: null,
topCanPlayThrough: null,
topChange: null,
topClick: null,
topCompositionEnd: null,
@@ -37,6 +40,9 @@ var topLevelTypes = keyMirror({
topDragOver: null,
topDragStart: null,
topDrop: null,
topDurationChange: null,
topEmptied: null,
topEnded: null,
topError: null,
topFocus: null,
topInput: null,
@@ -44,21 +50,37 @@ var topLevelTypes = keyMirror({
topKeyPress: null,
topKeyUp: null,
topLoad: null,
topLoadedData: null,
topLoadedMetadata: null,
topLoadStart: null,
topMouseDown: null,
topMouseMove: null,
topMouseOut: null,
topMouseOver: null,
topMouseUp: null,
topOnEncrypted: null,
topPaste: null,
topPause: null,
topPlay: null,
topPlaying: null,
topProgress: null,
topRateChange: null,
topReset: null,
topScroll: null,
topSeeked: null,
topSeeking: null,
topSelectionChange: null,
topStalled: null,
topSuspend: null,
topSubmit: null,
topTextInput: null,
topTimeUpdate: null,
topTouchCancel: null,
topTouchEnd: null,
topTouchMove: null,
topTouchStart: null,
topVolumeChange: null,
topWaiting: null,
topWheel: null,
});