summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/components/reps/grip-array.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/components/reps/grip-array.js')
-rw-r--r--devtools/client/shared/components/reps/grip-array.js198
1 files changed, 198 insertions, 0 deletions
diff --git a/devtools/client/shared/components/reps/grip-array.js b/devtools/client/shared/components/reps/grip-array.js
new file mode 100644
index 000000000..04a5603bb
--- /dev/null
+++ b/devtools/client/shared/components/reps/grip-array.js
@@ -0,0 +1,198 @@
+/* -*- 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, isGrip } = require("./rep-utils");
+ const { Caption } = createFactories(require("./caption"));
+
+ // Shortcuts
+ const { span } = 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 GripArray = React.createClass({
+ displayName: "GripArray",
+
+ propTypes: {
+ object: React.PropTypes.object.isRequired,
+ mode: React.PropTypes.string,
+ provider: React.PropTypes.object,
+ },
+
+ getLength: function (grip) {
+ if (!grip.preview) {
+ return 0;
+ }
+
+ return grip.preview.length || grip.preview.childNodesLength || 0;
+ },
+
+ getTitle: function (object, context) {
+ let objectLink = this.props.objectLink || span;
+ if (this.props.mode != "tiny") {
+ return objectLink({
+ object: object
+ }, object.class + " ");
+ }
+ return "";
+ },
+
+ getPreviewItems: function (grip) {
+ if (!grip.preview) {
+ return null;
+ }
+
+ return grip.preview.items || grip.preview.childNodes || null;
+ },
+
+ arrayIterator: function (grip, max) {
+ let items = [];
+ const gripLength = this.getLength(grip);
+
+ if (!gripLength) {
+ return items;
+ }
+
+ const previewItems = this.getPreviewItems(grip);
+ if (!previewItems) {
+ return items;
+ }
+
+ let delim;
+ // number of grip preview items is limited to 10, but we may have more
+ // items in grip-array.
+ let delimMax = gripLength > previewItems.length ?
+ previewItems.length : previewItems.length - 1;
+ let provider = this.props.provider;
+
+ for (let i = 0; i < previewItems.length && i < max; i++) {
+ try {
+ let itemGrip = previewItems[i];
+ let value = provider ? provider.getValue(itemGrip) : itemGrip;
+
+ delim = (i == delimMax ? "" : ", ");
+
+ items.push(GripArrayItem(Object.assign({}, this.props, {
+ object: value,
+ delim: delim
+ })));
+ } catch (exc) {
+ items.push(GripArrayItem(Object.assign({}, this.props, {
+ object: exc,
+ delim: delim
+ })));
+ }
+ }
+ if (previewItems.length > max || gripLength > previewItems.length) {
+ let objectLink = this.props.objectLink || span;
+ let leftItemNum = gripLength - max > 0 ?
+ gripLength - max : gripLength - previewItems.length;
+ items.push(Caption({
+ object: objectLink({
+ object: this.props.object
+ }, leftItemNum + " more…")
+ }));
+ }
+
+ return items;
+ },
+
+ 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 objectLength = this.getLength(object);
+ let isEmpty = objectLength === 0;
+ items = [span({className: "length"}, isEmpty ? "" : objectLength)];
+ 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 || span;
+ let title = this.getTitle(object);
+
+ return (
+ span({
+ className: "objectBox objectBox-array"},
+ title,
+ objectLink({
+ className: "arrayLeftBracket",
+ object: object
+ }, brackets.left),
+ ...items,
+ objectLink({
+ className: "arrayRightBracket",
+ object: object
+ }, brackets.right),
+ span({
+ className: "arrayProperties",
+ role: "group"}
+ )
+ )
+ );
+ },
+ });
+
+ /**
+ * Renders array item. Individual values are separated by
+ * a delimiter (a comma by default).
+ */
+ let GripArrayItem = React.createFactory(React.createClass({
+ displayName: "GripArrayItem",
+
+ propTypes: {
+ delim: React.PropTypes.string,
+ },
+
+ render: function () {
+ let { Rep } = createFactories(require("./rep"));
+
+ return (
+ span({},
+ Rep(Object.assign({}, this.props, {
+ mode: "tiny"
+ })),
+ this.props.delim
+ )
+ );
+ }
+ }));
+
+ function supportsObject(grip, type) {
+ if (!isGrip(grip)) {
+ return false;
+ }
+
+ return (grip.preview && (
+ grip.preview.kind == "ArrayLike" ||
+ type === "DocumentFragment"
+ )
+ );
+ }
+
+ // Exports from this module
+ exports.GripArray = {
+ rep: GripArray,
+ supportsObject: supportsObject
+ };
+});