@samitouri / QOS-React-2 / commits / 669f4b867f

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;