diff options
Diffstat (limited to 'devtools/client/shared/components/reps/array.js')
-rw-r--r-- | devtools/client/shared/components/reps/array.js | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/devtools/client/shared/components/reps/array.js b/devtools/client/shared/components/reps/array.js new file mode 100644 index 000000000..8ec1443e1 --- /dev/null +++ b/devtools/client/shared/components/reps/array.js @@ -0,0 +1,186 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Make this available to both AMD and CJS environments +define(function (require, exports, module) { + // Dependencies + const React = require("devtools/client/shared/vendor/react"); + const { createFactories } = require("./rep-utils"); + const { Caption } = createFactories(require("./caption")); + + // Shortcuts + const DOM = React.DOM; + + /** + * Renders an array. The array is enclosed by left and right bracket + * and the max number of rendered items depends on the current mode. + */ + let ArrayRep = React.createClass({ + displayName: "ArrayRep", + + getTitle: function (object, context) { + return "[" + object.length + "]"; + }, + + arrayIterator: function (array, max) { + let items = []; + let delim; + + for (let i = 0; i < array.length && i < max; i++) { + try { + let value = array[i]; + + delim = (i == array.length - 1 ? "" : ", "); + + items.push(ItemRep({ + object: value, + // Hardcode tiny mode to avoid recursive handling. + mode: "tiny", + delim: delim + })); + } catch (exc) { + items.push(ItemRep({ + object: exc, + mode: "tiny", + delim: delim + })); + } + } + + if (array.length > max) { + let objectLink = this.props.objectLink || DOM.span; + items.push(Caption({ + object: objectLink({ + object: this.props.object + }, (array.length - max) + " moreā¦") + })); + } + + return items; + }, + + /** + * Returns true if the passed object is an array with additional (custom) + * properties, otherwise returns false. Custom properties should be + * displayed in extra expandable section. + * + * Example array with a custom property. + * let arr = [0, 1]; + * arr.myProp = "Hello"; + * + * @param {Array} array The array object. + */ + hasSpecialProperties: function (array) { + function isInteger(x) { + let y = parseInt(x, 10); + if (isNaN(y)) { + return false; + } + return x === y.toString(); + } + + let props = Object.getOwnPropertyNames(array); + for (let i = 0; i < props.length; i++) { + let p = props[i]; + + // Valid indexes are skipped + if (isInteger(p)) { + continue; + } + + // Ignore standard 'length' property, anything else is custom. + if (p != "length") { + return true; + } + } + + return false; + }, + + // Event Handlers + + onToggleProperties: function (event) { + }, + + onClickBracket: function (event) { + }, + + render: function () { + let mode = this.props.mode || "short"; + let object = this.props.object; + let items; + let brackets; + let needSpace = function (space) { + return space ? { left: "[ ", right: " ]"} : { left: "[", right: "]"}; + }; + + if (mode == "tiny") { + let isEmpty = object.length === 0; + items = [DOM.span({className: "length"}, isEmpty ? "" : object.length)]; + brackets = needSpace(false); + } else { + let max = (mode == "short") ? 3 : 300; + items = this.arrayIterator(object, max); + brackets = needSpace(items.length > 0); + } + + let objectLink = this.props.objectLink || DOM.span; + + return ( + DOM.span({ + className: "objectBox objectBox-array"}, + objectLink({ + className: "arrayLeftBracket", + object: object + }, brackets.left), + ...items, + objectLink({ + className: "arrayRightBracket", + object: object + }, brackets.right), + DOM.span({ + className: "arrayProperties", + role: "group"} + ) + ) + ); + }, + }); + + /** + * Renders array item. Individual values are separated by a comma. + */ + let ItemRep = React.createFactory(React.createClass({ + displayName: "ItemRep", + + render: function () { + const { Rep } = createFactories(require("./rep")); + + let object = this.props.object; + let delim = this.props.delim; + let mode = this.props.mode; + return ( + DOM.span({}, + Rep({object: object, mode: mode}), + delim + ) + ); + } + })); + + function supportsObject(object, type) { + return Array.isArray(object) || + Object.prototype.toString.call(object) === "[object Arguments]"; + } + + // Exports from this module + exports.ArrayRep = { + rep: ArrayRep, + supportsObject: supportsObject + }; +}); |