DOMProperty

The DOMProperty module is used to load the node property plug-in, which ultimately affects the addition and removal of node properties by the DOMPropertyOperation module.

 

'use strict';

var _prodInvariant = require('./reactProdInvariant');
var invariant = require('fbjs/lib/invariant');

// Get whether the property is added in node[propName]=value, or the property value processing method
function checkMask(value, bitmask) {
  return (value & bitmask) === bitmask;
}

var DOMPropertyInjection = {
  MUST_USE_PROPERTY: 0x1,// 0x 16 bits add properties in node[propName]=value
  HAS_BOOLEAN_VALUE: 0x4, // filter no value
  HAS_NUMERIC_VALUE: 0x8,// filter non-numeric type
  HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8,// filter non-positive numbers
  HAS_OVERLOADED_BOOLEAN_VALUE: 0x20,// 过滤false

  /**The writing method of the node attribute plugin, that is, the attributes it contains:
   *
   * isCustomAttribute: function, return true value, attribute that will be added to the node, such as data-, aria- of HTMLDOMPropertyConfig module
   *
   * Properties: Set the collection of property value type processing methods, such as a property value of 0x4, otherwise the value will not be added as a property of the node
   *
   * DOMAttributeNames: key-value pairs store attribute names, used when splicing attribute names and their values ​​in string form
   *
   * DOMAttributeNamespaces: A collection of key-value pair convention attribute namespaces
   *
   * DOMPropertyNames: When the property in Properties is set to 0x1, that is, when MUST_USE_PROPERTY, node[propName]=value adds the property name set of the property
   *
   * DOMMutationMethods: Stores the method set for setting property values, such as {propName:(node,value)=>{}}
   */
  // Load the node attribute plugin and inject content for DOMProperty.properties, DOMProperty._isCustomAttributeFunctions
  injectDOMPropertyConfig: function (domPropertyConfig) {
    var Injection = DOMPropertyInjection;

    // Set the collection of attribute value type processing methods, such as an attribute value of 0x4, otherwise the value will not be added as an attribute of the node
    var Properties = domPropertyConfig.Properties || {};

    // A collection of convention property namespaces
    var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {};

    // The mapping of react property names to browser node property names, such as {className:"class"}
    var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};

    // namespace to store properties
    var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};

    // A set of methods for storing set property values, such as {propName:(node,value)=>{}}
    var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};

    // Custom attribute verification, if passed, it will be added to the corresponding attribute of the node, such as data-, aria- of HTMLDOMPropertyConfig module
    if (domPropertyConfig.isCustomAttribute) {
      DOMProperty._isCustomAttributeFunctions.push (domPropertyConfig.isCustomAttribute);
    }

    for (var propName in Properties) {
      // Attributes with the same name cannot be loaded twice, that is, the attribute names of each node attribute plug-in cannot collide
      !!DOMProperty.properties.hasOwnProperty(propName) ?
        process.env.NODE_ENV !== 'production' ?
          invariant(false, 'injectDOMPropertyConfig(...):'
            + ' You\'re trying to inject DOM property \'%s\' which has already been injected.'
            + ' You may be accidentally injecting the same DOM property config twice,'
            + ' or you may be injecting two configs that have conflicting property names.', propName)
          : _prodInvariant ('48 ', propName): void 0;

      var lowerCased = propName.toLowerCase();

      // In the node property plugin, propName refers to the property name, Properties[propName] convention type
      // Properties[propName] does bitwise AND comparison with DOMPropertyInjection.HAS_NUMERIC_VALUE and other properties
      // When the two are equal, the property value must be set to the literal type of the property such as DOMPropertyInjection.HAS_NUMERIC_VALUE
      // That is, DOMPropertyInjection.HAS_NUMERIC_VALUE requires the property of the node to be a value
      var propConfig = Properties[propName];

      var propertyInfo =
        // When adding a node attribute by splicing strings, it is used as the attribute name
        attributeName: lowerCased,

        // attribute namespace, node.setAttributeNS(namespace,attr,value) adds attributes; initialized to null
        attributeNamespace: null,

        // When propertyInfo.mustUseProperty is true, node[propertyInfo[propertyName]] is used as the property name of the node when setting the property of the node
        propertyName: propName,

        // Method for setting property value, (node, value)=>{} form; initialized to null
        mutationMethod: null,

        // When true, use node[propertyInfo[propertyName]] to set the attribute of the node instead of the setAttribute method
        // Handle the compatibility problem of ie8, 9setAttribute method converting attribute value to string `[object]`
        mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY),

        // Used to set the type of node attribute value, such as hasNumericValue attribute is true value, attribute value type is numeric type
        hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE),
        hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE),
        hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE),
        hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE)
      };

      // The type setting of the attribute value conflicts, if it cannot be both boolean and numeric
      !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue +
        propertyInfo.hasOverloadedBooleanValue <= 1) ?
          process.env.NODE_ENV !== 'production' ?
            invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean,'
              + ' or numeric value, but not a combination: %s', propName) :
            _prodInvariant ('50 ', propName):
          void 0;

      if (process.env.NODE_ENV !== 'production') {
        DOMProperty.getPossibleStandardName[lowerCased] = propName;
      }

      // The DOMAttributeNames attribute of the node attribute plugin is the mapping from the react attribute name to the browser node attribute name, such as className is mapped to class
      // Used when concatenating property names and their values ​​as strings
      if (DOMAttributeNames.hasOwnProperty(propName)) {
        var attributeName = DOMAttributeNames[propName];
        propertyInfo.attributeName = attributeName;
        if (process.env.NODE_ENV !== 'production') {
          DOMProperty.getPossibleStandardName[attributeName] = propName;
        }
      }

      // Extract the namespace of the node attribute plugin DOMAttributeNamespaces
      if (DOMAttributeNamespaces.hasOwnProperty(propName)) {
        propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName];
      }

      // DOMPropertyNames stores the set of property names that can be added when propertyInfo.mustUseProperty is true
      if (DOMPropertyNames.hasOwnProperty(propName)) {
        propertyInfo.propertyName = DOMPropertyNames[propName];
      }

      // propertyInfo.mutationMethod method to set property value, (node, value)=>{} form
      if (DOMMutationMethods.hasOwnProperty(propName)) {
        propertyInfo.mutationMethod = DOMMutationMethods[propName];
      }

      DOMProperty.properties[propName] = propertyInfo;
    }
  }
};

