/** * Copyright 2013-2015, 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 ReactDOMIDOperations * @typechecks static-only */ /*jslint evil: true */ 'use strict'; var CSSPropertyOperations = require("./CSSPropertyOperations"); var DOMChildrenOperations = require("./DOMChildrenOperations"); var DOMPropertyOperations = require("./DOMPropertyOperations"); var ReactMount = require("./ReactMount"); var ReactPerf = require("./ReactPerf"); var invariant = require("./invariant"); var setInnerHTML = require("./setInnerHTML"); /** * Errors for properties that should not be updated with `updatePropertyById()`. * * @type {object} * @private */ var INVALID_PROPERTY_ERRORS = { dangerouslySetInnerHTML: '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', style: '`style` must be set using `updateStylesByID()`.' }; /** * Operations used to process updates to DOM nodes. This is made injectable via * `ReactDOMComponent.BackendIDOperations`. */ var ReactDOMIDOperations = { /** * Updates a DOM node with new property values. This should only be used to * update DOM properties in `DOMProperty`. * * @param {string} id ID of the node to update. * @param {string} name A valid property name, see `DOMProperty`. * @param {*} value New value of the property. * @internal */ updatePropertyByID: function(id, name, value) { var node = ReactMount.getNode(id); ("production" !== process.env.NODE_ENV ? invariant( !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name] ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); // If we're updating to null or undefined, we should remove the property // from the DOM node instead of inadvertantly setting to a string. This // brings us in line with the same behavior we have on initial render. if (value != null) { DOMPropertyOperations.setValueForProperty(node, name, value); } else { DOMPropertyOperations.deleteValueForProperty(node, name); } }, /** * Updates a DOM node to remove a property. This should only be used to remove * DOM properties in `DOMProperty`. * * @param {string} id ID of the node to update. * @param {string} name A property name to remove, see `DOMProperty`. * @internal */ deletePropertyByID: function(id, name, value) { var node = ReactMount.getNode(id); ("production" !== process.env.NODE_ENV ? invariant( !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name] ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); DOMPropertyOperations.deleteValueForProperty(node, name, value); }, /** * Updates a DOM node with new style values. If a value is specified as '', * the corresponding style property will be unset. * * @param {string} id ID of the node to update. * @param {object} styles Mapping from styles to values. * @internal */ updateStylesByID: function(id, styles) { var node = ReactMount.getNode(id); CSSPropertyOperations.setValueForStyles(node, styles); }, /** * Updates a DOM node's innerHTML. * * @param {string} id ID of the node to update. * @param {string} html An HTML string. * @internal */ updateInnerHTMLByID: function(id, html) { var node = ReactMount.getNode(id); setInnerHTML(node, html); }, /** * Updates a DOM node's text content set by `props.content`. * * @param {string} id ID of the node to update. * @param {string} content Text content. * @internal */ updateTextContentByID: function(id, content) { var node = ReactMount.getNode(id); DOMChildrenOperations.updateTextContent(node, content); }, /** * Replaces a DOM node that exists in the document with markup. * * @param {string} id ID of child to be replaced. * @param {string} markup Dangerous markup to inject in place of child. * @internal * @see {Danger.dangerouslyReplaceNodeWithMarkup} */ dangerouslyReplaceNodeWithMarkupByID: function(id, markup) { var node = ReactMount.getNode(id); DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); }, /** * Updates a component's children by processing a series of updates. * * @param {array} updates List of update configurations. * @param {array} markup List of markup strings. * @internal */ dangerouslyProcessChildrenUpdates: function(updates, markup) { for (var i = 0; i < updates.length; i++) { updates[i].parentNode = ReactMount.getNode(updates[i].parentID); } DOMChildrenOperations.processUpdates(updates, markup); } }; ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', { updatePropertyByID: 'updatePropertyByID', deletePropertyByID: 'deletePropertyByID', updateStylesByID: 'updateStylesByID', updateInnerHTMLByID: 'updateInnerHTMLByID', updateTextContentByID: 'updateTextContentByID', dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID', dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates' }); module.exports = ReactDOMIDOperations;