mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
react app
This commit is contained in:
380
react-app/node_modules/react/lib/ChangeEventPlugin.js
generated
vendored
Normal file
380
react-app/node_modules/react/lib/ChangeEventPlugin.js
generated
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
/**
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule ChangeEventPlugin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var EventConstants = require("./EventConstants");
|
||||
var EventPluginHub = require("./EventPluginHub");
|
||||
var EventPropagators = require("./EventPropagators");
|
||||
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
||||
var ReactUpdates = require("./ReactUpdates");
|
||||
var SyntheticEvent = require("./SyntheticEvent");
|
||||
|
||||
var isEventSupported = require("./isEventSupported");
|
||||
var isTextInputElement = require("./isTextInputElement");
|
||||
var keyOf = require("./keyOf");
|
||||
|
||||
var topLevelTypes = EventConstants.topLevelTypes;
|
||||
|
||||
var eventTypes = {
|
||||
change: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: keyOf({onChange: null}),
|
||||
captured: keyOf({onChangeCapture: null})
|
||||
},
|
||||
dependencies: [
|
||||
topLevelTypes.topBlur,
|
||||
topLevelTypes.topChange,
|
||||
topLevelTypes.topClick,
|
||||
topLevelTypes.topFocus,
|
||||
topLevelTypes.topInput,
|
||||
topLevelTypes.topKeyDown,
|
||||
topLevelTypes.topKeyUp,
|
||||
topLevelTypes.topSelectionChange
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* For IE shims
|
||||
*/
|
||||
var activeElement = null;
|
||||
var activeElementID = null;
|
||||
var activeElementValue = null;
|
||||
var activeElementValueProp = null;
|
||||
|
||||
/**
|
||||
* SECTION: handle `change` event
|
||||
*/
|
||||
function shouldUseChangeEvent(elem) {
|
||||
return (
|
||||
elem.nodeName === 'SELECT' ||
|
||||
(elem.nodeName === 'INPUT' && elem.type === 'file')
|
||||
);
|
||||
}
|
||||
|
||||
var doesChangeEventBubble = false;
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
// See `handleChange` comment below
|
||||
doesChangeEventBubble = isEventSupported('change') && (
|
||||
(!('documentMode' in document) || document.documentMode > 8)
|
||||
);
|
||||
}
|
||||
|
||||
function manualDispatchChangeEvent(nativeEvent) {
|
||||
var event = SyntheticEvent.getPooled(
|
||||
eventTypes.change,
|
||||
activeElementID,
|
||||
nativeEvent
|
||||
);
|
||||
EventPropagators.accumulateTwoPhaseDispatches(event);
|
||||
|
||||
// If change and propertychange bubbled, we'd just bind to it like all the
|
||||
// other events and have it go through ReactBrowserEventEmitter. Since it
|
||||
// doesn't, we manually listen for the events and so we have to enqueue and
|
||||
// process the abstract event manually.
|
||||
//
|
||||
// Batching is necessary here in order to ensure that all event handlers run
|
||||
// before the next rerender (including event handlers attached to ancestor
|
||||
// elements instead of directly on the input). Without this, controlled
|
||||
// components don't work properly in conjunction with event bubbling because
|
||||
// the component is rerendered and the value reverted before all the event
|
||||
// handlers can run. See https://github.com/facebook/react/issues/708.
|
||||
ReactUpdates.batchedUpdates(runEventInBatch, event);
|
||||
}
|
||||
|
||||
function runEventInBatch(event) {
|
||||
EventPluginHub.enqueueEvents(event);
|
||||
EventPluginHub.processEventQueue();
|
||||
}
|
||||
|
||||
function startWatchingForChangeEventIE8(target, targetID) {
|
||||
activeElement = target;
|
||||
activeElementID = targetID;
|
||||
activeElement.attachEvent('onchange', manualDispatchChangeEvent);
|
||||
}
|
||||
|
||||
function stopWatchingForChangeEventIE8() {
|
||||
if (!activeElement) {
|
||||
return;
|
||||
}
|
||||
activeElement.detachEvent('onchange', manualDispatchChangeEvent);
|
||||
activeElement = null;
|
||||
activeElementID = null;
|
||||
}
|
||||
|
||||
function getTargetIDForChangeEvent(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
if (topLevelType === topLevelTypes.topChange) {
|
||||
return topLevelTargetID;
|
||||
}
|
||||
}
|
||||
function handleEventsForChangeEventIE8(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
if (topLevelType === topLevelTypes.topFocus) {
|
||||
// stopWatching() should be a noop here but we call it just in case we
|
||||
// missed a blur event somehow.
|
||||
stopWatchingForChangeEventIE8();
|
||||
startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);
|
||||
} else if (topLevelType === topLevelTypes.topBlur) {
|
||||
stopWatchingForChangeEventIE8();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: handle `input` event
|
||||
*/
|
||||
var isInputEventSupported = false;
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
// IE9 claims to support the input event but fails to trigger it when
|
||||
// deleting text, so we ignore its input events
|
||||
isInputEventSupported = isEventSupported('input') && (
|
||||
(!('documentMode' in document) || document.documentMode > 9)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* (For old IE.) Replacement getter/setter for the `value` property that gets
|
||||
* set on the active element.
|
||||
*/
|
||||
var newValueProp = {
|
||||
get: function() {
|
||||
return activeElementValueProp.get.call(this);
|
||||
},
|
||||
set: function(val) {
|
||||
// Cast to a string so we can do equality checks.
|
||||
activeElementValue = '' + val;
|
||||
activeElementValueProp.set.call(this, val);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* (For old IE.) Starts tracking propertychange events on the passed-in element
|
||||
* and override the value property so that we can distinguish user events from
|
||||
* value changes in JS.
|
||||
*/
|
||||
function startWatchingForValueChange(target, targetID) {
|
||||
activeElement = target;
|
||||
activeElementID = targetID;
|
||||
activeElementValue = target.value;
|
||||
activeElementValueProp = Object.getOwnPropertyDescriptor(
|
||||
target.constructor.prototype,
|
||||
'value'
|
||||
);
|
||||
|
||||
Object.defineProperty(activeElement, 'value', newValueProp);
|
||||
activeElement.attachEvent('onpropertychange', handlePropertyChange);
|
||||
}
|
||||
|
||||
/**
|
||||
* (For old IE.) Removes the event listeners from the currently-tracked element,
|
||||
* if any exists.
|
||||
*/
|
||||
function stopWatchingForValueChange() {
|
||||
if (!activeElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// delete restores the original property definition
|
||||
delete activeElement.value;
|
||||
activeElement.detachEvent('onpropertychange', handlePropertyChange);
|
||||
|
||||
activeElement = null;
|
||||
activeElementID = null;
|
||||
activeElementValue = null;
|
||||
activeElementValueProp = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* (For old IE.) Handles a propertychange event, sending a `change` event if
|
||||
* the value of the active element has changed.
|
||||
*/
|
||||
function handlePropertyChange(nativeEvent) {
|
||||
if (nativeEvent.propertyName !== 'value') {
|
||||
return;
|
||||
}
|
||||
var value = nativeEvent.srcElement.value;
|
||||
if (value === activeElementValue) {
|
||||
return;
|
||||
}
|
||||
activeElementValue = value;
|
||||
|
||||
manualDispatchChangeEvent(nativeEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a `change` event should be fired, returns the target's ID.
|
||||
*/
|
||||
function getTargetIDForInputEvent(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
if (topLevelType === topLevelTypes.topInput) {
|
||||
// In modern browsers (i.e., not IE8 or IE9), the input event is exactly
|
||||
// what we want so fall through here and trigger an abstract event
|
||||
return topLevelTargetID;
|
||||
}
|
||||
}
|
||||
|
||||
// For IE8 and IE9.
|
||||
function handleEventsForInputEventIE(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
if (topLevelType === topLevelTypes.topFocus) {
|
||||
// In IE8, we can capture almost all .value changes by adding a
|
||||
// propertychange handler and looking for events with propertyName
|
||||
// equal to 'value'
|
||||
// In IE9, propertychange fires for most input events but is buggy and
|
||||
// doesn't fire when text is deleted, but conveniently, selectionchange
|
||||
// appears to fire in all of the remaining cases so we catch those and
|
||||
// forward the event if the value has changed
|
||||
// In either case, we don't want to call the event handler if the value
|
||||
// is changed from JS so we redefine a setter for `.value` that updates
|
||||
// our activeElementValue variable, allowing us to ignore those changes
|
||||
//
|
||||
// stopWatching() should be a noop here but we call it just in case we
|
||||
// missed a blur event somehow.
|
||||
stopWatchingForValueChange();
|
||||
startWatchingForValueChange(topLevelTarget, topLevelTargetID);
|
||||
} else if (topLevelType === topLevelTypes.topBlur) {
|
||||
stopWatchingForValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
// For IE8 and IE9.
|
||||
function getTargetIDForInputEventIE(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
if (topLevelType === topLevelTypes.topSelectionChange ||
|
||||
topLevelType === topLevelTypes.topKeyUp ||
|
||||
topLevelType === topLevelTypes.topKeyDown) {
|
||||
// On the selectionchange event, the target is just document which isn't
|
||||
// helpful for us so just check activeElement instead.
|
||||
//
|
||||
// 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
|
||||
// propertychange on the first input event after setting `value` from a
|
||||
// script and fires only keydown, keypress, keyup. Catching keyup usually
|
||||
// gets it and catching keydown lets us fire an event for the first
|
||||
// keystroke if user does a key repeat (it'll be a little delayed: right
|
||||
// before the second keystroke). Other input methods (e.g., paste) seem to
|
||||
// fire selectionchange normally.
|
||||
if (activeElement && activeElement.value !== activeElementValue) {
|
||||
activeElementValue = activeElement.value;
|
||||
return activeElementID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: handle `click` event
|
||||
*/
|
||||
function shouldUseClickEvent(elem) {
|
||||
// Use the `click` event to detect changes to checkbox and radio inputs.
|
||||
// This approach works across all browsers, whereas `change` does not fire
|
||||
// until `blur` in IE8.
|
||||
return (
|
||||
elem.nodeName === 'INPUT' &&
|
||||
(elem.type === 'checkbox' || elem.type === 'radio')
|
||||
);
|
||||
}
|
||||
|
||||
function getTargetIDForClickEvent(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
if (topLevelType === topLevelTypes.topClick) {
|
||||
return topLevelTargetID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This plugin creates an `onChange` event that normalizes change events
|
||||
* across form elements. This event fires at a time when it's possible to
|
||||
* change the element's value without seeing a flicker.
|
||||
*
|
||||
* Supported elements are:
|
||||
* - input (see `isTextInputElement`)
|
||||
* - textarea
|
||||
* - select
|
||||
*/
|
||||
var ChangeEventPlugin = {
|
||||
|
||||
eventTypes: eventTypes,
|
||||
|
||||
/**
|
||||
* @param {string} topLevelType Record from `EventConstants`.
|
||||
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
||||
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
||||
* @param {object} nativeEvent Native browser event.
|
||||
* @return {*} An accumulation of synthetic events.
|
||||
* @see {EventPluginHub.extractEvents}
|
||||
*/
|
||||
extractEvents: function(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID,
|
||||
nativeEvent) {
|
||||
|
||||
var getTargetIDFunc, handleEventFunc;
|
||||
if (shouldUseChangeEvent(topLevelTarget)) {
|
||||
if (doesChangeEventBubble) {
|
||||
getTargetIDFunc = getTargetIDForChangeEvent;
|
||||
} else {
|
||||
handleEventFunc = handleEventsForChangeEventIE8;
|
||||
}
|
||||
} else if (isTextInputElement(topLevelTarget)) {
|
||||
if (isInputEventSupported) {
|
||||
getTargetIDFunc = getTargetIDForInputEvent;
|
||||
} else {
|
||||
getTargetIDFunc = getTargetIDForInputEventIE;
|
||||
handleEventFunc = handleEventsForInputEventIE;
|
||||
}
|
||||
} else if (shouldUseClickEvent(topLevelTarget)) {
|
||||
getTargetIDFunc = getTargetIDForClickEvent;
|
||||
}
|
||||
|
||||
if (getTargetIDFunc) {
|
||||
var targetID = getTargetIDFunc(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID
|
||||
);
|
||||
if (targetID) {
|
||||
var event = SyntheticEvent.getPooled(
|
||||
eventTypes.change,
|
||||
targetID,
|
||||
nativeEvent
|
||||
);
|
||||
EventPropagators.accumulateTwoPhaseDispatches(event);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
if (handleEventFunc) {
|
||||
handleEventFunc(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ChangeEventPlugin;
|
Reference in New Issue
Block a user