mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Consolidate ReactDOMNodeCache and getDOMNodeID into ReactID.
When we move away from using the "id" attribute to identify React-generated elements, we will need the cache (formerly ReactDOMNodeCache) to be tied much more closely to the code that looks elements up by ID (getDOMNodeID) and sets element IDs, since the magic of document.getElementById will no longer be available. The priming functions are going to come in handy when we create new DOM fragments in mountComponent. For backwards compatibility, the ReactDOMNodeCache and getDOMNodeID modules still exist, but they are implemented entirely in terms of functions exported from ReactID.
This commit is contained in:
committed by
Paul O’Shannessy
parent
2bc2b52eaa
commit
191c0dec32
@@ -19,70 +19,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var ExecutionEnvironment = require('ExecutionEnvironment');
|
||||
var ReactMount = require('ReactMount');
|
||||
var ReactID = require('ReactID');
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
var nodeCache = {};
|
||||
|
||||
/**
|
||||
* DOM node cache only intended for use by React. Placed into a shared module so
|
||||
* that both read and write utilities may benefit from a shared cache.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
var ReactDOMNodeCache = {
|
||||
|
||||
/**
|
||||
* Finds the node with the supplied React-generated DOM ID.
|
||||
*
|
||||
* @param {string} id A React-generated DOM ID.
|
||||
* @return {?DOMElement} DOM node with the suppled `id`.
|
||||
* @internal
|
||||
*/
|
||||
getNodeByID: function(id) {
|
||||
invariant(
|
||||
ExecutionEnvironment.canUseDOM,
|
||||
'getDOMNode(): The DOM is not supported in the current environment.'
|
||||
);
|
||||
if (!nodeCache[id]) {
|
||||
nodeCache[id] =
|
||||
document.getElementById(id) ||
|
||||
ReactMount.findReactRenderedDOMNodeSlow(id);
|
||||
}
|
||||
return nodeCache[id];
|
||||
},
|
||||
|
||||
/**
|
||||
* Purges the supplied ID from cache.
|
||||
*
|
||||
* @param {string} id A React-generated DOM ID.
|
||||
* @internal
|
||||
*/
|
||||
purgeID: function(id) {
|
||||
nodeCache[id] = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Purges the entire node cache used for fast ID lookups.
|
||||
*
|
||||
* This implementation is aggressive with purging because the bookkeeping
|
||||
* associated with doing fine-grained deletes from the cache may outweight the
|
||||
* benefits of the cache.
|
||||
*
|
||||
* The heuristic used to purge is 'any time anything is deleted'. Typically
|
||||
* this means that a large amount of content is being replaced and several
|
||||
* elements would need purging regardless. This is also when applications are
|
||||
* less likely to be in the middle of "smooth operations" such as animations
|
||||
* or scrolling.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
purgeEntireCache: function() {
|
||||
nodeCache = {};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ReactDOMNodeCache;
|
||||
exports.getNodeByID = ReactID.getNode;
|
||||
exports.purgeID = ReactID.purgeID;
|
||||
exports.purgeEntireCache = ReactID.purgeEntireCache;
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Copyright 2013 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @providesModule ReactID
|
||||
* @typechecks
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var ReactMount = require('ReactMount');
|
||||
var ATTR_NAME = 'id';
|
||||
var nodeCache = {};
|
||||
|
||||
/**
|
||||
* Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
|
||||
* element can return its control whose name or ID equals ATTR_NAME. All
|
||||
* DOM nodes support `getAttributeNode` but this can also get called on
|
||||
* other objects so just return '' if we're given something other than a
|
||||
* DOM node (such as window).
|
||||
*
|
||||
* @param {DOMElement|DOMWindow|DOMDocument} node DOM node.
|
||||
* @returns {string} ID of the supplied `domNode`.
|
||||
*/
|
||||
function getID(node) {
|
||||
if (node && node.getAttributeNode) {
|
||||
var attributeNode = node.getAttributeNode(ATTR_NAME);
|
||||
return attributeNode && attributeNode.value || '';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the React-specific ID of the given node.
|
||||
*
|
||||
* @param {DOMElement} node The DOM node whose ID will be set.
|
||||
* @param {string} id The value of the ID attribute.
|
||||
*/
|
||||
function setID(node, id) {
|
||||
var oldID = getID(node);
|
||||
if (oldID !== id) {
|
||||
delete nodeCache[oldID];
|
||||
}
|
||||
node.setAttribute(ATTR_NAME, id);
|
||||
nodeCache[id] = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the node with the supplied React-generated DOM ID.
|
||||
*
|
||||
* @param {string} id A React-generated DOM ID.
|
||||
* @return {?DOMElement} DOM node with the suppled `id`.
|
||||
* @internal
|
||||
*/
|
||||
function getNode(id) {
|
||||
if (!nodeCache.hasOwnProperty(id)) {
|
||||
nodeCache[id] =
|
||||
document.getElementById(id) || // TODO Quit using getElementById.
|
||||
ReactMount.findReactRenderedDOMNodeSlow(id);
|
||||
}
|
||||
|
||||
var node = nodeCache[id];
|
||||
if (getID(node) === id) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficiently finds all nodes with a React-specific ID and primes the
|
||||
* cache so that getNode lookups take constant time.
|
||||
*
|
||||
* @param {DOMElement} root The root element to scan.
|
||||
*/
|
||||
function primeTree(root) {
|
||||
var nodes = root.querySelectorAll
|
||||
? root.querySelectorAll('[' + ATTR_NAME + ']')
|
||||
: root.getElementsByTagName('*');
|
||||
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
prime(nodes.item(i));
|
||||
}
|
||||
|
||||
prime(root);
|
||||
}
|
||||
|
||||
function prime(node) {
|
||||
var attributeNode = node.getAttributeNode(ATTR_NAME);
|
||||
if (attributeNode) {
|
||||
nodeCache[attributeNode.value] = node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the cache to forget about one React-specific ID.
|
||||
*
|
||||
* @param {string} id The ID to forget.
|
||||
*/
|
||||
function purgeID(id) {
|
||||
delete nodeCache[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the entire cache.
|
||||
*/
|
||||
function purgeEntireCache() {
|
||||
nodeCache = {};
|
||||
}
|
||||
|
||||
exports.getID = getID;
|
||||
exports.setID = setID;
|
||||
exports.getNode = getNode;
|
||||
exports.primeTree = primeTree;
|
||||
exports.purgeID = purgeID;
|
||||
exports.purgeEntireCache = purgeEntireCache;
|
||||
+4
-17
@@ -19,22 +19,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Accessing "id" or calling getAttribute('id') on a form element can return its
|
||||
* control whose name or ID is "id". All DOM nodes support `getAttributeNode`
|
||||
* but this can also get called on other objects so just return '' if we're
|
||||
* given something other than a DOM node (such as window).
|
||||
*
|
||||
* @param {DOMElement|DOMWindow|DOMDocument} domNode DOM node.
|
||||
* @returns {string} ID of the supplied `domNode`.
|
||||
*/
|
||||
function getDOMNodeID(domNode) {
|
||||
if (domNode.getAttributeNode) {
|
||||
var attributeNode = domNode.getAttributeNode('id');
|
||||
return attributeNode && attributeNode.value || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
var ReactID = require('ReactID');
|
||||
|
||||
function getDOMNodeID(domNode) {
|
||||
return ReactID.getID(domNode);
|
||||
}
|
||||
module.exports = getDOMNodeID;
|
||||
|
||||
Reference in New Issue
Block a user