-
Notifications
You must be signed in to change notification settings - Fork 47.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split markup generation from DOM property management (#10197)
* Replace SSR unit test with integration test * Remove unit test that is already covered by integration suite * Replace unit tests for boolean attrs with integration tests * Replace unit test for aria attrs with integration test * Replace unit tests for numeric 0 with integration tests * Remove unit test covered by integration tests * Replace unit test for injection with integration test It still touches internals but it tests both renderers. * Fork DOMPropertyOperations into DOMMarkupOperations * Trim down DOMPropertyOperations and DOMMarkupOperations * Record SSR sizes * Record them tests * Fix false positive warning for overloaded booleans when passing numbers * Remove stray import * Replace CSS markup tests with public API tests Some of these are handy as integration tests so I moved them there. But some test markup specifically so I changed them to use DOMServer. * Make CSSPropertyOperations client-only I forked createMarkupForStyles() into ReactDOMComponent and ReactPartialRenderer. Duplication is fine because one of them will soon be gone (guess which one!) The warnInvalidStyle helper is used by both server and client, unlike other client-only stuff in CSSPropertyOperations, so I moved it to a separately module used in both. * Record server bundle size * Add an early exit to validation * Clarify what is being duplicated
- Loading branch information
Showing
11 changed files
with
742 additions
and
563 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/** | ||
* 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 DOMMarkupOperations | ||
*/ | ||
|
||
'use strict'; | ||
|
||
var DOMProperty = require('DOMProperty'); | ||
|
||
var quoteAttributeValueForBrowser = require('quoteAttributeValueForBrowser'); | ||
var warning = require('fbjs/lib/warning'); | ||
|
||
// isAttributeNameSafe() is currently duplicated in DOMPropertyOperations. | ||
// TODO: Find a better place for this. | ||
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp( | ||
'^[' + | ||
DOMProperty.ATTRIBUTE_NAME_START_CHAR + | ||
'][' + | ||
DOMProperty.ATTRIBUTE_NAME_CHAR + | ||
']*$', | ||
); | ||
var illegalAttributeNameCache = {}; | ||
var validatedAttributeNameCache = {}; | ||
function isAttributeNameSafe(attributeName) { | ||
if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { | ||
return true; | ||
} | ||
if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { | ||
return false; | ||
} | ||
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { | ||
validatedAttributeNameCache[attributeName] = true; | ||
return true; | ||
} | ||
illegalAttributeNameCache[attributeName] = true; | ||
warning(false, 'Invalid attribute name: `%s`', attributeName); | ||
return false; | ||
} | ||
|
||
// shouldIgnoreValue() is currently duplicated in DOMPropertyOperations. | ||
// TODO: Find a better place for this. | ||
function shouldIgnoreValue(propertyInfo, value) { | ||
return ( | ||
value == null || | ||
(propertyInfo.hasBooleanValue && !value) || | ||
(propertyInfo.hasNumericValue && isNaN(value)) || | ||
(propertyInfo.hasPositiveNumericValue && value < 1) || | ||
(propertyInfo.hasOverloadedBooleanValue && value === false) | ||
); | ||
} | ||
|
||
/** | ||
* Operations for dealing with DOM properties. | ||
*/ | ||
var DOMMarkupOperations = { | ||
/** | ||
* Creates markup for the ID property. | ||
* | ||
* @param {string} id Unescaped ID. | ||
* @return {string} Markup string. | ||
*/ | ||
createMarkupForID: function(id) { | ||
return ( | ||
DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id) | ||
); | ||
}, | ||
|
||
createMarkupForRoot: function() { | ||
return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""'; | ||
}, | ||
|
||
/** | ||
* Creates markup for a property. | ||
* | ||
* @param {string} name | ||
* @param {*} value | ||
* @return {?string} Markup string, or null if the property was invalid. | ||
*/ | ||
createMarkupForProperty: function(name, value) { | ||
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) | ||
? DOMProperty.properties[name] | ||
: null; | ||
if (propertyInfo) { | ||
if (shouldIgnoreValue(propertyInfo, value)) { | ||
return ''; | ||
} | ||
var attributeName = propertyInfo.attributeName; | ||
if ( | ||
propertyInfo.hasBooleanValue || | ||
(propertyInfo.hasOverloadedBooleanValue && value === true) | ||
) { | ||
return attributeName + '=""'; | ||
} | ||
return attributeName + '=' + quoteAttributeValueForBrowser(value); | ||
} else if (DOMProperty.isCustomAttribute(name)) { | ||
if (value == null) { | ||
return ''; | ||
} | ||
return name + '=' + quoteAttributeValueForBrowser(value); | ||
} | ||
return null; | ||
}, | ||
|
||
/** | ||
* Creates markup for a custom property. | ||
* | ||
* @param {string} name | ||
* @param {*} value | ||
* @return {string} Markup string, or empty string if the property was invalid. | ||
*/ | ||
createMarkupForCustomAttribute: function(name, value) { | ||
if (!isAttributeNameSafe(name) || value == null) { | ||
return ''; | ||
} | ||
return name + '=' + quoteAttributeValueForBrowser(value); | ||
}, | ||
}; | ||
|
||
module.exports = DOMMarkupOperations; |
Oops, something went wrong.