diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /devtools/client/shared/components/reps/grip.js | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'devtools/client/shared/components/reps/grip.js')
-rw-r--r-- | devtools/client/shared/components/reps/grip.js | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/devtools/client/shared/components/reps/grip.js b/devtools/client/shared/components/reps/grip.js new file mode 100644 index 000000000..c63ee19f3 --- /dev/null +++ b/devtools/client/shared/components/reps/grip.js @@ -0,0 +1,247 @@ +/* -*- 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) { + // ReactJS + const React = require("devtools/client/shared/vendor/react"); + // Dependencies + const { createFactories, isGrip } = require("./rep-utils"); + const { Caption } = createFactories(require("./caption")); + const { PropRep } = createFactories(require("./prop-rep")); + // Shortcuts + const { span } = React.DOM; + + /** + * Renders generic grip. Grip is client representation + * of remote JS object and is used as an input object + * for this rep component. + */ + const GripRep = React.createClass({ + displayName: "Grip", + + propTypes: { + object: React.PropTypes.object.isRequired, + mode: React.PropTypes.string, + isInterestingProp: React.PropTypes.func + }, + + getTitle: function (object) { + if (this.props.objectLink) { + return this.props.objectLink({ + object: object + }, object.class); + } + return object.class || "Object"; + }, + + safePropIterator: function (object, max) { + max = (typeof max === "undefined") ? 3 : max; + try { + return this.propIterator(object, max); + } catch (err) { + console.error(err); + } + return []; + }, + + propIterator: function (object, max) { + if (object.preview && Object.keys(object.preview).includes("wrappedValue")) { + const { Rep } = createFactories(require("./rep")); + + return [Rep({ + object: object.preview.wrappedValue, + mode: this.props.mode || "tiny", + defaultRep: Grip, + })]; + } + + // Property filter. Show only interesting properties to the user. + let isInterestingProp = this.props.isInterestingProp || ((type, value) => { + return ( + type == "boolean" || + type == "number" || + (type == "string" && value.length != 0) + ); + }); + + let properties = object.preview + ? object.preview.ownProperties + : {}; + let propertiesLength = object.preview && object.preview.ownPropertiesLength + ? object.preview.ownPropertiesLength + : object.ownPropertyLength; + + if (object.preview && object.preview.safeGetterValues) { + properties = Object.assign({}, properties, object.preview.safeGetterValues); + propertiesLength += Object.keys(object.preview.safeGetterValues).length; + } + + let indexes = this.getPropIndexes(properties, max, isInterestingProp); + if (indexes.length < max && indexes.length < propertiesLength) { + // There are not enough props yet. Then add uninteresting props to display them. + indexes = indexes.concat( + this.getPropIndexes(properties, max - indexes.length, (t, value, name) => { + return !isInterestingProp(t, value, name); + }) + ); + } + + const truncate = Object.keys(properties).length > max; + let props = this.getProps(properties, indexes, truncate); + if (truncate) { + // There are some undisplayed props. Then display "more...". + let objectLink = this.props.objectLink || span; + + props.push(Caption({ + object: objectLink({ + object: object + }, `${object.ownPropertyLength - max} moreā¦`) + })); + } + + return props; + }, + + /** + * Get props ordered by index. + * + * @param {Object} properties Props object. + * @param {Array} indexes Indexes of props. + * @param {Boolean} truncate true if the grip will be truncated. + * @return {Array} Props. + */ + getProps: function (properties, indexes, truncate) { + let props = []; + + // Make indexes ordered by ascending. + indexes.sort(function (a, b) { + return a - b; + }); + + indexes.forEach((i) => { + let name = Object.keys(properties)[i]; + let value = this.getPropValue(properties[name]); + + props.push(PropRep(Object.assign({}, this.props, { + mode: "tiny", + name: name, + object: value, + equal: ": ", + delim: i !== indexes.length - 1 || truncate ? ", " : "", + defaultRep: Grip + }))); + }); + + return props; + }, + + /** + * Get the indexes of props in the object. + * + * @param {Object} properties Props object. + * @param {Number} max The maximum length of indexes array. + * @param {Function} filter Filter the props you want. + * @return {Array} Indexes of interesting props in the object. + */ + getPropIndexes: function (properties, max, filter) { + let indexes = []; + + try { + let i = 0; + for (let name in properties) { + if (indexes.length >= max) { + return indexes; + } + + // Type is specified in grip's "class" field and for primitive + // values use typeof. + let value = this.getPropValue(properties[name]); + let type = (value.class || typeof value); + type = type.toLowerCase(); + + if (filter(type, value, name)) { + indexes.push(i); + } + i++; + } + } catch (err) { + console.error(err); + } + return indexes; + }, + + /** + * Get the actual value of a property. + * + * @param {Object} property + * @return {Object} Value of the property. + */ + getPropValue: function (property) { + let value = property; + if (typeof property === "object") { + let keys = Object.keys(property); + if (keys.includes("value")) { + value = property.value; + } else if (keys.includes("getterValue")) { + value = property.getterValue; + } + } + return value; + }, + + render: function () { + let object = this.props.object; + let props = this.safePropIterator(object, + (this.props.mode == "long") ? 100 : 3); + + let objectLink = this.props.objectLink || span; + if (this.props.mode == "tiny") { + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, "") + ) + ); + } + + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, " { "), + ...props, + objectLink({ + className: "objectRightBrace", + object: object + }, " }") + ) + ); + }, + }); + + // Registration + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + return (object.preview && object.preview.ownProperties); + } + + let Grip = { + rep: GripRep, + supportsObject: supportsObject + }; + + // Exports from this module + exports.Grip = Grip; +}); |