Handle keys that are in the default object's prototype chain.

This may seem a bit improbable at first, but I ran into this when
testing something unrelated in Firefox, which turns out to have:

  "watch" in {} === true
This commit is contained in:
Jason Davies 2012-02-20 03:18:10 +00:00
Родитель 3081dd45ef
Коммит 1e63be0cdd
4 изменённых файлов: 22 добавлений и 11 удалений

9
d3.v2.js поставляемый
Просмотреть файл

@ -1709,7 +1709,7 @@ d3_selectionPrototype.data = function(data, join) {
for (i = -1; ++i < n;) { for (i = -1; ++i < n;) {
key = join.call(node = group[i], node.__data__, i); key = join.call(node = group[i], node.__data__, i);
if (key in nodeByKey) { if (nodeByKey.hasOwnProperty(key)) {
exitNodes[j++] = node; // duplicate key exitNodes[j++] = node; // duplicate key
} else { } else {
nodeByKey[key] = node; nodeByKey[key] = node;
@ -1718,8 +1718,9 @@ d3_selectionPrototype.data = function(data, join) {
} }
for (i = -1; ++i < m;) { for (i = -1; ++i < m;) {
node = nodeByKey[key = join.call(groupData, nodeData = groupData[i], i)]; key = join.call(groupData, nodeData = groupData[i], i)
if (node) { if (nodeByKey.hasOwnProperty(key)) {
node = nodeByKey[key];
node.__data__ = nodeData; node.__data__ = nodeData;
updateNodes[i] = node; updateNodes[i] = node;
enterNodes[i] = exitNodes[i] = null; enterNodes[i] = exitNodes[i] = null;
@ -1731,7 +1732,7 @@ d3_selectionPrototype.data = function(data, join) {
} }
for (i = -1; ++i < n;) { for (i = -1; ++i < n;) {
if (keys[i] in nodeByKey) { if (nodeByKey.hasOwnProperty(keys[i])) {
exitNodes[i] = group[i]; exitNodes[i] = group[i];
} }
} }

6
d3.v2.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -24,7 +24,7 @@ d3_selectionPrototype.data = function(data, join) {
for (i = -1; ++i < n;) { for (i = -1; ++i < n;) {
key = join.call(node = group[i], node.__data__, i); key = join.call(node = group[i], node.__data__, i);
if (key in nodeByKey) { if (nodeByKey.hasOwnProperty(key)) {
exitNodes[j++] = node; // duplicate key exitNodes[j++] = node; // duplicate key
} else { } else {
nodeByKey[key] = node; nodeByKey[key] = node;
@ -33,8 +33,9 @@ d3_selectionPrototype.data = function(data, join) {
} }
for (i = -1; ++i < m;) { for (i = -1; ++i < m;) {
node = nodeByKey[key = join.call(groupData, nodeData = groupData[i], i)]; key = join.call(groupData, nodeData = groupData[i], i)
if (node) { if (nodeByKey.hasOwnProperty(key)) {
node = nodeByKey[key];
node.__data__ = nodeData; node.__data__ = nodeData;
updateNodes[i] = node; updateNodes[i] = node;
enterNodes[i] = exitNodes[i] = null; enterNodes[i] = exitNodes[i] = null;
@ -46,7 +47,7 @@ d3_selectionPrototype.data = function(data, join) {
} }
for (i = -1; ++i < n;) { for (i = -1; ++i < n;) {
if (keys[i] in nodeByKey) { if (nodeByKey.hasOwnProperty(keys[i])) {
exitNodes[i] = group[i]; exitNodes[i] = group[i];
} }
} }

Просмотреть файл

@ -160,6 +160,15 @@ suite.addBatch({
assert.domNull(exit[0][1]); assert.domNull(exit[0][1]);
assert.domEqual(exit[1][0], span[1][0]); assert.domEqual(exit[1][0], span[1][0]);
assert.domNull(exit[1][1]); assert.domNull(exit[1][1]);
},
"handles keys that are in the default object's prototype chain": function(span) {
// This also applies to the non-standard "watch" and "unwatch" in Mozilla Firefox.
var update = span.data(["hasOwnProperty", "isPrototypeOf", "toLocaleString", "toString", "valueOf"], String);
assert.domNull(update[0][0]);
assert.domNull(update[0][1]);
assert.domNull(update[0][2]);
assert.domNull(update[0][3]);
assert.domNull(update[0][4]);
} }
} }
}); });