var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';

var DOMProperty = {

  ID_ATTRIBUTE_NAME: 'data-reactid',
  ROOT_ATTRIBUTE_NAME: 'data-reactroot',

  // used to verify the property name
  ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR,
  ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040',

  /** Set the attribute name to add or remove method

   * attributeName: the way to concatenate strings

   * attributeNamespace: the namespace of the attribute

   * propertyName: When mustUseProperty is true, when adding or removing properties by node[propName], it is used as propName

   * mutationMethod: The method of setting the attribute value, in the form of (node, value)=>{}, with the highest priority

   * mustUseProperty: whether to set the properties of the node with node[propertyInfo[propertyName]] instead of the setAttribute method

   * Set the extraction method of attribute value
   * hasBooleanValue: When the attribute value is set to no value, it is not added to the dom element
   * hasNumericValue: The attribute value must be set to a numeric value or a string that can be converted to a numeric value, otherwise it will not be added to the dom element
   * hasPositiveNumericValue: The attribute value must be set to a positive number, otherwise it will not be added to the dom element
   * hasOverloadedBooleanValue: When the attribute value is false, it is not added to the dom element
   */
  properties: {},

  // Store the mapping of node attributes in lowercase to react node attributes, such as {class:"className"}, etc.; for debugging
  getPossibleStandardName: process.env.NODE_ENV !== 'production' ? { autofocus: 'autoFocus' } : null,

  // Store the isCustomAttribute method of each node attribute plug-in, such as the isCustomAttribute method of the HTMLDOMPropertyConfig module
  _isCustomAttributeFunctions: [],

  // Whether it is allowed to set the custom attribute attributeName of the dom node, for example, the HTMLDOMPropertyConfig module sets the attribute name starting with data- or aria-
  isCustomAttribute: function (attributeName) {
    for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {
      var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions [i];
      if (isCustomAttributeFn(attributeName)) {
        return true;
      }
    }
    return false;
  },

  // Load node property plugins through ReactDefaultInjection module, such as ARIADOMPropertyConfig, HTMLDOMPropertyConfig, SVGDOMPropertyConfig
  // Finally inject content for the current module's DOMProperty.properties, DOMProperty._isCustomAttributeFunctions
  injection: DOMPropertyInjection
};

module.exports = DOMProperty;

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326817940&siteId=291194637