Allow DOM Nodes in ImmutableObject
Currently, `ImmutableObject` will stack overflow while it tries to recurse and deep freeze all the properties of a DOM node.
Tim Yung committed
Aug 19, 2013 at 11:26 UTC
669f4b867f09cb47e603fe58e3d0174d31053769
3 files changed
+43
src/utils/ImmutableObject.js
+4
@@ -20,6 +20,7 @@
20
"use strict";
21
22
var invariant = require('invariant');
23
+var isDOMNode = require('isDOMNode');
24
var merge = require('merge');
25
var mergeInto = require('mergeInto');
26
var mergeHelpers = require('mergeHelpers');
@@ -75,6 +76,9 @@ if (__DEV__) {
76
* @param {*} object The object to freeze.
77
*/
78
var deepFreeze = function(object) {
79
+ if (isDOMNode(object)) {
80
+ return; // Don't try to freeze DOM nodes.
81
+ }
82
Object.freeze(object); // First freeze the object.
83
for (var prop in object) {
84
var field = object[prop];
src/utils/__tests__/ImmutableObject-test.js
+6
@@ -89,6 +89,12 @@ describe('ImmutableObject', function() {
89
}).not.toThrow();
90
});
91
92
+ testDev('should not exceed maximum call stack size with nodes', function() {
93
+ var node = document.createElement('div');
94
+ var object = new ImmutableObject({node: node});
95
+ expect(object.node).toBe(node);
96
+ });
97
+
98
testDevAndProd('should not throw when not mutating directly', function() {
99
var io = new ImmutableObject({oldField: 'asdf'});
100
expect(function() {
src/vendor/core/dom/isDOMNode.js
new
+33
@@ -0,0 +1,33 @@
1
+/**
2
+ * Copyright 2013 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 isDOMNode
17
+ * @typechecks
18
+ */
19
+
20
+/**
21
+ * @param {*} object The object to check.
22
+ * @return {boolean} Whether or not the object is a DOM node.
23
+ */
24
+function isDOMNode(object) {
25
+ return !!(object && (
26
+ typeof Node !== 'undefined' ? object instanceof Node :
27
+ typeof object === 'object' &&
28
+ typeof object.nodeType === 'number' &&
29
+ typeof object.nodeName === 'string'
30
+ ));
31
+}
32
+
33
+module.exports = isDOMNode;