diff --git a/src/vendor/core/$.js b/src/vendor/core/$.js index 3918051c6b..c255eb3570 100644 --- a/src/vendor/core/$.js +++ b/src/vendor/core/$.js @@ -17,7 +17,6 @@ * @typechecks */ -var ge = require('ge'); var ex = require('ex'); /** @@ -28,12 +27,9 @@ var ex = require('ex'); * * If you're not sure whether or not the element exists, use ge instead, and * manually check for the element's existence in your application code. - * - * @param {string|DOMDocument|DOMElement|DOMTextNode|Comment} id - * @return {DOMDocument|DOMElement|DOMTextNode|Comment} */ -function $(id) { - var element = ge(id); +function getRequiredElement(id) { + var element = typeof id === 'string' ? document.getElementById(id) : id; if (!element) { throw new Error(ex( 'Tried to get element with id of "%s" but it is not present on the page.', @@ -43,4 +39,23 @@ function $(id) { return element; } +/** + * Find a node by ID with typechecked input and output. + * + * @param {string|DOMDocument|DOMElement|DOMTextNode|Comment} id + * @return {DOMDocument|DOMElement|DOMTextNode|Comment} + */ +function $(id) { + return getRequiredElement(id); +} + +/** + * Find a node by ID without typechecks. + * + * This is micro-optimization for the small subset of users who have typechecks + * enabled. It should only be used by frequently called core modules that are + * already checking their params and return values. + */ +$.unsafe = getRequiredElement; + module.exports = $; diff --git a/src/vendor/core/createArrayFrom.js b/src/vendor/core/createArrayFrom.js index 22d1c75cde..aed52557d5 100644 --- a/src/vendor/core/createArrayFrom.js +++ b/src/vendor/core/createArrayFrom.js @@ -17,11 +17,9 @@ * @typechecks */ +var toArray = require('toArray'); + /** - * NOTE: if you are a previous user of this function, it has been considered - * unsafe because it's inconsistent across browsers for some inputs. - * Instead use `Array.isArray()`. - * * Perform a heuristic test to determine if an object is "array-like". * * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" @@ -31,6 +29,8 @@ * true if the argument is an actual array, an `arguments' object, or an * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). * + * It will return false for other array-like objects like Filelist. + * * @param {*} obj * @return {boolean} */ @@ -73,8 +73,8 @@ function hasArrayNature(obj) { * * This allows you to treat `things' as an array, but accept scalars in the API. * - * This is also good for converting certain pseudo-arrays, like `arguments` or - * HTMLCollections, into arrays. + * If you need to convert an array-like object, like `arguments`, into an array + * use toArray instead. * * @param {*} obj * @return {array} @@ -82,14 +82,11 @@ function hasArrayNature(obj) { function createArrayFrom(obj) { if (!hasArrayNature(obj)) { return [obj]; + } else if (Array.isArray(obj)) { + return obj.slice(); + } else { + return toArray(obj); } - if (obj.item) { - // IE does not support Array#slice on HTMLCollections - var l = obj.length, ret = new Array(l); - while (l--) { ret[l] = obj[l]; } - return ret; - } - return Array.prototype.slice.call(obj); } module.exports = createArrayFrom; diff --git a/src/vendor/core/dom/getActiveElement.js b/src/vendor/core/dom/getActiveElement.js index bcee74a0d1..b71ef780d7 100644 --- a/src/vendor/core/dom/getActiveElement.js +++ b/src/vendor/core/dom/getActiveElement.js @@ -20,14 +20,15 @@ /** * Same as document.activeElement but wraps in a try-catch block. In IE it is * not safe to call document.activeElement if there is nothing focused. + * + * The activeElement will be null only if the document body is not yet defined. */ function getActiveElement() /*?DOMElement*/ { try { - return document.activeElement; + return document.activeElement || document.body; } catch (e) { - return null; + return document.body; } } module.exports = getActiveElement; - diff --git a/src/vendor/core/ge.js b/src/vendor/core/ge.js deleted file mode 100644 index 76dd2e7423..0000000000 --- a/src/vendor/core/ge.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright 2013 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 ge - */ - -/** - * Find a node by ID. Optionally search a sub-tree outside of the document - * - * Use ge if you're not sure whether or not the element exists. You can test - * for existence yourself in your application code. - * - * If your application code depends on the existence of the element, use $ - * instead, which will throw in DEV if the element doesn't exist. - */ -function ge(arg, root, tag) { - return typeof arg != 'string' ? arg : - !root ? document.getElementById(arg) : - _geFromSubtree(arg, root, tag); -} - -function _geFromSubtree(id, root, tag) { - var elem, children, ii; - - if (_getNodeID(root) == id) { - return root; - } else if (root.getElementsByTagName) { - // All Elements implement this, which does an iterative DFS, which is - // faster than recursion and doesn't run into stack depth issues. - children = root.getElementsByTagName(tag || '*'); - for (ii = 0; ii < children.length; ii++) { - if (_getNodeID(children[ii]) == id) { - return children[ii]; - } - } - } else { - // DocumentFragment does not implement getElementsByTagName, so - // recurse over its children. Its children must be Elements, so - // each child will use the getElementsByTagName case instead. - children = root.childNodes; - for (ii = 0; ii < children.length; ii++) { - elem = _geFromSubtree(id, children[ii]); - if (elem) { - return elem; - } - } - } - - return null; -} - -/** - * Return the ID value for a given node. This allows us to avoid issues - * with forms that contain inputs with name="id". - * - * @return string (null if attribute not set) - */ -function _getNodeID(node) { - // #document and #document-fragment do not have getAttributeNode. - var id = node.getAttributeNode && node.getAttributeNode('id'); - return id ? id.value : null; -} - -module.exports = ge; diff --git a/src/vendor/core/getMarkupWrap.js b/src/vendor/core/getMarkupWrap.js index 2b21b275e1..eb64525866 100644 --- a/src/vendor/core/getMarkupWrap.js +++ b/src/vendor/core/getMarkupWrap.js @@ -39,6 +39,7 @@ var shouldWrap = { 'g': true, 'line': true, 'path': true, + 'polygon': true, 'polyline': true, 'rect': true, 'text': true @@ -75,6 +76,7 @@ var markupWrap = { 'g': svgWrap, 'line': svgWrap, 'path': svgWrap, + 'polygon': svgWrap, 'polyline': svgWrap, 'rect': svgWrap, 'text': svgWrap diff --git a/src/vendor/core/invariant.js b/src/vendor/core/invariant.js index 549211d312..a3c94ed554 100644 --- a/src/vendor/core/invariant.js +++ b/src/vendor/core/invariant.js @@ -1,26 +1,13 @@ /** - * Copyright 2013 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 invariant */ /** * Use invariant() to assert state which your program assumes to be true. * - * Provide sprintf style format and arguments to provide information about - * what broke and what you were expecting. + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. @@ -28,7 +15,9 @@ function invariant(condition) { if (!condition) { - throw new Error('Invariant Violation'); + var error = new Error('Invariant Violation'); + error.framesToPop = 1; + throw error; } } @@ -43,10 +32,12 @@ if (__DEV__) { if (!condition) { var args = [a, b, c, d, e, f]; var argIndex = 0; - throw new Error( + var error = new Error( 'Invariant Violation: ' + format.replace(/%s/g, function() { return args[argIndex++]; }) ); + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; } }; diff --git a/src/vendor/core/toArray.js b/src/vendor/core/toArray.js new file mode 100644 index 0000000000..d0e4857e58 --- /dev/null +++ b/src/vendor/core/toArray.js @@ -0,0 +1,73 @@ +/** + * Copyright 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 toArray + * @typechecks + */ + +var invariant = require('invariant'); + +/** + * Convert array-like objects to arrays. + * + * This API assumes the caller knows the contents of the data type. For less + * well defined inputs use createArrayFrom. + * + * @param {object|function} obj + * @return {array} + */ +function toArray(obj) { + var length = obj.length; + + // Some browse builtin objects can report typeof 'function' (e.g. NodeList in + // old versions of Safari). + invariant( + !Array.isArray(obj) && + (typeof obj === 'object' || typeof obj === 'function'), + 'toArray: Array-like object expected' + ); + + invariant( + typeof length === 'number', + 'toArray: Object needs a length property' + ); + + invariant( + length === 0 || + (length - 1) in obj, + 'toArray: Object should have keys for indices' + ); + + // Old IE doesn't give collections access to hasOwnProperty. Assume inputs + // without method will throw during the slice call and skip straight to the + // fallback. + if (obj.hasOwnProperty) { + try { + return Array.prototype.slice.call(obj); + } catch (e) { + // IE < 9 does not support Array#slice on collections objects + } + } + + // Fall back to copying key by key. This assumes all keys have a value, + // so will not preserve sparsely populated inputs. + var ret = Array(length); + for (var ii = 0; ii < length; ii++) { + ret[ii] = obj[ii]; + } + return ret; +} + +module.exports = toArray;