@samitouri / QOS-React-2 / commits / 534e7c06e9

Consolidate innerHTML setting logic

See https://github.com/facebook/react/commit/7eb33ef#commitcomment-5447724.

Ben Alpert committed Feb 25, 2014 at 21:02 UTC 534e7c06e9c2446028a82e2e6c695a130ee7f061
3 files changed +68 -32
src/browser/ui/ReactComponentBrowserEnvironment.js
+2 -1
@@ -28,6 +28,7 @@ var ReactReconcileTransaction = require('ReactReconcileTransaction');
28
29 var getReactRootElementInContainer = require('getReactRootElementInContainer');
30 var invariant = require('invariant');
31 +var setInnerHTML = require('setInnerHTML');
32
33
34 var ELEMENT_NODE_TYPE = 1;
@@ -113,7 +114,7 @@ var ReactComponentBrowserEnvironment = {
114 'See renderComponentToString() for server rendering.'
115 );
116
116 - container.innerHTML = markup;
117 + setInnerHTML(container, markup);
118 }
119 )
120 };
src/browser/ui/ReactDOMIDOperations.js
+2 -31
@@ -28,6 +28,7 @@ var ReactMount = require('ReactMount');
28 var ReactPerf = require('ReactPerf');
29
30 var invariant = require('invariant');
31 +var setInnerHTML = require('setInnerHTML');
32
33 /**
34 * Errors for properties that should not be updated with `updatePropertyById()`.
@@ -41,8 +42,6 @@ var INVALID_PROPERTY_ERRORS = {
42 style: '`style` must be set using `updateStylesByID()`.'
43 };
44
44 -var useWhitespaceWorkaround;
45 -
45 /**
46 * Operations used to process updates to DOM nodes. This is made injectable via
47 * `ReactComponent.BackendIDOperations`.
@@ -131,35 +130,7 @@ var ReactDOMIDOperations = {
130 'updateInnerHTMLByID',
131 function(id, html) {
132 var node = ReactMount.getNode(id);
134 -
135 - // IE8: When updating a just created node with innerHTML only leading
136 - // whitespace is removed. When updating an existing node with innerHTML
137 - // whitespace in root TextNodes is also collapsed.
138 - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
139 -
140 - if (useWhitespaceWorkaround === undefined) {
141 - // Feature detection; only IE8 is known to behave improperly like this.
142 - var temp = document.createElement('div');
143 - temp.innerHTML = ' ';
144 - useWhitespaceWorkaround = temp.innerHTML === '';
145 - }
146 -
147 - if (useWhitespaceWorkaround) {
148 - // Magic theory: IE8 supposedly differentiates between added and updated
149 - // nodes when processing innerHTML, innerHTML on updated nodes suffers
150 - // from worse whitespace behavior. Re-adding a node like this triggers
151 - // the initial and more favorable whitespace behavior.
152 - node.parentNode.replaceChild(node, node);
153 - }
154 -
155 - if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) {
156 - // Recover leading whitespace by temporarily prepending any character.
157 - // \uFEFF has the potential advantage of being zero-width/invisible.
158 - node.innerHTML = '\uFEFF' + html;
159 - node.firstChild.deleteData(0, 1);
160 - } else {
161 - node.innerHTML = html;
162 - }
133 + setInnerHTML(node, html);
134 }
135 ),
136
src/browser/ui/dom/setInnerHTML.js new
+64
@@ -0,0 +1,64 @@
1 +/**
2 + * Copyright 2013-2014 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @providesModule setInnerHTML
17 + */
18 +
19 +"use strict";
20 +
21 +var ExecutionEnvironment = require('ExecutionEnvironment');
22 +
23 +/**
24 + * Set the innerHTML property of a node, ensuring that whitespace is preserved
25 + * even in IE8.
26 + *
27 + * @param {DOMElement} node
28 + * @param {string} html
29 + * @internal
30 + */
31 +var setInnerHTML = function(node, html) {
32 + node.innerHTML = html;
33 +};
34 +
35 +if (ExecutionEnvironment.canUseDOM) {
36 + // IE8: When updating a just created node with innerHTML only leading
37 + // whitespace is removed. When updating an existing node with innerHTML
38 + // whitespace in root TextNodes is also collapsed.
39 + // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
40 +
41 + // Feature detection; only IE8 is known to behave improperly like this.
42 + var testElement = document.createElement('div');
43 + testElement.innerHTML = ' ';
44 + if (testElement.innerHTML === '') {
45 + setInnerHTML = function(node, html) {
46 + // Magic theory: IE8 supposedly differentiates between added and updated
47 + // nodes when processing innerHTML, innerHTML on updated nodes suffers
48 + // from worse whitespace behavior. Re-adding a node like this triggers
49 + // the initial and more favorable whitespace behavior.
50 + node.parentNode.replaceChild(node, node);
51 +
52 + if (html.match(/^[ \r\n\t\f]/)) {
53 + // Recover leading whitespace by temporarily prepending any character.
54 + // \uFEFF has the potential advantage of being zero-width/invisible.
55 + node.innerHTML = '\uFEFF' + html;
56 + node.firstChild.deleteData(0, 1);
57 + } else {
58 + node.innerHTML = html;
59 + }
60 + };
61 + }
62 +}
63 +
64 +module.exports = setInnerHTML;