mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
fe4a5b4004
* Only re-assign defaultValue if it is different * Do not set value if it is the same * Properly cover defaultValue * Use coercion to be smart about value assignment * Add explanation of loose type checks in value assignment. * Add test coverage for setAttribute update. * Only apply loose value check to text inputs * Fix case where empty switches to zero * Handle zero case in controlled input * Correct mistake with default value assignment after rebase * Do not assign bad input to number input * Only trigger number input value attribute updates on blur * Remove reference to LinkedValueUtils * Record new fiber tests * Add tests for blurred number input behavior * Replace onBlur wrapper with rule in ChangeEventPlugin * Sift down to only number inputs * Re-record fiber tests * Add test case for updating attribute on uncontrolled inputs. Make related correction * Handle uncontrolled inputs, integrate fiber * Reorder boolean to mitigate DOM checks * Only assign value if it is different * Add number input browser test fixtures During the course of the number input fix, we uncovered many edge cases. This commit adds browser test fixtures for each of those instances. * Address edge case preventing number precision lower than 1 place 0.0 coerces to 0, however they are not the same value when doing string comparision. This prevented controlled number inputs from inputing the characters `0.00`. Also adds test cases. * Accommodate lack of IE9 number input support IE9 does not support number inputs. Number inputs in IE9 fallback to traditional text inputs. This means that accessing `input.value` will report the raw text, rather than parsing a numeric value. This commit makes the ReactDOMInput wrapper check to see if the `type` prop has been configured to `"number"`. In those cases, it will perform a comparison based upon `parseFloat` instead of the raw input value. * Remove footnotes about IE exponent issues With the recent IE9 fix, IE properly inserts `e` when it produces an invalid number. * Address exception in IE9/10 ChangeEventPlugin blur event On blur, inputs have their values assigned. This is so that number inputs do not conduct unexpected behavior in Chrome/Safari. Unfortunately, there are cases where the target instance might be undefined in IE9/10, raising an exception. * Migrate over ReactDOMInput.js number input fixes to Fiber Also re-record tests * Update number fixtures to use latest components * Add number input test case for dashes and negative numbers * Replace trailing dash test case with replace with dash Also run prettier
245 lines
6.5 KiB
JavaScript
245 lines
6.5 KiB
JavaScript
/**
|
|
* Copyright 2013-present, 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 HTMLDOMPropertyConfig
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DOMProperty = require('DOMProperty');
|
|
|
|
var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
|
|
var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
|
|
var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE;
|
|
var HAS_POSITIVE_NUMERIC_VALUE =
|
|
DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
|
|
var HAS_OVERLOADED_BOOLEAN_VALUE =
|
|
DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;
|
|
|
|
var HTMLDOMPropertyConfig = {
|
|
isCustomAttribute: RegExp.prototype.test.bind(
|
|
new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')
|
|
),
|
|
Properties: {
|
|
/**
|
|
* Standard Properties
|
|
*/
|
|
accept: 0,
|
|
acceptCharset: 0,
|
|
accessKey: 0,
|
|
action: 0,
|
|
allowFullScreen: HAS_BOOLEAN_VALUE,
|
|
allowTransparency: 0,
|
|
alt: 0,
|
|
// specifies target context for links with `preload` type
|
|
as: 0,
|
|
async: HAS_BOOLEAN_VALUE,
|
|
autoComplete: 0,
|
|
// autoFocus is polyfilled/normalized by AutoFocusUtils
|
|
// autoFocus: HAS_BOOLEAN_VALUE,
|
|
autoPlay: HAS_BOOLEAN_VALUE,
|
|
capture: HAS_BOOLEAN_VALUE,
|
|
cellPadding: 0,
|
|
cellSpacing: 0,
|
|
charSet: 0,
|
|
challenge: 0,
|
|
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
cite: 0,
|
|
classID: 0,
|
|
className: 0,
|
|
cols: HAS_POSITIVE_NUMERIC_VALUE,
|
|
colSpan: 0,
|
|
content: 0,
|
|
contentEditable: 0,
|
|
contextMenu: 0,
|
|
controls: HAS_BOOLEAN_VALUE,
|
|
coords: 0,
|
|
crossOrigin: 0,
|
|
data: 0, // For `<object />` acts as `src`.
|
|
dateTime: 0,
|
|
default: HAS_BOOLEAN_VALUE,
|
|
defer: HAS_BOOLEAN_VALUE,
|
|
dir: 0,
|
|
disabled: HAS_BOOLEAN_VALUE,
|
|
download: HAS_OVERLOADED_BOOLEAN_VALUE,
|
|
draggable: 0,
|
|
encType: 0,
|
|
form: 0,
|
|
formAction: 0,
|
|
formEncType: 0,
|
|
formMethod: 0,
|
|
formNoValidate: HAS_BOOLEAN_VALUE,
|
|
formTarget: 0,
|
|
frameBorder: 0,
|
|
headers: 0,
|
|
height: 0,
|
|
hidden: HAS_BOOLEAN_VALUE,
|
|
high: 0,
|
|
href: 0,
|
|
hrefLang: 0,
|
|
htmlFor: 0,
|
|
httpEquiv: 0,
|
|
icon: 0,
|
|
id: 0,
|
|
inputMode: 0,
|
|
integrity: 0,
|
|
is: 0,
|
|
keyParams: 0,
|
|
keyType: 0,
|
|
kind: 0,
|
|
label: 0,
|
|
lang: 0,
|
|
list: 0,
|
|
loop: HAS_BOOLEAN_VALUE,
|
|
low: 0,
|
|
manifest: 0,
|
|
marginHeight: 0,
|
|
marginWidth: 0,
|
|
max: 0,
|
|
maxLength: 0,
|
|
media: 0,
|
|
mediaGroup: 0,
|
|
method: 0,
|
|
min: 0,
|
|
minLength: 0,
|
|
// Caution; `option.selected` is not updated if `select.multiple` is
|
|
// disabled with `removeAttribute`.
|
|
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
name: 0,
|
|
nonce: 0,
|
|
noValidate: HAS_BOOLEAN_VALUE,
|
|
open: HAS_BOOLEAN_VALUE,
|
|
optimum: 0,
|
|
pattern: 0,
|
|
placeholder: 0,
|
|
playsInline: HAS_BOOLEAN_VALUE,
|
|
poster: 0,
|
|
preload: 0,
|
|
profile: 0,
|
|
radioGroup: 0,
|
|
readOnly: HAS_BOOLEAN_VALUE,
|
|
referrerPolicy: 0,
|
|
rel: 0,
|
|
required: HAS_BOOLEAN_VALUE,
|
|
reversed: HAS_BOOLEAN_VALUE,
|
|
role: 0,
|
|
rows: HAS_POSITIVE_NUMERIC_VALUE,
|
|
rowSpan: HAS_NUMERIC_VALUE,
|
|
sandbox: 0,
|
|
scope: 0,
|
|
scoped: HAS_BOOLEAN_VALUE,
|
|
scrolling: 0,
|
|
seamless: HAS_BOOLEAN_VALUE,
|
|
selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
|
|
shape: 0,
|
|
size: HAS_POSITIVE_NUMERIC_VALUE,
|
|
sizes: 0,
|
|
span: HAS_POSITIVE_NUMERIC_VALUE,
|
|
spellCheck: 0,
|
|
src: 0,
|
|
srcDoc: 0,
|
|
srcLang: 0,
|
|
srcSet: 0,
|
|
start: HAS_NUMERIC_VALUE,
|
|
step: 0,
|
|
style: 0,
|
|
summary: 0,
|
|
tabIndex: 0,
|
|
target: 0,
|
|
title: 0,
|
|
// Setting .type throws on non-<input> tags
|
|
type: 0,
|
|
useMap: 0,
|
|
value: 0,
|
|
width: 0,
|
|
wmode: 0,
|
|
wrap: 0,
|
|
|
|
/**
|
|
* RDFa Properties
|
|
*/
|
|
about: 0,
|
|
datatype: 0,
|
|
inlist: 0,
|
|
prefix: 0,
|
|
// property is also supported for OpenGraph in meta tags.
|
|
property: 0,
|
|
resource: 0,
|
|
typeof: 0,
|
|
vocab: 0,
|
|
|
|
/**
|
|
* Non-standard Properties
|
|
*/
|
|
// autoCapitalize and autoCorrect are supported in Mobile Safari for
|
|
// keyboard hints.
|
|
autoCapitalize: 0,
|
|
autoCorrect: 0,
|
|
// autoSave allows WebKit/Blink to persist values of input fields on page reloads
|
|
autoSave: 0,
|
|
// color is for Safari mask-icon link
|
|
color: 0,
|
|
// itemProp, itemScope, itemType are for
|
|
// Microdata support. See http://schema.org/docs/gs.html
|
|
itemProp: 0,
|
|
itemScope: HAS_BOOLEAN_VALUE,
|
|
itemType: 0,
|
|
// itemID and itemRef are for Microdata support as well but
|
|
// only specified in the WHATWG spec document. See
|
|
// https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api
|
|
itemID: 0,
|
|
itemRef: 0,
|
|
// results show looking glass icon and recent searches on input
|
|
// search fields in WebKit/Blink
|
|
results: 0,
|
|
// IE-only attribute that specifies security restrictions on an iframe
|
|
// as an alternative to the sandbox attribute on IE<10
|
|
security: 0,
|
|
// IE-only attribute that controls focus behavior
|
|
unselectable: 0,
|
|
},
|
|
DOMAttributeNames: {
|
|
acceptCharset: 'accept-charset',
|
|
className: 'class',
|
|
htmlFor: 'for',
|
|
httpEquiv: 'http-equiv',
|
|
},
|
|
DOMPropertyNames: {},
|
|
DOMMutationMethods: {
|
|
value: function(node, value) {
|
|
if (value == null) {
|
|
return node.removeAttribute('value');
|
|
}
|
|
|
|
// Number inputs get special treatment due to some edge cases in
|
|
// Chrome. Let everything else assign the value attribute as normal.
|
|
// https://github.com/facebook/react/issues/7253#issuecomment-236074326
|
|
if (node.type !== 'number' || node.hasAttribute('value') === false) {
|
|
node.setAttribute('value', '' + value);
|
|
} else if (
|
|
node.validity &&
|
|
!node.validity.badInput &&
|
|
node.ownerDocument.activeElement !== node
|
|
) {
|
|
// Don't assign an attribute if validation reports bad
|
|
// input. Chrome will clear the value. Additionally, don't
|
|
// operate on inputs that have focus, otherwise Chrome might
|
|
// strip off trailing decimal places and cause the user's
|
|
// cursor position to jump to the beginning of the input.
|
|
//
|
|
// In ReactDOMInput, we have an onBlur event that will trigger
|
|
// this function again when focus is lost.
|
|
node.setAttribute('value', '' + value);
|
|
}
|
|
},
|
|
},
|
|
};
|
|
|
|
module.exports = HTMLDOMPropertyConfig;
|