Merge pull request #1184 from spicyj/setInnerHTML

Consolidate innerHTML setting logic
This commit is contained in:
Cheng Lou
2014-04-12 00:58:37 -07:00
3 changed files with 68 additions and 32 deletions
@@ -28,6 +28,7 @@ var ReactReconcileTransaction = require('ReactReconcileTransaction');
var getReactRootElementInContainer = require('getReactRootElementInContainer');
var invariant = require('invariant');
var setInnerHTML = require('setInnerHTML');
var ELEMENT_NODE_TYPE = 1;
@@ -113,7 +114,7 @@ var ReactComponentBrowserEnvironment = {
'See renderComponentToString() for server rendering.'
);
container.innerHTML = markup;
setInnerHTML(container, markup);
}
)
};
+2 -31
View File
@@ -28,6 +28,7 @@ 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()`.
@@ -41,8 +42,6 @@ var INVALID_PROPERTY_ERRORS = {
style: '`style` must be set using `updateStylesByID()`.'
};
var useWhitespaceWorkaround;
/**
* Operations used to process updates to DOM nodes. This is made injectable via
* `ReactComponent.BackendIDOperations`.
@@ -131,35 +130,7 @@ var ReactDOMIDOperations = {
'updateInnerHTMLByID',
function(id, html) {
var node = ReactMount.getNode(id);
// IE8: When updating a just created node with innerHTML only leading
// whitespace is removed. When updating an existing node with innerHTML
// whitespace in root TextNodes is also collapsed.
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
if (useWhitespaceWorkaround === undefined) {
// Feature detection; only IE8 is known to behave improperly like this.
var temp = document.createElement('div');
temp.innerHTML = ' ';
useWhitespaceWorkaround = temp.innerHTML === '';
}
if (useWhitespaceWorkaround) {
// Magic theory: IE8 supposedly differentiates between added and updated
// nodes when processing innerHTML, innerHTML on updated nodes suffers
// from worse whitespace behavior. Re-adding a node like this triggers
// the initial and more favorable whitespace behavior.
node.parentNode.replaceChild(node, node);
}
if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) {
// Recover leading whitespace by temporarily prepending any character.
// \uFEFF has the potential advantage of being zero-width/invisible.
node.innerHTML = '\uFEFF' + html;
node.firstChild.deleteData(0, 1);
} else {
node.innerHTML = html;
}
setInnerHTML(node, html);
}
),
+64
View File
@@ -0,0 +1,64 @@
/**
* Copyright 2013-2014 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 setInnerHTML
*/
"use strict";
var ExecutionEnvironment = require('ExecutionEnvironment');
/**
* Set the innerHTML property of a node, ensuring that whitespace is preserved
* even in IE8.
*
* @param {DOMElement} node
* @param {string} html
* @internal
*/
var setInnerHTML = function(node, html) {
node.innerHTML = html;
};
if (ExecutionEnvironment.canUseDOM) {
// IE8: When updating a just created node with innerHTML only leading
// whitespace is removed. When updating an existing node with innerHTML
// whitespace in root TextNodes is also collapsed.
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
// Feature detection; only IE8 is known to behave improperly like this.
var testElement = document.createElement('div');
testElement.innerHTML = ' ';
if (testElement.innerHTML === '') {
setInnerHTML = function(node, html) {
// Magic theory: IE8 supposedly differentiates between added and updated
// nodes when processing innerHTML, innerHTML on updated nodes suffers
// from worse whitespace behavior. Re-adding a node like this triggers
// the initial and more favorable whitespace behavior.
node.parentNode.replaceChild(node, node);
if (html.match(/^[ \r\n\t\f]/)) {
// Recover leading whitespace by temporarily prepending any character.
// \uFEFF has the potential advantage of being zero-width/invisible.
node.innerHTML = '\uFEFF' + html;
node.firstChild.deleteData(0, 1);
} else {
node.innerHTML = html;
}
};
}
}
module.exports = setInnerHTML;