--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -65,33 +65,34 @@ return /******/ (function(modules) { //
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/build";
/******/
/******/ // Load entry module and return exports
-/******/ return __webpack_require__(__webpack_require__.s = 16);
+/******/ return __webpack_require__(__webpack_require__.s = 17);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
// Dependencies
const validProtocols = /^(http|https|ftp|data|javascript|resource|chrome):/i;
const tokenSplitRegex = /(\s|\'|\"|\\)+/;
+const ELLIPSIS = "\u2026";
const dom = __webpack_require__(1);
const { span } = dom;
/**
* Returns true if the given object is a grip (see RDP protocol)
*/
function isGrip(object) {
return object && object.actor;
@@ -213,21 +214,17 @@ function maybeEscapePropertyName(name) {
}
return name;
}
function cropMultipleLines(text, limit) {
return escapeNewLines(cropString(text, limit));
}
-function rawCropString(text, limit, alternativeText) {
- if (!alternativeText) {
- alternativeText = "\u2026";
- }
-
+function rawCropString(text, limit, alternativeText = ELLIPSIS) {
// Crop the string only if a limit is actually specified.
if (!limit || limit <= 0) {
return text;
}
// Set the limit at least to the length of the alternative text
// plus one character of the original text.
if (limit <= alternativeText.length) {
@@ -480,17 +477,18 @@ module.exports = {
cropMultipleLines,
parseURLParams,
parseURLEncodedText,
getFileName,
getURLDisplayString,
maybeEscapePropertyName,
getGripPreviewItems,
getGripType,
- tokenSplitRegex
+ tokenSplitRegex,
+ ELLIPSIS
};
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
@@ -525,50 +523,50 @@ module.exports = {
"use strict";
/* 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/. */
-__webpack_require__(17);
+__webpack_require__(18);
// Load all existing rep templates
-const Undefined = __webpack_require__(18);
-const Null = __webpack_require__(19);
+const Undefined = __webpack_require__(19);
+const Null = __webpack_require__(20);
const StringRep = __webpack_require__(7);
-const LongStringRep = __webpack_require__(20);
-const Number = __webpack_require__(21);
-const ArrayRep = __webpack_require__(9);
-const Obj = __webpack_require__(22);
-const SymbolRep = __webpack_require__(23);
-const InfinityRep = __webpack_require__(24);
-const NaNRep = __webpack_require__(25);
-const Accessor = __webpack_require__(26);
+const LongStringRep = __webpack_require__(21);
+const Number = __webpack_require__(22);
+const ArrayRep = __webpack_require__(10);
+const Obj = __webpack_require__(23);
+const SymbolRep = __webpack_require__(24);
+const InfinityRep = __webpack_require__(25);
+const NaNRep = __webpack_require__(26);
+const Accessor = __webpack_require__(27);
// DOM types (grips)
-const Attribute = __webpack_require__(27);
-const DateTime = __webpack_require__(28);
-const Document = __webpack_require__(29);
-const Event = __webpack_require__(30);
-const Func = __webpack_require__(31);
-const PromiseRep = __webpack_require__(32);
-const RegExp = __webpack_require__(33);
-const StyleSheet = __webpack_require__(34);
-const CommentNode = __webpack_require__(35);
-const ElementNode = __webpack_require__(36);
-const TextNode = __webpack_require__(40);
-const ErrorRep = __webpack_require__(41);
-const Window = __webpack_require__(42);
-const ObjectWithText = __webpack_require__(43);
-const ObjectWithURL = __webpack_require__(44);
-const GripArray = __webpack_require__(12);
-const GripMap = __webpack_require__(13);
-const GripMapEntry = __webpack_require__(14);
+const Attribute = __webpack_require__(28);
+const DateTime = __webpack_require__(29);
+const Document = __webpack_require__(30);
+const Event = __webpack_require__(31);
+const Func = __webpack_require__(32);
+const PromiseRep = __webpack_require__(36);
+const RegExp = __webpack_require__(37);
+const StyleSheet = __webpack_require__(38);
+const CommentNode = __webpack_require__(39);
+const ElementNode = __webpack_require__(40);
+const TextNode = __webpack_require__(41);
+const ErrorRep = __webpack_require__(42);
+const Window = __webpack_require__(43);
+const ObjectWithText = __webpack_require__(44);
+const ObjectWithURL = __webpack_require__(45);
+const GripArray = __webpack_require__(13);
+const GripMap = __webpack_require__(14);
+const GripMapEntry = __webpack_require__(15);
const Grip = __webpack_require__(8);
// List of all registered template.
// XXX there should be a way for extensions to register a new
// or modify an existing rep.
let reps = [RegExp, StyleSheet, Event, DateTime, CommentNode, ElementNode, TextNode, Attribute, LongStringRep, Func, PromiseRep, ArrayRep, Document, Window, ObjectWithText, ObjectWithURL, ErrorRep, GripArray, GripMap, GripMapEntry, Grip, Undefined, Null, StringRep, Number, SymbolRep, InfinityRep, NaNRep, Accessor];
/**
@@ -767,17 +765,18 @@ const PropTypes = __webpack_require__(2)
const {
containsURL,
isURL,
escapeString,
getGripType,
rawCropString,
sanitizeString,
wrapRender,
- tokenSplitRegex
+ tokenSplitRegex,
+ ELLIPSIS
} = __webpack_require__(0);
const dom = __webpack_require__(1);
const { a, span } = dom;
/**
* Renders a string. String value is enclosed within quotes.
*/
@@ -816,53 +815,127 @@ function StringRep(props) {
}
if (useQuotes) {
text = escapeString(text, escapeWhitespace);
} else {
text = sanitizeString(text);
}
- if ((!member || !member.open) && cropLimit) {
- text = rawCropString(text, cropLimit);
- }
-
+ const shouldCrop = (!member || !member.open) && cropLimit;
if (!containsURL(text)) {
+ if (shouldCrop) {
+ text = rawCropString(text, cropLimit);
+ }
return span(config, text);
}
- const items = [];
+ return span(config, ...getLinkifiedElements(text, shouldCrop && cropLimit, omitLinkHref, openLink));
+}
+
+/**
+ * Get an array of the elements representing the string, cropped if needed,
+ * with actual links.
+ *
+ * @param {String} text: The actual string to linkify.
+ * @param {Integer | null} cropLimit
+ * @param {Boolean} omitLinkHref: Do not create an href attribute if true.
+ * @param {Function} openLink: Function handling the link opening.
+ * @returns {Array<String|ReactElement>}
+ */
+function getLinkifiedElements(text, cropLimit, omitLinkHref, openLink) {
+ const halfLimit = Math.ceil((cropLimit - ELLIPSIS.length) / 2);
+ const startCropIndex = halfLimit;
+ const endCropIndex = text.length - halfLimit;
// As we walk through the tokens of the source string, we make sure to preserve
// the original whitespace that separated the tokens.
- let tokens = text.split(tokenSplitRegex);
- let textIndex = 0;
- let tokenStart;
- tokens.forEach((token, i) => {
- tokenStart = text.indexOf(token, textIndex);
+ let currentIndex = 0;
+ const items = [];
+ for (let token of text.split(tokenSplitRegex)) {
if (isURL(token)) {
- items.push(text.slice(textIndex, tokenStart));
- textIndex = tokenStart + token.length;
-
- items.push(a({
- className: "url",
- title: token,
- href: omitLinkHref === true ? null : token,
- draggable: false,
- onClick: openLink ? e => {
- e.preventDefault();
- openLink(token);
- } : null
- }, token));
+ // Let's grab all the non-url strings before the link.
+ const tokenStart = text.indexOf(token, currentIndex);
+ let nonUrlText = text.slice(currentIndex, tokenStart);
+ nonUrlText = getCroppedString(nonUrlText, currentIndex, startCropIndex, endCropIndex);
+ if (nonUrlText) {
+ items.push(nonUrlText);
+ }
+
+ // Update the index to match the beginning of the token.
+ currentIndex = tokenStart;
+
+ let linkText = getCroppedString(token, currentIndex, startCropIndex, endCropIndex);
+ if (linkText) {
+ items.push(a({
+ className: "url",
+ title: token,
+ href: omitLinkHref === true ? null : token,
+ draggable: false,
+ onClick: openLink ? e => {
+ e.preventDefault();
+ openLink(token);
+ } : null
+ }, linkText));
+ }
+
+ currentIndex = tokenStart + token.length;
+ }
+ }
+
+ // Clean up any non-URL text at the end of the source string,
+ // i.e. not handled in the loop.
+ if (currentIndex !== text.length) {
+ let nonUrlText = text.slice(currentIndex, text.length);
+ if (currentIndex < endCropIndex) {
+ const cutIndex = endCropIndex - currentIndex;
+ nonUrlText = nonUrlText.substring(cutIndex);
}
- });
-
- // Clean up any non-URL text at the end of the source string.
- items.push(text.slice(textIndex, text.length));
- return span(config, ...items);
+ items.push(nonUrlText);
+ }
+
+ return items;
+}
+
+/**
+ * Returns a cropped substring given an offset, start and end crop indices in a parent
+ * string.
+ *
+ * @param {String} text: The substring to crop.
+ * @param {Integer} offset: The offset corresponding to the index at which the substring
+ * is in the parent string.
+ * @param {Integer} startCropIndex: the index where the start of the crop should happen
+ * in the parent string
+ * @param {Integer} endCropIndex: the index where the end of the crop should happen
+ * in the parent string
+ * @returns {String|null} The cropped substring, or null if the text is completly cropped.
+ */
+function getCroppedString(text, offset = 0, startCropIndex, endCropIndex) {
+ const start = offset;
+ const end = offset + text.length;
+
+ const shouldBeVisible = !(start >= startCropIndex && end <= endCropIndex);
+ if (!shouldBeVisible) {
+ return null;
+ }
+
+ const shouldCropEnd = start < startCropIndex && end > startCropIndex;
+ const shouldCropStart = start < endCropIndex && end > endCropIndex;
+ if (shouldCropEnd) {
+ const cutIndex = startCropIndex - start;
+ return text.substring(0, cutIndex) + ELLIPSIS + (shouldCropStart ? text.substring(endCropIndex - start) : "");
+ }
+
+ if (shouldCropStart) {
+ // The string should be cropped at the beginning.
+ const cutIndex = endCropIndex - start;
+ return text.substring(cutIndex);
+ }
+
+ return text;
}
function supportsObject(object, noGrip = false) {
return getGripType(object, noGrip) == "string";
}
// Exports from this module
@@ -1191,16 +1264,63 @@ module.exports = Grip;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
+var _svgInlineReact = __webpack_require__(11);
+
+var _svgInlineReact2 = _interopRequireDefault(_svgInlineReact);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/* 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/. */
+
+const React = __webpack_require__(6);
+const PropTypes = __webpack_require__(2);
+
+
+const svg = {
+ "open-inspector": __webpack_require__(34),
+ "jump-definition": __webpack_require__(35)
+};
+
+Svg.propTypes = {
+ className: PropTypes.string
+};
+
+function Svg(name, props) {
+ if (!svg[name]) {
+ throw new Error("Unknown SVG: " + name);
+ }
+ let className = name;
+ if (props && props.className) {
+ className = `${name} ${props.className}`;
+ }
+ if (name === "subSettings") {
+ className = "";
+ }
+ props = Object.assign({}, props, { className, src: svg[name] });
+ return React.createElement(_svgInlineReact2.default, props);
+}
+
+module.exports = Svg;
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
/* 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/. */
// Dependencies
const dom = __webpack_require__(1);
const PropTypes = __webpack_require__(2);
const {
@@ -1331,17 +1451,115 @@ maxLengthMap.set(MODE.LONG, 10);
module.exports = {
rep: wrapRender(ArrayRep),
supportsObject,
maxLengthMap,
getLength
};
/***/ }),
-/* 10 */
+/* 11 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _react = __webpack_require__(6);
+
+var _react2 = _interopRequireDefault(_react);
+
+var _propTypes = __webpack_require__(2);
+
+var _util = __webpack_require__(33);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var process = process || { env: {} };
+
+var InlineSVG = function (_React$Component) {
+ _inherits(InlineSVG, _React$Component);
+
+ function InlineSVG() {
+ _classCallCheck(this, InlineSVG);
+
+ return _possibleConstructorReturn(this, (InlineSVG.__proto__ || Object.getPrototypeOf(InlineSVG)).apply(this, arguments));
+ }
+
+ _createClass(InlineSVG, [{
+ key: 'componentWillReceiveProps',
+ value: function componentWillReceiveProps(_ref) {
+ var children = _ref.children;
+
+ if ("production" !== process.env.NODE_ENV && children != null) {
+ console.info('<InlineSVG />: `children` prop will be ignored.');
+ }
+ }
+ }, {
+ key: 'render',
+ value: function render() {
+ var Element = void 0,
+ __html = void 0,
+ svgProps = void 0;
+
+ var _props = this.props,
+ element = _props.element,
+ raw = _props.raw,
+ src = _props.src,
+ otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
+
+ if (raw === true) {
+ Element = 'svg';
+ svgProps = (0, _util.extractSVGProps)(src);
+ __html = (0, _util.getSVGFromSource)(src).innerHTML;
+ }
+ __html = __html || src;
+ Element = Element || element;
+ svgProps = svgProps || {};
+
+ return _react2.default.createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
+ dangerouslySetInnerHTML: { __html: __html } }));
+ }
+ }]);
+
+ return InlineSVG;
+}(_react2.default.Component);
+
+exports.default = InlineSVG;
+
+
+InlineSVG.defaultProps = {
+ element: 'i',
+ raw: false,
+ src: ''
+};
+
+InlineSVG.propTypes = {
+ src: _propTypes.string.isRequired,
+ element: _propTypes.string,
+ raw: _propTypes.bool
+};
+
+/***/ }),
+/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -1365,63 +1583,17 @@ module.exports = {
DOCUMENT_POSITION_PRECEDING: 0x02,
DOCUMENT_POSITION_FOLLOWING: 0x04,
DOCUMENT_POSITION_CONTAINS: 0x08,
DOCUMENT_POSITION_CONTAINED_BY: 0x10,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20
};
/***/ }),
-/* 11 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var _svgInlineReact = __webpack_require__(37);
-
-var _svgInlineReact2 = _interopRequireDefault(_svgInlineReact);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-/* 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/. */
-
-const React = __webpack_require__(6);
-const PropTypes = __webpack_require__(2);
-
-
-const svg = {
- "open-inspector": __webpack_require__(39)
-};
-
-Svg.propTypes = {
- className: PropTypes.string
-};
-
-function Svg(name, props) {
- if (!svg[name]) {
- throw new Error("Unknown SVG: " + name);
- }
- let className = name;
- if (props && props.className) {
- className = `${name} ${props.className}`;
- }
- if (name === "subSettings") {
- className = "";
- }
- props = Object.assign({}, props, { className, src: svg[name] });
- return React.createElement(_svgInlineReact2.default, props);
-}
-
-module.exports = Svg;
-
-/***/ }),
-/* 12 */
+/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -1619,17 +1791,17 @@ maxLengthMap.set(MODE.LONG, 10);
module.exports = {
rep: wrapRender(GripArray),
supportsObject,
maxLengthMap,
getLength
};
/***/ }),
-/* 13 */
+/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -1827,17 +1999,17 @@ maxLengthMap.set(MODE.LONG, 10);
module.exports = {
rep: wrapRender(GripMap),
supportsObject,
maxLengthMap,
getLength
};
/***/ }),
-/* 14 */
+/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -1905,32 +2077,32 @@ function createGripMapEntry(key, value)
// Exports from this module
module.exports = {
rep: wrapRender(GripMapEntry),
createGripMapEntry,
supportsObject
};
/***/ }),
-/* 15 */
+/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
const { get, has } = __webpack_require__(53);
const { maybeEscapePropertyName } = __webpack_require__(0);
-const ArrayRep = __webpack_require__(9);
-const GripArrayRep = __webpack_require__(12);
-const GripMap = __webpack_require__(13);
-const GripMapEntryRep = __webpack_require__(14);
+const ArrayRep = __webpack_require__(10);
+const GripArrayRep = __webpack_require__(13);
+const GripMap = __webpack_require__(14);
+const GripMapEntryRep = __webpack_require__(15);
const MAX_NUMERICAL_PROPERTIES = 100;
const NODE_TYPES = {
BUCKET: Symbol("[nā¦n]"),
DEFAULT_PROPERTIES: Symbol("[default properties]"),
ENTRIES: Symbol("<entries>"),
GET: Symbol("<get>"),
@@ -2582,30 +2754,30 @@ module.exports = {
shouldLoadItemSymbols,
sortProperties,
NODE_TYPES,
// Export for testing purpose.
SAFE_PATH_PREFIX
};
/***/ }),
-/* 16 */
+/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
const { MODE } = __webpack_require__(3);
const { REPS, getRep } = __webpack_require__(4);
-const ObjectInspector = __webpack_require__(45);
-const ObjectInspectorUtils = __webpack_require__(15);
+const ObjectInspector = __webpack_require__(46);
+const ObjectInspectorUtils = __webpack_require__(16);
const {
parseURLEncodedText,
parseURLParams,
maybeEscapePropertyName,
getGripPreviewItems
} = __webpack_require__(0);
@@ -2617,23 +2789,23 @@ module.exports = {
parseURLEncodedText,
parseURLParams,
getGripPreviewItems,
ObjectInspector,
ObjectInspectorUtils
};
/***/ }),
-/* 17 */
+/* 18 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
-/* 18 */
+/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -2665,17 +2837,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Undefined),
supportsObject
};
/***/ }),
-/* 19 */
+/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -2707,17 +2879,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Null),
supportsObject
};
/***/ }),
-/* 20 */
+/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -2784,17 +2956,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(LongStringRep),
supportsObject
};
/***/ }),
-/* 21 */
+/* 22 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -2836,17 +3008,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Number),
supportsObject
};
/***/ }),
-/* 22 */
+/* 23 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -2919,136 +3091,112 @@ function safePropIterator(props, object,
return propIterator(props, object, max);
} catch (err) {
console.error(err);
}
return [];
}
function propIterator(props, object, max) {
- let isInterestingProp = (type, value) => {
- // Do not pick objects, it could cause recursion.
- return type == "boolean" || type == "number" || type == "string" && value;
- };
-
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=945377
if (Object.prototype.toString.call(object) === "[object Generator]") {
object = Object.getPrototypeOf(object);
}
- // Object members with non-empty values are preferred since it gives the
- // user a better overview of the object.
- let interestingObject = getFilteredObject(object, max, isInterestingProp);
-
- if (Object.keys(interestingObject).length < max) {
- // There are not enough props yet (or at least, not enough props to
- // be able to know whether we should print "moreā¦" or not).
- // Let's display also empty members and functions.
- interestingObject = Object.assign({}, interestingObject, getFilteredObject(object, max - Object.keys(interestingObject).length, (type, value) => !isInterestingProp(type, value)));
- }
-
- let propsArray = getPropsArray(interestingObject, props);
- if (Object.keys(object).length > max) {
- propsArray.push(span({
- className: "more-ellipsis",
- title: "moreā¦"
- }, "ā¦"));
- }
-
- return unfoldProps(propsArray);
-}
-
-function unfoldProps(items) {
- return items.reduce((res, item, index) => {
- if (Array.isArray(item)) {
- res = res.concat(item);
- } else {
- res.push(item);
- }
-
- // Interleave commas between elements
- if (index !== items.length - 1) {
- res.push(", ");
+ const elements = [];
+ const unimportantProperties = [];
+ let propertiesNumber = 0;
+ const propertiesNames = Object.keys(object);
+
+ const pushPropRep = (name, value) => {
+ elements.push(PropRep(Object.assign({}, props, {
+ key: name,
+ mode: MODE.TINY,
+ name,
+ object: value,
+ equal: ": "
+ })));
+ propertiesNumber++;
+
+ if (propertiesNumber < propertiesNames.length) {
+ elements.push(", ");
}
- return res;
- }, []);
-}
-
-/**
- * Get an array of components representing the properties of the object
- *
- * @param {Object} object
- * @param {Object} props
- * @return {Array} Array of PropRep.
- */
-function getPropsArray(object, props) {
- let propsArray = [];
-
- if (!object) {
- return propsArray;
- }
-
- // Hardcode tiny mode to avoid recursive handling.
- let mode = MODE.TINY;
- const objectKeys = Object.keys(object);
- return objectKeys.map((name, i) => PropRep(Object.assign({}, props, {
- mode,
- name,
- object: object[name],
- equal: ": "
- })));
-}
-
-/**
- * Get a copy of the object filtered by a given predicate.
- *
- * @param {Object} object.
- * @param {Number} max The maximum length of keys array.
- * @param {Function} filter Filter the props you want.
- * @return {Object} the filtered object.
- */
-function getFilteredObject(object, max, filter) {
- let filteredObject = {};
+ };
try {
- for (let name in object) {
- if (Object.keys(filteredObject).length >= max) {
- return filteredObject;
+ for (let name of propertiesNames) {
+ if (propertiesNumber >= max) {
+ break;
}
let value;
try {
value = object[name];
} catch (exc) {
continue;
}
- let t = typeof value;
- if (filter(t, value)) {
- filteredObject[name] = value;
+ // Object members with non-empty values are preferred since it gives the
+ // user a better overview of the object.
+ if (isInterestingProp(value)) {
+ pushPropRep(name, value);
+ } else {
+ // If the property is not important, put its name on an array for later use.
+ unimportantProperties.push(name);
}
}
} catch (err) {
console.error(err);
}
- return filteredObject;
+
+ if (propertiesNumber < max) {
+ for (let name of unimportantProperties) {
+ if (propertiesNumber >= max) {
+ break;
+ }
+
+ let value;
+ try {
+ value = object[name];
+ } catch (exc) {
+ continue;
+ }
+
+ pushPropRep(name, value);
+ }
+ }
+
+ if (propertiesNumber < propertiesNames.length) {
+ elements.push(span({
+ key: "more",
+ className: "more-ellipsis",
+ title: ", moreā¦"
+ }, "ā¦"));
+ }
+
+ return elements;
+}
+
+function isInterestingProp(value) {
+ const type = typeof value;
+ return type == "boolean" || type == "number" || type == "string" && value;
}
function supportsObject(object) {
return true;
}
// Exports from this module
module.exports = {
rep: wrapRender(ObjectRep),
supportsObject
};
/***/ }),
-/* 23 */
+/* 24 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3087,17 +3235,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(SymbolRep),
supportsObject
};
/***/ }),
-/* 24 */
+/* 25 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3135,17 +3283,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(InfinityRep),
supportsObject
};
/***/ }),
-/* 25 */
+/* 26 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3172,17 +3320,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(NaNRep),
supportsObject
};
/***/ }),
-/* 26 */
+/* 27 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3242,17 +3390,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Accessor),
supportsObject
};
/***/ }),
-/* 27 */
+/* 28 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3303,17 +3451,17 @@ function supportsObject(grip, noGrip = f
}
module.exports = {
rep: wrapRender(Attribute),
supportsObject
};
/***/ }),
-/* 28 */
+/* 29 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3370,17 +3518,17 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(DateTime),
supportsObject
};
/***/ }),
-/* 29 */
+/* 30 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3437,17 +3585,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Document),
supportsObject
};
/***/ }),
-/* 30 */
+/* 31 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3544,17 +3692,17 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(Event),
supportsObject
};
/***/ }),
-/* 31 */
+/* 32 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3565,38 +3713,57 @@ const PropTypes = __webpack_require__(2)
// Reps
const {
getGripType,
isGrip,
cropString,
wrapRender
} = __webpack_require__(0);
const { MODE } = __webpack_require__(3);
+const Svg = __webpack_require__(9);
const dom = __webpack_require__(1);
const { span } = dom;
/**
* This component represents a template for Function objects.
*/
FunctionRep.propTypes = {
object: PropTypes.object.isRequired,
- parameterNames: PropTypes.array
+ parameterNames: PropTypes.array,
+ onViewSourceInDebugger: PropTypes.func
};
function FunctionRep(props) {
- let grip = props.object;
+ let {
+ object: grip,
+ onViewSourceInDebugger
+ } = props;
+
+ let jumpToDefinitionButton;
+ if (onViewSourceInDebugger && grip.location && grip.location.url) {
+ jumpToDefinitionButton = Svg("jump-definition", {
+ element: "a",
+ draggable: false,
+ title: "Jump to definition",
+ onClick: e => {
+ // Stop the event propagation so we don't trigger ObjectInspector expand/collapse.
+ e.stopPropagation();
+ onViewSourceInDebugger(grip.location);
+ }
+ });
+ }
return span({
"data-link-actor-id": grip.actor,
className: "objectBox objectBox-function",
// Set dir="ltr" to prevent function parentheses from
// appearing in the wrong direction
dir: "ltr"
- }, getTitle(grip, props), getFunctionName(grip, props), "(", ...renderParams(props), ")");
+ }, getTitle(grip, props), getFunctionName(grip, props), "(", ...renderParams(props), ")", jumpToDefinitionButton);
}
function getTitle(grip, props) {
const {
mode
} = props;
if (mode === MODE.TINY && !grip.isGenerator && !grip.isAsync) {
@@ -3613,18 +3780,38 @@ function getTitle(grip, props) {
title = "async" + " " + title;
}
return span({
className: "objectTitle"
}, title);
}
+// Decodes an anonymous naming scheme that
+// spider monkey implements based on "Naming Anonymous JavaScript Functions"
+// http://johnjbarton.github.io/nonymous/index.html
+const objectProperty = /([\w\d]+)$/;
+const arrayProperty = /\[(.*?)\]$/;
+const functionProperty = /([\w\d]+)[\/\.<]*?$/;
+const annonymousProperty = /([\w\d]+)\(\^\)$/;
+
function getFunctionName(grip, props) {
let name = grip.userDisplayName || grip.displayName || grip.name || props.functionName || "";
+
+ const scenarios = [objectProperty, arrayProperty, functionProperty, annonymousProperty];
+
+ scenarios.some(reg => {
+ const match = reg.exec(name);
+ if (match) {
+ name = match[1];
+ return true;
+ }
+ return false;
+ });
+
return cropString(name, 100);
}
function renderParams(props) {
const {
parameterNames = []
} = props;
@@ -3646,21 +3833,90 @@ function supportsObject(grip, noGrip = f
return type == "Function";
}
// Exports from this module
module.exports = {
rep: wrapRender(FunctionRep),
- supportsObject
+ supportsObject,
+ // exported for testing purpose.
+ getFunctionName
};
/***/ }),
-/* 32 */
+/* 33 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.convertReactSVGDOMProperty = convertReactSVGDOMProperty;
+exports.startsWith = startsWith;
+exports.serializeAttrs = serializeAttrs;
+exports.getSVGFromSource = getSVGFromSource;
+exports.extractSVGProps = extractSVGProps;
+// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
+
+function convertReactSVGDOMProperty(str) {
+ return str.replace(/[-|:]([a-z])/g, function (g) {
+ return g[1].toUpperCase();
+ });
+}
+
+function startsWith(str, substring) {
+ return str.indexOf(substring) === 0;
+}
+
+var DataPropPrefix = 'data-';
+// Serialize `Attr` objects in `NamedNodeMap`
+function serializeAttrs(map) {
+ var ret = {};
+ for (var prop, i = 0; i < map.length; i++) {
+ var key = map[i].name;
+ if (!startsWith(key, DataPropPrefix)) {
+ prop = convertReactSVGDOMProperty(key);
+ }
+ ret[prop] = map[i].value;
+ }
+ return ret;
+}
+
+function getSVGFromSource(src) {
+ var svgContainer = document.createElement('div');
+ svgContainer.innerHTML = src;
+ var svg = svgContainer.firstElementChild;
+ svg.remove(); // deref from parent element
+ return svg;
+}
+
+// get <svg /> element props
+function extractSVGProps(src) {
+ var map = getSVGFromSource(src).attributes;
+ return map.length > 0 ? serializeAttrs(map) : null;
+}
+
+/***/ }),
+/* 34 */
+/***/ (function(module, exports) {
+
+module.exports = "<!-- 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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8,3L12,3L12,7L14,7L14,8L12,8L12,12L8,12L8,14L7,14L7,12L3,12L3,8L1,8L1,7L3,7L3,3L7,3L7,1L8,1L8,3ZM10,10L10,5L5,5L5,10L10,10Z\"></path></svg>"
+
+/***/ }),
+/* 35 */
+/***/ (function(module, exports) {
+
+module.exports = "<!-- 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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\"><g id=\"arrow\" transform=\"translate(1.000000, 3.000000)\"><path d=\"M4.5,0.5 L6.5,2.5\"></path><path d=\"M4.5,2.5 L6.5,4.5\" transform=\"translate(5.500000, 3.500000) scale(1, -1) translate(-5.500000, -3.500000) \"></path><path d=\"M6.00090144,2.5 C4.67806937,2.5 3.67938478,2.5 3.00484766,2.5 C1.99304199,2.5 1.01049805,3.5168457 0.993840144,4.52403846 C0.988750751,4.54723808 0.988750751,5.87097168 0.993840144,8.49523926\" id=\"Path-2\" stroke-linejoin=\"round\"></path></g><g id=\"content-lines\" transform=\"translate(9.000000, 2.000000)\"><path d=\"M1.5,3.5 L5.5,3.5\"></path><path d=\"M0.5,1.5 L5.5,1.5\"></path><path d=\"M0.5,5.5 L5.5,5.5\"></path></g></g></svg>"
+
+/***/ }),
+/* 36 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3760,17 +4016,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(PromiseRep),
supportsObject
};
/***/ }),
-/* 33 */
+/* 37 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3819,17 +4075,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(RegExp),
supportsObject
};
/***/ }),
-/* 34 */
+/* 38 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3887,17 +4143,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(StyleSheet),
supportsObject
};
/***/ }),
-/* 35 */
+/* 39 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3906,17 +4162,17 @@ module.exports = {
const PropTypes = __webpack_require__(2);
const {
isGrip,
cropString,
cropMultipleLines,
wrapRender
} = __webpack_require__(0);
const { MODE } = __webpack_require__(3);
-const nodeConstants = __webpack_require__(10);
+const nodeConstants = __webpack_require__(12);
const dom = __webpack_require__(1);
const { span } = dom;
/**
* Renders DOM comment node.
*/
CommentNode.propTypes = {
object: PropTypes.object.isRequired,
@@ -3953,17 +4209,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(CommentNode),
supportsObject
};
/***/ }),
-/* 36 */
+/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -3973,18 +4229,18 @@ const PropTypes = __webpack_require__(2)
// Utils
const {
isGrip,
wrapRender
} = __webpack_require__(0);
const { rep: StringRep } = __webpack_require__(7);
const { MODE } = __webpack_require__(3);
-const nodeConstants = __webpack_require__(10);
-const Svg = __webpack_require__(11);
+const nodeConstants = __webpack_require__(12);
+const Svg = __webpack_require__(9);
const dom = __webpack_require__(1);
const { span } = dom;
/**
* Renders DOM element node.
*/
ElementNode.propTypes = {
@@ -4085,176 +4341,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(ElementNode),
supportsObject
};
/***/ }),
-/* 37 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _react = __webpack_require__(6);
-
-var _react2 = _interopRequireDefault(_react);
-
-var _propTypes = __webpack_require__(2);
-
-var _util = __webpack_require__(38);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var process = process || { env: {} };
-
-var InlineSVG = function (_React$Component) {
- _inherits(InlineSVG, _React$Component);
-
- function InlineSVG() {
- _classCallCheck(this, InlineSVG);
-
- return _possibleConstructorReturn(this, (InlineSVG.__proto__ || Object.getPrototypeOf(InlineSVG)).apply(this, arguments));
- }
-
- _createClass(InlineSVG, [{
- key: 'componentWillReceiveProps',
- value: function componentWillReceiveProps(_ref) {
- var children = _ref.children;
-
- if ("production" !== process.env.NODE_ENV && children != null) {
- console.info('<InlineSVG />: `children` prop will be ignored.');
- }
- }
- }, {
- key: 'render',
- value: function render() {
- var Element = void 0,
- __html = void 0,
- svgProps = void 0;
-
- var _props = this.props,
- element = _props.element,
- raw = _props.raw,
- src = _props.src,
- otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
-
- if (raw === true) {
- Element = 'svg';
- svgProps = (0, _util.extractSVGProps)(src);
- __html = (0, _util.getSVGFromSource)(src).innerHTML;
- }
- __html = __html || src;
- Element = Element || element;
- svgProps = svgProps || {};
-
- return _react2.default.createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
- dangerouslySetInnerHTML: { __html: __html } }));
- }
- }]);
-
- return InlineSVG;
-}(_react2.default.Component);
-
-exports.default = InlineSVG;
-
-
-InlineSVG.defaultProps = {
- element: 'i',
- raw: false,
- src: ''
-};
-
-InlineSVG.propTypes = {
- src: _propTypes.string.isRequired,
- element: _propTypes.string,
- raw: _propTypes.bool
-};
-
-/***/ }),
-/* 38 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.convertReactSVGDOMProperty = convertReactSVGDOMProperty;
-exports.startsWith = startsWith;
-exports.serializeAttrs = serializeAttrs;
-exports.getSVGFromSource = getSVGFromSource;
-exports.extractSVGProps = extractSVGProps;
-// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
-
-function convertReactSVGDOMProperty(str) {
- return str.replace(/[-|:]([a-z])/g, function (g) {
- return g[1].toUpperCase();
- });
-}
-
-function startsWith(str, substring) {
- return str.indexOf(substring) === 0;
-}
-
-var DataPropPrefix = 'data-';
-// Serialize `Attr` objects in `NamedNodeMap`
-function serializeAttrs(map) {
- var ret = {};
- for (var prop, i = 0; i < map.length; i++) {
- var key = map[i].name;
- if (!startsWith(key, DataPropPrefix)) {
- prop = convertReactSVGDOMProperty(key);
- }
- ret[prop] = map[i].value;
- }
- return ret;
-}
-
-function getSVGFromSource(src) {
- var svgContainer = document.createElement('div');
- svgContainer.innerHTML = src;
- var svg = svgContainer.firstElementChild;
- svg.remove(); // deref from parent element
- return svg;
-}
-
-// get <svg /> element props
-function extractSVGProps(src) {
- var map = getSVGFromSource(src).attributes;
- return map.length > 0 ? serializeAttrs(map) : null;
-}
-
-/***/ }),
-/* 39 */
-/***/ (function(module, exports) {
-
-module.exports = "<!-- 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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8,3L12,3L12,7L14,7L14,8L12,8L12,12L8,12L8,14L7,14L7,12L3,12L3,8L1,8L1,7L3,7L3,3L7,3L7,1L8,1L8,3ZM10,10L10,5L5,5L5,10L10,10Z\"></path></svg>"
-
-/***/ }),
-/* 40 */
+/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -4264,17 +4361,17 @@ const PropTypes = __webpack_require__(2)
// Reps
const {
isGrip,
cropString,
wrapRender
} = __webpack_require__(0);
const { MODE } = __webpack_require__(3);
-const Svg = __webpack_require__(11);
+const Svg = __webpack_require__(9);
const dom = __webpack_require__(1);
const { span } = dom;
/**
* Renders DOM #text node.
*/
TextNode.propTypes = {
@@ -4353,17 +4450,17 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(TextNode),
supportsObject
};
/***/ }),
-/* 41 */
+/* 42 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -4388,17 +4485,32 @@ ErrorRep.propTypes = {
object: PropTypes.object.isRequired,
// @TODO Change this to Object.values once it's supported in Node's version of V8
mode: PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key]))
};
function ErrorRep(props) {
let object = props.object;
let preview = object.preview;
- let name = preview && preview.name ? preview.name : "Error";
+
+ let name;
+ if (preview && preview.name && preview.kind) {
+ switch (preview.kind) {
+ case "Error":
+ name = preview.name;
+ break;
+ case "DOMException":
+ name = preview.kind;
+ break;
+ default:
+ throw new Error("Unknown preview kind for the Error rep.");
+ }
+ } else {
+ name = "Error";
+ }
let content = props.mode === MODE.TINY ? name : `${name}: ${preview.message}`;
if (preview.stack && props.mode !== MODE.TINY) {
/*
* Since Reps are used in the JSON Viewer, we can't localize
* the "Stack trace" label (defined in debugger.properties as
* "variablesViewErrorStacktrace" property), until Bug 1317038 lands.
@@ -4412,27 +4524,27 @@ function ErrorRep(props) {
}, content);
}
// Registration
function supportsObject(object, noGrip = false) {
if (noGrip === true || !isGrip(object)) {
return false;
}
- return object.preview && getGripType(object, noGrip) === "Error";
+ return object.preview && getGripType(object, noGrip) === "Error" || object.class === "DOMException";
}
// Exports from this module
module.exports = {
rep: wrapRender(ErrorRep),
supportsObject
};
/***/ }),
-/* 42 */
+/* 43 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -4500,17 +4612,17 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(WindowRep),
supportsObject
};
/***/ }),
-/* 43 */
+/* 44 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -4561,17 +4673,17 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(ObjectWithText),
supportsObject
};
/***/ }),
-/* 44 */
+/* 45 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/. */
@@ -4627,23 +4739,23 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(ObjectWithURL),
supportsObject
};
/***/ }),
-/* 45 */
+/* 46 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var _devtoolsComponents = __webpack_require__(46);
+var _devtoolsComponents = __webpack_require__(47);
var _devtoolsComponents2 = _interopRequireDefault(_devtoolsComponents);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/. */
@@ -4684,17 +4796,17 @@ const {
nodeIsPrototype,
nodeIsSetter,
nodeIsWindow,
shouldLoadItemEntries,
shouldLoadItemIndexedProperties,
shouldLoadItemNonIndexedProperties,
shouldLoadItemPrototype,
shouldLoadItemSymbols
-} = __webpack_require__(15);
+} = __webpack_require__(16);
const {
enumEntries,
enumIndexedProperties,
enumNonIndexedProperties,
getPrototype,
enumSymbols
} = __webpack_require__(54);
@@ -5063,188 +5175,172 @@ ObjectInspector.propTypes = {
onFocus: PropTypes.func,
onDoubleClick: PropTypes.func,
onLabelClick: PropTypes.func
};
module.exports = ObjectInspector;
/***/ }),
-/* 46 */
+/* 47 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
-var _tree = __webpack_require__(47);
+var _tree = __webpack_require__(48);
var _tree2 = _interopRequireDefault(_tree);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = {
Tree: _tree2.default
}; /* 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/. */
/***/ }),
-/* 47 */
+/* 48 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(6);
var _react2 = _interopRequireDefault(_react);
-var _svgInlineReact = __webpack_require__(48);
+var _reactDomFactories = __webpack_require__(1);
+
+var _reactDomFactories2 = _interopRequireDefault(_reactDomFactories);
+
+var _propTypes = __webpack_require__(2);
+
+var _propTypes2 = _interopRequireDefault(_propTypes);
+
+var _svgInlineReact = __webpack_require__(11);
var _svgInlineReact2 = _interopRequireDefault(_svgInlineReact);
var _arrow = __webpack_require__(49);
var _arrow2 = _interopRequireDefault(_arrow);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-const { DOM: dom, createClass, createFactory, createElement, PropTypes } = _react2.default; /* 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/. */
+const { Component, createFactory, createElement } = _react2.default; /* 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/. */
__webpack_require__(50);
const AUTO_EXPAND_DEPTH = 0; // depth
/**
* An arrow that displays whether its node is expanded (ā¼) or collapsed
* (ā¶). When its node has no children, it is hidden.
*/
-const ArrowExpander = createFactory(createClass({
- displayName: "ArrowExpander",
-
- propTypes: {
- expanded: PropTypes.bool
- },
+class ArrowExpander extends Component {
+ static get propTypes() {
+ return {
+ expanded: _propTypes2.default.bool
+ };
+ }
shouldComponentUpdate(nextProps, nextState) {
return this.props.expanded !== nextProps.expanded;
- },
+ }
render() {
const {
expanded
} = this.props;
const classNames = ["arrow"];
if (expanded) {
classNames.push("expanded");
}
return createElement(_svgInlineReact2.default, {
className: classNames.join(" "),
src: _arrow2.default
});
}
-}));
-
-const TreeNode = createFactory(createClass({
- displayName: "TreeNode",
-
- propTypes: {
- id: PropTypes.any.isRequired,
- index: PropTypes.number.isRequired,
- depth: PropTypes.number.isRequired,
- focused: PropTypes.bool.isRequired,
- expanded: PropTypes.bool.isRequired,
- item: PropTypes.any.isRequired,
- isExpandable: PropTypes.bool.isRequired,
- onClick: PropTypes.func,
- renderItem: PropTypes.func.isRequired
- },
+}
+
+const treeIndent = _reactDomFactories2.default.span({ className: "tree-indent" }, "\u200B");
+
+class TreeNode extends Component {
+ static get propTypes() {
+ return {
+ id: _propTypes2.default.any.isRequired,
+ index: _propTypes2.default.number.isRequired,
+ depth: _propTypes2.default.number.isRequired,
+ focused: _propTypes2.default.bool.isRequired,
+ expanded: _propTypes2.default.bool.isRequired,
+ item: _propTypes2.default.any.isRequired,
+ isExpandable: _propTypes2.default.bool.isRequired,
+ onClick: _propTypes2.default.func,
+ renderItem: _propTypes2.default.func.isRequired
+ };
+ }
shouldComponentUpdate(nextProps) {
return this.props.item !== nextProps.item || this.props.focused !== nextProps.focused || this.props.expanded !== nextProps.expanded;
- },
+ }
render() {
const {
depth,
id,
item,
focused,
expanded,
renderItem,
isExpandable
} = this.props;
- const arrow = isExpandable ? ArrowExpander({
+ const arrow = isExpandable ? ArrowExpanderFactory({
item,
expanded
}) : null;
- const treeIndentWidthVar = "var(--tree-indent-width)";
- const treeBorderColorVar = "var(--tree-indent-border-color, black)";
- const treeBorderWidthVar = "var(--tree-indent-border-width, 1px)";
-
- const paddingInlineStart = `calc(
- (${treeIndentWidthVar} * ${depth})
- ${isExpandable ? "" : "+ var(--arrow-total-width)"}
- )`;
-
- // This is the computed border that will mimic a border on tree nodes.
- // This allow us to have as many "borders" as we need without adding
- // specific elements for that purpose only.
- // it's a gradient with "hard stops" which will give us as much plain
- // lines as we need given the depth of the node.
- // The gradient uses CSS custom properties so everything is customizable
- // by consumers if needed.
- const backgroundBorder = depth === 0 ? null : "linear-gradient(90deg, " + Array.from({ length: depth }).map((_, i) => {
- const indentWidth = `(${i} * ${treeIndentWidthVar})`;
- const alignIndent = `(var(--arrow-width) / 2)`;
- const start = `calc(${indentWidth} + ${alignIndent})`;
- const end = `calc(${indentWidth} + ${alignIndent} + ${treeBorderWidthVar})`;
-
- return `transparent ${start},
- ${treeBorderColorVar} ${start},
- ${treeBorderColorVar} ${end},
- transparent ${end}`;
- }).join(",") + ")";
-
let ariaExpanded;
if (this.props.isExpandable) {
ariaExpanded = false;
}
if (this.props.expanded) {
ariaExpanded = true;
}
- return dom.div({
+ const indents = Array.from({ length: depth }).fill(treeIndent);
+ let items = indents.concat(renderItem(item, depth, focused, arrow, expanded));
+
+ return _reactDomFactories2.default.div({
id,
className: "tree-node" + (focused ? " focused" : ""),
- style: {
- paddingInlineStart,
- backgroundImage: backgroundBorder
- },
onClick: this.props.onClick,
role: "treeitem",
"aria-level": depth,
"aria-expanded": ariaExpanded,
"data-expandable": this.props.isExpandable
- }, renderItem(item, depth, focused, arrow, expanded));
- }
-}));
+ }, ...items);
+ }
+}
+
+const ArrowExpanderFactory = createFactory(ArrowExpander);
+const TreeNodeFactory = createFactory(TreeNode);
/**
* Create a function that calls the given function `fn` only once per animation
* frame.
*
* @param {Function} fn
* @returns {Function}
*/
@@ -5280,50 +5376,38 @@ function oncePerAnimationFrame(fn) {
* This tree component doesn't make any assumptions about how to render items in
* the tree. You provide a `renderItem` function, and this component will ensure
* that only those items whose parents are expanded and which are visible in the
* viewport are rendered. The `renderItem` function could render the items as a
* "traditional" tree or as rows in a table or anything else. It doesn't
* restrict you to only one certain kind of tree.
*
* The tree comes with basic styling for the indent, the arrow, as well as hovered
- * and focused styles.
- * All of this can be customize on the customer end, by overriding the following
- * CSS custom properties :
- * --arrow-width: the width of the arrow.
- * --arrow-single-margin: the end margin between the arrow and the item that follows.
- * --arrow-fill-color: the fill-color of the arrow.
- * --tree-indent-width: the width of a 1-level-deep item.
- * --tree-indent-border-color: the color of the indent border.
- * --tree-indent-border-width: the width of the indent border.
- * --tree-node-hover-background-color: the background color of a hovered node.
- * --tree-node-focus-color: the color of a focused node.
- * --tree-node-focus-background-color: the background color of a focused node.
- *
+ * and focused styles which can be override in CSS.
*
* ### Example Usage
*
* Suppose we have some tree data where each item has this form:
*
* {
* id: Number,
* label: String,
* parent: Item or null,
* children: Array of child items,
* expanded: bool,
* }
*
* Here is how we could render that data with this component:
*
- * const MyTree = createClass({
- * displayName: "MyTree",
- *
- * propTypes: {
+ * class MyTree extends Component {
+ * static get propTypes() {
* // The root item of the tree, with the form described above.
- * root: PropTypes.object.isRequired
+ * return {
+ * root: PropTypes.object.isRequired
+ * };
* },
*
* render() {
* return Tree({
* itemHeight: 20, // px
*
* getRoots: () => [this.props.root],
*
@@ -5345,175 +5429,193 @@ function oncePerAnimationFrame(fn) {
* dom.span({ className: "my-tree-item-label" }, item.label)
* );
* },
*
* onExpand: item => dispatchExpandActionToRedux(item),
* onCollapse: item => dispatchCollapseActionToRedux(item),
* });
* }
- * });
+ * }
*/
-const Tree = createClass({
- displayName: "Tree",
-
- propTypes: {
- // Required props
-
- // A function to get an item's parent, or null if it is a root.
- //
- // Type: getParent(item: Item) -> Maybe<Item>
- //
- // Example:
- //
- // // The parent of this item is stored in its `parent` property.
- // getParent: item => item.parent
- getParent: PropTypes.func.isRequired,
-
- // A function to get an item's children.
- //
- // Type: getChildren(item: Item) -> [Item]
- //
- // Example:
- //
- // // This item's children are stored in its `children` property.
- // getChildren: item => item.children
- getChildren: PropTypes.func.isRequired,
-
- // A function which takes an item and ArrowExpander component instance and
- // returns a component, or text, or anything else that React considers
- // renderable.
- //
- // Type: renderItem(item: Item,
- // depth: Number,
- // isFocused: Boolean,
- // arrow: ReactComponent,
- // isExpanded: Boolean) -> ReactRenderable
- //
- // Example:
- //
- // renderItem: (item, depth, isFocused, arrow, isExpanded) => {
- // let className = "my-tree-item";
- // if (isFocused) {
- // className += " focused";
- // }
- // return dom.div(
- // {
- // className,
- // style: { marginLeft: depth * 10 + "px" }
- // },
- // arrow,
- // dom.span({ className: "my-tree-item-label" }, item.label)
- // );
- // },
- renderItem: PropTypes.func.isRequired,
-
- // A function which returns the roots of the tree (forest).
- //
- // Type: getRoots() -> [Item]
- //
- // Example:
- //
- // // In this case, we only have one top level, root item. You could
- // // return multiple items if you have many top level items in your
- // // tree.
- // getRoots: () => [this.props.rootOfMyTree]
- getRoots: PropTypes.func.isRequired,
-
- // A function to get a unique key for the given item. This helps speed up
- // React's rendering a *TON*.
- //
- // Type: getKey(item: Item) -> String
- //
- // Example:
- //
- // getKey: item => `my-tree-item-${item.uniqueId}`
- getKey: PropTypes.func.isRequired,
-
- // A function to get whether an item is expanded or not. If an item is not
- // expanded, then it must be collapsed.
- //
- // Type: isExpanded(item: Item) -> Boolean
- //
- // Example:
- //
- // isExpanded: item => item.expanded,
- isExpanded: PropTypes.func.isRequired,
-
- // Optional props
-
- // The currently focused item, if any such item exists.
- focused: PropTypes.any,
-
- // Handle when a new item is focused.
- onFocus: PropTypes.func,
-
- // The depth to which we should automatically expand new items.
- autoExpandDepth: PropTypes.number,
- // Should auto expand all new items or just the new items under the first
- // root item.
- autoExpandAll: PropTypes.bool,
-
- // Note: the two properties below are mutually exclusive. Only one of the
- // label properties is necessary.
- // ID of an element whose textual content serves as an accessible label for
- // a tree.
- labelledby: PropTypes.string,
- // Accessibility label for a tree widget.
- label: PropTypes.string,
-
- // Optional event handlers for when items are expanded or collapsed. Useful
- // for dispatching redux events and updating application state, maybe lazily
- // loading subtrees from a worker, etc.
- //
- // Type:
- // onExpand(item: Item)
- // onCollapse(item: Item)
- //
- // Example:
- //
- // onExpand: item => dispatchExpandActionToRedux(item)
- onExpand: PropTypes.func,
- onCollapse: PropTypes.func,
- isExpandable: PropTypes.func,
- // Additional classes to add to the root element.
- className: PropTypes.string,
- // style object to be applied to the root element.
- style: PropTypes.object
- },
-
- getDefaultProps() {
+class Tree extends Component {
+ static get propTypes() {
+ return {
+ // Required props
+
+ // A function to get an item's parent, or null if it is a root.
+ //
+ // Type: getParent(item: Item) -> Maybe<Item>
+ //
+ // Example:
+ //
+ // // The parent of this item is stored in its `parent` property.
+ // getParent: item => item.parent
+ getParent: _propTypes2.default.func.isRequired,
+
+ // A function to get an item's children.
+ //
+ // Type: getChildren(item: Item) -> [Item]
+ //
+ // Example:
+ //
+ // // This item's children are stored in its `children` property.
+ // getChildren: item => item.children
+ getChildren: _propTypes2.default.func.isRequired,
+
+ // A function which takes an item and ArrowExpander component instance and
+ // returns a component, or text, or anything else that React considers
+ // renderable.
+ //
+ // Type: renderItem(item: Item,
+ // depth: Number,
+ // isFocused: Boolean,
+ // arrow: ReactComponent,
+ // isExpanded: Boolean) -> ReactRenderable
+ //
+ // Example:
+ //
+ // renderItem: (item, depth, isFocused, arrow, isExpanded) => {
+ // let className = "my-tree-item";
+ // if (isFocused) {
+ // className += " focused";
+ // }
+ // return dom.div(
+ // {
+ // className,
+ // style: { marginLeft: depth * 10 + "px" }
+ // },
+ // arrow,
+ // dom.span({ className: "my-tree-item-label" }, item.label)
+ // );
+ // },
+ renderItem: _propTypes2.default.func.isRequired,
+
+ // A function which returns the roots of the tree (forest).
+ //
+ // Type: getRoots() -> [Item]
+ //
+ // Example:
+ //
+ // // In this case, we only have one top level, root item. You could
+ // // return multiple items if you have many top level items in your
+ // // tree.
+ // getRoots: () => [this.props.rootOfMyTree]
+ getRoots: _propTypes2.default.func.isRequired,
+
+ // A function to get a unique key for the given item. This helps speed up
+ // React's rendering a *TON*.
+ //
+ // Type: getKey(item: Item) -> String
+ //
+ // Example:
+ //
+ // getKey: item => `my-tree-item-${item.uniqueId}`
+ getKey: _propTypes2.default.func.isRequired,
+
+ // A function to get whether an item is expanded or not. If an item is not
+ // expanded, then it must be collapsed.
+ //
+ // Type: isExpanded(item: Item) -> Boolean
+ //
+ // Example:
+ //
+ // isExpanded: item => item.expanded,
+ isExpanded: _propTypes2.default.func.isRequired,
+
+ // Optional props
+
+ // The currently focused item, if any such item exists.
+ focused: _propTypes2.default.any,
+
+ // Handle when a new item is focused.
+ onFocus: _propTypes2.default.func,
+
+ // The depth to which we should automatically expand new items.
+ autoExpandDepth: _propTypes2.default.number,
+ // Should auto expand all new items or just the new items under the first
+ // root item.
+ autoExpandAll: _propTypes2.default.bool,
+
+ // Note: the two properties below are mutually exclusive. Only one of the
+ // label properties is necessary.
+ // ID of an element whose textual content serves as an accessible label for
+ // a tree.
+ labelledby: _propTypes2.default.string,
+ // Accessibility label for a tree widget.
+ label: _propTypes2.default.string,
+
+ // Optional event handlers for when items are expanded or collapsed. Useful
+ // for dispatching redux events and updating application state, maybe lazily
+ // loading subtrees from a worker, etc.
+ //
+ // Type:
+ // onExpand(item: Item)
+ // onCollapse(item: Item)
+ //
+ // Example:
+ //
+ // onExpand: item => dispatchExpandActionToRedux(item)
+ onExpand: _propTypes2.default.func,
+ onCollapse: _propTypes2.default.func,
+ isExpandable: _propTypes2.default.func,
+ // Additional classes to add to the root element.
+ className: _propTypes2.default.string,
+ // style object to be applied to the root element.
+ style: _propTypes2.default.object
+ };
+ }
+
+ static get defaultProps() {
return {
autoExpandDepth: AUTO_EXPAND_DEPTH,
autoExpandAll: true
};
- },
-
- getInitialState() {
- return {
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
seen: new Set()
};
- },
+
+ this._onExpand = oncePerAnimationFrame(this._onExpand).bind(this);
+ this._onCollapse = oncePerAnimationFrame(this._onCollapse).bind(this);
+ this._focusPrevNode = oncePerAnimationFrame(this._focusPrevNode).bind(this);
+ this._focusNextNode = oncePerAnimationFrame(this._focusNextNode).bind(this);
+ this._focusParentNode = oncePerAnimationFrame(this._focusParentNode).bind(this);
+
+ this._autoExpand = this._autoExpand.bind(this);
+ this._preventArrowKeyScrolling = this._preventArrowKeyScrolling.bind(this);
+ this._dfs = this._dfs.bind(this);
+ this._dfsFromRoots = this._dfsFromRoots.bind(this);
+ this._focus = this._focus.bind(this);
+ this._scrollNodeIntoView = this._scrollNodeIntoView.bind(this);
+ this._onBlur = this._onBlur.bind(this);
+ this._onKeyDown = this._onKeyDown.bind(this);
+ this._nodeIsExpandable = this._nodeIsExpandable.bind(this);
+ }
componentDidMount() {
this._autoExpand();
if (this.props.focused) {
this._scrollNodeIntoView(this.props.focused);
}
- },
+ }
componentWillReceiveProps(nextProps) {
this._autoExpand();
- },
+ }
componentDidUpdate(prevProps, prevState) {
if (prevProps.focused !== this.props.focused) {
this._scrollNodeIntoView(this.props.focused);
}
- },
+ }
_autoExpand() {
if (!this.props.autoExpandDepth) {
return;
}
// Automatically expand the first autoExpandDepth levels for new items. Do
// not use the usual DFS infrastructure because we don't want to ignore
@@ -5537,17 +5639,17 @@ const Tree = createClass({
const length = roots.length;
if (this.props.autoExpandAll) {
for (let i = 0; i < length; i++) {
autoExpand(roots[i], 0);
}
} else if (length != 0) {
autoExpand(roots[0], 0);
}
- },
+ }
_preventArrowKeyScrolling(e) {
switch (e.key) {
case "ArrowUp":
case "ArrowDown":
case "ArrowLeft":
case "ArrowRight":
e.preventDefault();
@@ -5556,17 +5658,17 @@ const Tree = createClass({
if (e.nativeEvent.preventDefault) {
e.nativeEvent.preventDefault();
}
if (e.nativeEvent.stopPropagation) {
e.nativeEvent.stopPropagation();
}
}
}
- },
+ }
/**
* Perform a pre-order depth-first search from item.
*/
_dfs(item, maxDepth = Infinity, traversal = [], _depth = 0) {
traversal.push({ item, depth: _depth });
if (!this.props.isExpanded(item)) {
@@ -5581,63 +5683,63 @@ const Tree = createClass({
const children = this.props.getChildren(item);
const length = children.length;
for (let i = 0; i < length; i++) {
this._dfs(children[i], maxDepth, traversal, nextDepth);
}
return traversal;
- },
+ }
/**
* Perform a pre-order depth-first search over the whole forest.
*/
_dfsFromRoots(maxDepth = Infinity) {
const traversal = [];
const roots = this.props.getRoots();
const length = roots.length;
for (let i = 0; i < length; i++) {
this._dfs(roots[i], maxDepth, traversal);
}
return traversal;
- },
+ }
/**
* Expands current row.
*
* @param {Object} item
* @param {Boolean} expandAllChildren
*/
- _onExpand: oncePerAnimationFrame(function (item, expandAllChildren) {
+ _onExpand(item, expandAllChildren) {
if (this.props.onExpand) {
this.props.onExpand(item);
if (expandAllChildren) {
const children = this._dfs(item);
const length = children.length;
for (let i = 0; i < length; i++) {
this.props.onExpand(children[i].item);
}
}
}
- }),
+ }
/**
* Collapses current row.
*
* @param {Object} item
*/
- _onCollapse: oncePerAnimationFrame(function (item) {
+ _onCollapse(item) {
if (this.props.onCollapse) {
this.props.onCollapse(item);
}
- }),
+ }
/**
* Sets the passed in item to be the focused item.
*
* @param {Object|undefined} item
* The item to be focused, or undefined to focus no item.
*
* @param {Object|undefined} options
@@ -5646,33 +5748,33 @@ const Tree = createClass({
* top or the bottom of the scrollable container when the element is
* off canvas.
*/
_focus(item, options) {
this._scrollNodeIntoView(item, options);
if (this.props.onFocus) {
this.props.onFocus(item);
}
- },
+ }
/**
* Sets the passed in item to be the focused item.
*
* @param {Object|undefined} item
* The item to be scrolled to.
*
* @param {Object|undefined} options
* An options object which can contain:
* - dir: "up" or "down" to indicate if we should scroll the element to the
* top or the bottom of the scrollable container when the element is
* off canvas.
*/
_scrollNodeIntoView(item, options = {}) {
if (item !== undefined) {
- const treeElement = this.refs.tree;
+ const treeElement = this.treeRef;
const element = document.getElementById(this.props.getKey(item));
if (element) {
const { top, bottom } = element.getBoundingClientRect();
const closestScrolledParent = node => {
if (node == null) {
return null;
}
@@ -5685,24 +5787,24 @@ const Tree = createClass({
const isVisible = !scrolledParent || top >= 0 && bottom <= scrolledParent.clientHeight;
if (!isVisible) {
let scrollToTop = !options.alignTo && top < 0 || options.alignTo === "top";
element.scrollIntoView(scrollToTop);
}
}
}
- },
+ }
/**
* Sets the state to have no focused item.
*/
_onBlur() {
this._focus(undefined);
- },
+ }
/**
* Handles key down events in the tree's container.
*
* @param {Event} e
*/
_onKeyDown(e) {
if (this.props.focused == null) {
@@ -5735,22 +5837,22 @@ const Tree = createClass({
case "ArrowRight":
if (this._nodeIsExpandable(this.props.focused) && !this.props.isExpanded(this.props.focused)) {
this._onExpand(this.props.focused);
} else {
this._focusNextNode();
}
}
- },
+ }
/**
* Sets the previous node relative to the currently focused item, to focused.
*/
- _focusPrevNode: oncePerAnimationFrame(function () {
+ _focusPrevNode() {
// Start a depth first search and keep going until we reach the currently
// focused node. Focus the previous node in the DFS, if it exists. If it
// doesn't exist, we're at the first node already.
let prev;
const traversal = this._dfsFromRoots();
const length = traversal.length;
@@ -5761,23 +5863,23 @@ const Tree = createClass({
}
prev = item;
}
if (prev === undefined) {
return;
}
this._focus(prev, { alignTo: "top" });
- }),
+ }
/**
* Handles the down arrow key which will focus either the next child
* or sibling row.
*/
- _focusNextNode: oncePerAnimationFrame(function () {
+ _focusNextNode() {
// Start a depth first search and keep going until we reach the currently
// focused node. Focus the next node in the DFS, if it exists. If it
// doesn't exist, we're at the last node already.
const traversal = this._dfsFromRoots();
const length = traversal.length;
let i = 0;
while (i < length) {
@@ -5785,55 +5887,55 @@ const Tree = createClass({
break;
}
i++;
}
if (i + 1 < traversal.length) {
this._focus(traversal[i + 1].item, { alignTo: "bottom" });
}
- }),
+ }
/**
* Handles the left arrow key, going back up to the current rows'
* parent row.
*/
- _focusParentNode: oncePerAnimationFrame(function () {
+ _focusParentNode() {
const parent = this.props.getParent(this.props.focused);
if (!parent) {
this._focusPrevNode(this.props.focused);
return;
}
const traversal = this._dfsFromRoots();
const length = traversal.length;
let parentIndex = 0;
for (; parentIndex < length; parentIndex++) {
if (traversal[parentIndex].item === parent) {
break;
}
}
this._focus(parent, { alignTo: "top" });
- }),
-
- _nodeIsExpandable: function (item) {
+ }
+
+ _nodeIsExpandable(item) {
return this.props.isExpandable ? this.props.isExpandable(item) : !!this.props.getChildren(item).length;
- },
+ }
render() {
const traversal = this._dfsFromRoots();
const {
focused
} = this.props;
const nodes = traversal.map((v, i) => {
const { item, depth } = traversal[i];
const key = this.props.getKey(item, i);
- return TreeNode({
+ return TreeNodeFactory({
key,
id: key,
index: i,
item,
depth,
renderItem: this.props.renderItem,
focused: focused === item,
expanded: this.props.isExpanded(item),
@@ -5851,254 +5953,55 @@ const Tree = createClass({
});
});
const style = Object.assign({}, this.props.style || {}, {
padding: 0,
margin: 0
});
- return dom.div({
+ return _reactDomFactories2.default.div({
className: `tree ${this.props.className ? this.props.className : ""}`,
- ref: "tree",
+ ref: el => {
+ this.treeRef = el;
+ },
role: "tree",
tabIndex: "0",
onKeyDown: this._onKeyDown,
onKeyPress: this._preventArrowKeyScrolling,
onKeyUp: this._preventArrowKeyScrolling,
onFocus: ({ nativeEvent }) => {
- if (focused || !nativeEvent || !this.refs.tree) {
+ if (focused || !nativeEvent || !this.treeRef) {
return;
}
let { explicitOriginalTarget } = nativeEvent;
// Only set default focus to the first tree node if the focus came
// from outside the tree (e.g. by tabbing to the tree from other
// external elements).
- if (explicitOriginalTarget !== this.refs.tree && !this.refs.tree.contains(explicitOriginalTarget)) {
+ if (explicitOriginalTarget !== this.treeRef && !this.treeRef.contains(explicitOriginalTarget)) {
this._focus(traversal[0].item);
}
},
onBlur: this._onBlur,
onClick: () => {
// Focus should always remain on the tree container itself.
- this.refs.tree.focus();
+ this.treeRef.focus();
},
"aria-label": this.props.label,
"aria-labelledby": this.props.labelledby,
"aria-activedescendant": focused && this.props.getKey(focused),
style
}, nodes);
}
-});
+}
exports.default = Tree;
/***/ }),
-/* 48 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, '__esModule', {
- value: true
-});
-
-var _extends = Object.assign || function (target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];for (var key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- }return target;
-};
-
-var _createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ('value' in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
- }
- }return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
- };
-}();
-
-var _get = function get(_x, _x2, _x3) {
- var _again = true;_function: while (_again) {
- var object = _x,
- property = _x2,
- receiver = _x3;_again = false;if (object === null) object = Function.prototype;var desc = Object.getOwnPropertyDescriptor(object, property);if (desc === undefined) {
- var parent = Object.getPrototypeOf(object);if (parent === null) {
- return undefined;
- } else {
- _x = parent;_x2 = property;_x3 = receiver;_again = true;desc = parent = undefined;continue _function;
- }
- } else if ('value' in desc) {
- return desc.value;
- } else {
- var getter = desc.get;if (getter === undefined) {
- return undefined;
- }return getter.call(receiver);
- }
- }
-};
-
-function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : { 'default': obj };
-}
-
-function _objectWithoutProperties(obj, keys) {
- var target = {};for (var i in obj) {
- if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];
- }return target;
-}
-
-function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
-}
-
-function _inherits(subClass, superClass) {
- if (typeof superClass !== 'function' && superClass !== null) {
- throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
- }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
-}
-
-var _react = __webpack_require__(6);
-
-var _react2 = _interopRequireDefault(_react);
-
-var DOMParser = typeof window !== 'undefined' && window.DOMParser;
-var process = process || {};
-process.env = process.env || {};
-var parserAvailable = typeof DOMParser !== 'undefined' && DOMParser.prototype != null && DOMParser.prototype.parseFromString != null;
-
-function isParsable(src) {
- // kinda naive but meh, ain't gonna use full-blown parser for this
- return parserAvailable && typeof src === 'string' && src.trim().substr(0, 4) === '<svg';
-}
-
-// parse SVG string using `DOMParser`
-function parseFromSVGString(src) {
- var parser = new DOMParser();
- return parser.parseFromString(src, "image/svg+xml");
-}
-
-// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
-function switchSVGAttrToReactProp(propName) {
- switch (propName) {
- case 'class':
- return 'className';
- default:
- return propName;
- }
-}
-
-var InlineSVG = function (_React$Component) {
- _inherits(InlineSVG, _React$Component);
-
- _createClass(InlineSVG, null, [{
- key: 'defaultProps',
- value: {
- element: 'i',
- raw: false,
- src: ''
- },
- enumerable: true
- }, {
- key: 'propTypes',
- value: {
- src: _react2['default'].PropTypes.string.isRequired,
- element: _react2['default'].PropTypes.string,
- raw: _react2['default'].PropTypes.bool
- },
- enumerable: true
- }]);
-
- function InlineSVG(props) {
- _classCallCheck(this, InlineSVG);
-
- _get(Object.getPrototypeOf(InlineSVG.prototype), 'constructor', this).call(this, props);
- this._extractSVGProps = this._extractSVGProps.bind(this);
- }
-
- // Serialize `Attr` objects in `NamedNodeMap`
-
- _createClass(InlineSVG, [{
- key: '_serializeAttrs',
- value: function _serializeAttrs(map) {
- var ret = {};
- var prop = undefined;
- for (var i = 0; i < map.length; i++) {
- prop = switchSVGAttrToReactProp(map[i].name);
- ret[prop] = map[i].value;
- }
- return ret;
- }
-
- // get <svg /> element props
- }, {
- key: '_extractSVGProps',
- value: function _extractSVGProps(src) {
- var map = parseFromSVGString(src).documentElement.attributes;
- return map.length > 0 ? this._serializeAttrs(map) : null;
- }
-
- // get content inside <svg> element.
- }, {
- key: '_stripSVG',
- value: function _stripSVG(src) {
- return parseFromSVGString(src).documentElement.innerHTML;
- }
- }, {
- key: 'componentWillReceiveProps',
- value: function componentWillReceiveProps(_ref) {
- var children = _ref.children;
-
- if ("production" !== process.env.NODE_ENV && children != null) {
- console.info('<InlineSVG />: `children` prop will be ignored.');
- }
- }
- }, {
- key: 'render',
- value: function render() {
- var Element = undefined,
- __html = undefined,
- svgProps = undefined;
- var _props = this.props;
- var element = _props.element;
- var raw = _props.raw;
- var src = _props.src;
-
- var otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
-
- if (raw === true && isParsable(src)) {
- Element = 'svg';
- svgProps = this._extractSVGProps(src);
- __html = this._stripSVG(src);
- }
- __html = __html || src;
- Element = Element || element;
- svgProps = svgProps || {};
-
- return _react2['default'].createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
- dangerouslySetInnerHTML: { __html: __html } }));
- }
- }]);
-
- return InlineSVG;
-}(_react2['default'].Component);
-
-exports['default'] = InlineSVG;
-module.exports = exports['default'];
-
-/***/ }),
/* 49 */
/***/ (function(module, exports) {
module.exports = "<!-- 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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"
/***/ }),
/* 50 */
/***/ (function(module, exports) {