Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DOM wrapper component using lower-level primitives #3976

Merged
merged 1 commit into from
Jun 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,31 @@
* 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 AutoFocusMixin
* @providesModule AutoFocusUtils
* @typechecks static-only
*/

'use strict';

var ReactMount = require('ReactMount');

var findDOMNode = require('findDOMNode');
var focusNode = require('focusNode');

var AutoFocusMixin = {
var Mixin = {
componentDidMount: function() {
if (this.props.autoFocus) {
focusNode(findDOMNode(this));
}
}
};

module.exports = AutoFocusMixin;
var AutoFocusUtils = {
Mixin: Mixin,

focusDOMComponent: function() {
focusNode(ReactMount.getNode(this._rootNodeID));
}
};

module.exports = AutoFocusUtils;
111 changes: 61 additions & 50 deletions src/renderers/dom/client/wrappers/LinkedValueUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
var ReactPropTypes = require('ReactPropTypes');

var invariant = require('invariant');
var warning = require('warning');

var hasReadOnlyValue = {
'button': true,
Expand Down Expand Up @@ -52,59 +53,68 @@ function _assertCheckedLink(inputProps) {
);
}

/**
* @param {SyntheticEvent} e change event to handle
*/
function _handleLinkedValueChange(e) {
/*jshint validthis:true */
this.props.valueLink.requestChange(e.target.value);
}
var propTypes = {
value: function(props, propName, componentName) {
if (!props[propName] ||
hasReadOnlyValue[props.type] ||
props.onChange ||
props.readOnly ||
props.disabled) {
return null;
}
return new Error(
'You provided a `value` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultValue`. Otherwise, ' +
'set either `onChange` or `readOnly`.'
);
},
checked: function(props, propName, componentName) {
if (!props[propName] ||
props.onChange ||
props.readOnly ||
props.disabled) {
return null;
}
return new Error(
'You provided a `checked` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultChecked`. Otherwise, ' +
'set either `onChange` or `readOnly`.'
);
},
onChange: ReactPropTypes.func
};

/**
* @param {SyntheticEvent} e change event to handle
*/
function _handleLinkedCheckChange(e) {
/*jshint validthis:true */
this.props.checkedLink.requestChange(e.target.checked);
var loggedTypeFailures = {};
function getDeclarationErrorAddendum(owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}

/**
* Provide a linked `value` attribute for controlled forms. You should not use
* this outside of the ReactDOM controlled form components.
*/
var LinkedValueUtils = {
Mixin: {
propTypes: {
value: function(props, propName, componentName) {
if (!props[propName] ||
hasReadOnlyValue[props.type] ||
props.onChange ||
props.readOnly ||
props.disabled) {
return null;
}
return new Error(
'You provided a `value` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultValue`. Otherwise, ' +
'set either `onChange` or `readOnly`.'
);
},
checked: function(props, propName, componentName) {
if (!props[propName] ||
props.onChange ||
props.readOnly ||
props.disabled) {
return null;
}
return new Error(
'You provided a `checked` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultChecked`. Otherwise, ' +
'set either `onChange` or `readOnly`.'
);
},
onChange: ReactPropTypes.func
checkPropTypes: function (tagName, props, owner) {
for (var propName in propTypes) {
if (propTypes.hasOwnProperty(propName)) {
var error = propTypes[propName](props, propName, tagName, location);
}
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;

var addendum = getDeclarationErrorAddendum(owner);
warning(false, 'Failed form propType: %s%s', error.message, addendum);
}
}
},

Expand Down Expand Up @@ -135,17 +145,18 @@ var LinkedValueUtils = {

/**
* @param {object} inputProps Props for form component
* @return {function} change callback either from onChange prop or link.
* @param {SyntheticEvent} event change event to handle
*/
getOnChange: function(inputProps) {
executeOnChange: function(inputProps, event) {
if (inputProps.valueLink) {
_assertValueLink(inputProps);
return _handleLinkedValueChange;
return inputProps.valueLink.requestChange(event.target.value);
} else if (inputProps.checkedLink) {
_assertCheckedLink(inputProps);
return _handleLinkedCheckChange;
return inputProps.checkedLink.requestChange(event.target.checked);
} else if (inputProps.onChange) {
return inputProps.onChange.call(undefined, event);
}
return inputProps.onChange;
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/renderers/dom/client/wrappers/ReactDOMButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

'use strict';

var AutoFocusMixin = require('AutoFocusMixin');
var AutoFocusUtils = require('AutoFocusUtils');
var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin');
var ReactClass = require('ReactClass');
var ReactElement = require('ReactElement');
Expand Down Expand Up @@ -41,7 +41,7 @@ var ReactDOMButton = ReactClass.createClass({
displayName: 'ReactDOMButton',
tagName: 'BUTTON',

mixins: [AutoFocusMixin, ReactBrowserComponentMixin],
mixins: [AutoFocusUtils.Mixin, ReactBrowserComponentMixin],

render: function() {
var props = {};
Expand Down