From ff762ea52b4f74795783d94689c4e5de885245cc Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Sat, 21 Jan 2017 17:19:43 +0100 Subject: [PATCH] Update reps + Setup mochitests * add missing exports to src/index.js * remove unused index.js * cleanup build scripts for reps * update path to mc reps * synchronize tests from mc * update mc path in publish assets * add load-reps to reps/ * update bundle exports to be compatible with latest mc changes * migrate reps tests to use load-reps * synchronize reps from mc * cleanup prepare-mochitest-dev --- bin/copy-assets.js | 4 +- bin/download-firefox-artifact | 4 +- bin/prepare-mochitests-dev | 5 +- bin/publish-assets.js | 2 +- index.js | 9 - src/index.js | 12 +- src/launchpad/components/Result.js | 2 +- src/reps/array.js | 27 +- src/reps/attribute.js | 21 +- src/reps/caption.js | 12 +- src/reps/comment-node.js | 13 +- src/reps/date-time.js | 15 +- src/reps/document.js | 15 +- src/reps/element-node.js | 14 +- src/reps/error.js | 12 +- src/reps/event.js | 15 +- src/reps/function.js | 16 +- src/reps/grip-array.js | 17 +- src/reps/grip-map.js | 18 +- src/reps/grip.js | 21 +- src/reps/infinity.js | 12 +- src/reps/load-reps.js | 46 ++++ src/reps/long-string.js | 17 +- src/reps/nan.js | 8 +- src/reps/null.js | 9 +- src/reps/number.js | 16 +- src/reps/object-with-text.js | 12 +- src/reps/object-with-url.js | 13 +- src/reps/object.js | 17 +- src/reps/promise.js | 18 +- src/reps/prop-rep.js | 21 +- src/reps/regexp.js | 12 +- src/reps/rep-utils.js | 23 ++ src/reps/rep.js | 35 ++- src/reps/string.js | 16 +- src/reps/stylesheet.js | 14 +- src/reps/symbol.js | 8 +- src/reps/text-node.js | 15 +- src/reps/undefined.js | 9 +- src/reps/window.js | 25 +- src/test/mochitest/chrome.ini | 23 +- src/test/mochitest/head.js | 162 +----------- src/test/mochitest/test_reps_array.html | 60 +++-- src/test/mochitest/test_reps_attribute.html | 4 +- .../mochitest/test_reps_comment-node.html | 8 +- src/test/mochitest/test_reps_date-time.html | 4 +- src/test/mochitest/test_reps_document.html | 4 +- .../mochitest/test_reps_element-node.html | 20 +- src/test/mochitest/test_reps_error.html | 34 ++- src/test/mochitest/test_reps_event.html | 153 +++++++++++- src/test/mochitest/test_reps_failure.html | 59 +++++ src/test/mochitest/test_reps_function.html | 4 +- src/test/mochitest/test_reps_grip-array.html | 64 +++-- src/test/mochitest/test_reps_grip-map.html | 44 ++-- src/test/mochitest/test_reps_grip.html | 233 ++++++++++++++---- src/test/mochitest/test_reps_infinity.html | 4 +- src/test/mochitest/test_reps_long-string.html | 4 +- src/test/mochitest/test_reps_nan.html | 4 +- src/test/mochitest/test_reps_null.html | 4 +- src/test/mochitest/test_reps_number.html | 4 +- .../mochitest/test_reps_object-with-text.html | 4 +- .../mochitest/test_reps_object-with-url.html | 5 +- src/test/mochitest/test_reps_object.html | 40 +-- src/test/mochitest/test_reps_promise.html | 34 +-- src/test/mochitest/test_reps_regexp.html | 4 +- src/test/mochitest/test_reps_string.html | 4 +- src/test/mochitest/test_reps_stylesheet.html | 4 +- src/test/mochitest/test_reps_symbol.html | 4 +- src/test/mochitest/test_reps_text-node.html | 38 ++- src/test/mochitest/test_reps_undefined.html | 4 +- src/test/mochitest/test_reps_window.html | 5 +- 71 files changed, 1051 insertions(+), 591 deletions(-) delete mode 100644 index.js create mode 100644 src/reps/load-reps.js create mode 100644 src/test/mochitest/test_reps_failure.html diff --git a/bin/copy-assets.js b/bin/copy-assets.js index 4e629c4..4a9408d 100644 --- a/bin/copy-assets.js +++ b/bin/copy-assets.js @@ -9,9 +9,9 @@ const args = minimist(process.argv.slice(2), { function start() { console.log("start: copy assets"); const projectPath = path.resolve(__dirname, ".."); - const mcModulePath = "devtools/client/shared/components"; + const mcModulePath = "devtools/client/shared/components/reps"; const mcPath = "./firefox"; - + symlinkTests({ projectPath, mcModulePath }); makeBundle({ diff --git a/bin/download-firefox-artifact b/bin/download-firefox-artifact index 7b6c6cf..6db2401 100755 --- a/bin/download-firefox-artifact +++ b/bin/download-firefox-artifact @@ -24,8 +24,8 @@ if [ -d "$FIREFOX_PATH" ]; then # If the mochitest dir has been symlinked, remove it as revert # does not follow symlinks. - if [ -h "$FIREFOX_PATH/devtools/client/debugger/new/test/mochitest" ]; then - rm "$FIREFOX_PATH/devtools/client/debugger/new/test/mochitest"; + if [ -h "$FIREFOX_PATH/devtools/client/shared/components/reps/test/mochitest" ]; then + rm "$FIREFOX_PATH/devtools/client/shared/components/reps/test/mochitest"; fi hg revert -a diff --git a/bin/prepare-mochitests-dev b/bin/prepare-mochitests-dev index 71c0878..1138c21 100755 --- a/bin/prepare-mochitests-dev +++ b/bin/prepare-mochitests-dev @@ -6,7 +6,8 @@ FIREFOX_PATH="$ROOT/../firefox" # This will either download or update the local Firefox repo "$ROOT/download-firefox-artifact" -# Update the debugger files, build firefox, and run all the mochitests -"$ROOT/make-firefox-bundle" "$FIREFOX_PATH" --symlink-mochitests +# Update the reps files and symlink reps mochitests +node "$ROOT/copy-assets.js" + cd "$FIREFOX_PATH" ./mach build diff --git a/bin/publish-assets.js b/bin/publish-assets.js index 16a4790..a60b0fa 100644 --- a/bin/publish-assets.js +++ b/bin/publish-assets.js @@ -4,7 +4,7 @@ const path = require("path"); function start() { console.log("start: publish assets"); const projectPath = path.resolve(__dirname, ".."); - const mcModulePath = "devtools/client/debugger/new"; + const mcModulePath = "devtools/client/shared/components/reps"; copyFile( path.resolve(projectPath, "src/test/mochitest"), diff --git a/index.js b/index.js deleted file mode 100644 index 6c23967..0000000 --- a/index.js +++ /dev/null @@ -1,9 +0,0 @@ -const Rep = require("./src/reps/rep").Rep; -const Grip = require("./src/reps/grip").Grip; -const ObjectInspector = require("./src/ObjectInspector"); - -module.exports = { - Rep, - Grip, - ObjectInspector -} diff --git a/src/index.js b/src/index.js index d071881..2ed909b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,13 @@ const React = require("react"); const { MODE } = require("./reps/constants"); -const Rep = React.createFactory(require("./reps/rep")); -const Grip = require("./reps/grip"); +const { REPS } = require("./reps/rep"); +const { createFactories, parseURLEncodedText, parseURLParams } = require("./reps/rep-utils"); module.exports = { - Rep, - Grip, - MODE + REPS, + MODE, + createFactories, + parseURLEncodedText, + parseURLParams, }; diff --git a/src/launchpad/components/Result.js b/src/launchpad/components/Result.js index c31e775..dc7e9de 100644 --- a/src/launchpad/components/Result.js +++ b/src/launchpad/components/Result.js @@ -2,7 +2,7 @@ const React = require("react"); const { DOM: dom, PropTypes, createFactory } = React; const { MODE } = require("../../reps/constants"); -const Rep = createFactory(require("../../reps/rep")); +const Rep = createFactory(require("../../reps/rep").Rep); const Grip = require("../../reps/grip"); const Result = React.createClass({ diff --git a/src/reps/array.js b/src/reps/array.js index 0ac2af3..80e4f85 100644 --- a/src/reps/array.js +++ b/src/reps/array.js @@ -1,6 +1,12 @@ +"use strict"; +// Dependencies const React = require("react"); -const Caption = React.createFactory(require("./caption")); +const { + createFactories, + wrapRender, +} = require("./rep-utils"); +const { Caption } = createFactories(require("./caption")); const { MODE } = require("./constants"); // Shortcuts @@ -16,6 +22,8 @@ let ArrayRep = React.createClass({ propTypes: { // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, + object: React.PropTypes.array.isRequired, }, getTitle: function (object, context) { @@ -105,7 +113,7 @@ let ArrayRep = React.createClass({ onClickBracket: function (event) { }, - render: function () { + render: wrapRender(function () { let { object, mode = MODE.SHORT, @@ -147,7 +155,7 @@ let ArrayRep = React.createClass({ ) ) ); - }, + }), }); /** @@ -156,8 +164,14 @@ let ArrayRep = React.createClass({ let ItemRep = React.createFactory(React.createClass({ displayName: "ItemRep", - render: function () { - const Rep = React.createFactory(require("./rep")); + propTypes: { + object: React.PropTypes.any.isRequired, + delim: React.PropTypes.string.isRequired, + mode: React.PropTypes.symbol, + }, + + render: wrapRender(function () { + const { Rep } = createFactories(require("./rep")); let object = this.props.object; let delim = this.props.delim; @@ -168,7 +182,7 @@ let ItemRep = React.createFactory(React.createClass({ delim ) ); - } + }) })); function supportsObject(object, type) { @@ -176,6 +190,7 @@ function supportsObject(object, type) { Object.prototype.toString.call(object) === "[object Arguments]"; } +// Exports from this module module.exports = { rep: ArrayRep, supportsObject: supportsObject diff --git a/src/reps/attribute.js b/src/reps/attribute.js index 9f5212a..85f9b71 100644 --- a/src/reps/attribute.js +++ b/src/reps/attribute.js @@ -1,11 +1,17 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip } = require("./rep-utils"); -const StringRep = React.createFactory(require("./string").rep); +const { + createFactories, + isGrip, + wrapRender, +} = require("./rep-utils"); +const { StringRep } = require("./string"); // Shortcuts const { span } = React.DOM; +const { rep: StringRepFactory } = createFactories(StringRep); /** * Renders DOM attribute @@ -14,14 +20,15 @@ let Attribute = React.createClass({ displayName: "Attr", propTypes: { - object: React.PropTypes.object.isRequired + object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getTitle: function (grip) { return grip.preview.nodeName; }, - render: function () { + render: wrapRender(function () { let object = this.props.object; let value = object.preview.value; let objectLink = this.props.objectLink || span; @@ -35,11 +42,11 @@ let Attribute = React.createClass({ span({className: "attrEqual"}, "=" ), - StringRep({object: value}) + StringRepFactory({object: value}) ) ) ); - }, + }), }); // Registration @@ -55,4 +62,4 @@ function supportsObject(grip, type) { module.exports = { rep: Attribute, supportsObject: supportsObject -}; +}; \ No newline at end of file diff --git a/src/reps/caption.js b/src/reps/caption.js index 12e9cef..b01d668 100644 --- a/src/reps/caption.js +++ b/src/reps/caption.js @@ -1,6 +1,9 @@ +// Dependencies const React = require("react"); const DOM = React.DOM; +const { wrapRender } = require("./rep-utils"); + /** * Renders a caption. This template is used by other components * that needs to distinguish between a simple text/value and a label. @@ -8,11 +11,16 @@ const DOM = React.DOM; const Caption = React.createClass({ displayName: "Caption", - render: function () { + propTypes: { + object: React.PropTypes.object, + }, + + render: wrapRender(function () { return ( DOM.span({"className": "caption"}, this.props.object) ); - }, + }), }); +// Exports from this module module.exports = Caption; diff --git a/src/reps/comment-node.js b/src/reps/comment-node.js index cb224ea..f6f0197 100644 --- a/src/reps/comment-node.js +++ b/src/reps/comment-node.js @@ -1,5 +1,11 @@ +// Dependencies const React = require("react"); -const { isGrip, cropString, cropMultipleLines } = require("./rep-utils"); +const { + isGrip, + cropString, + cropMultipleLines, + wrapRender, +} = require("./rep-utils"); const { MODE } = require("./constants"); const nodeConstants = require("../shared/dom-node-constants"); @@ -18,7 +24,7 @@ const CommentNode = React.createClass({ mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), }, - render: function () { + render: wrapRender(function () { let { object, mode = MODE.SHORT @@ -32,7 +38,7 @@ const CommentNode = React.createClass({ } return span({className: "objectBox theme-comment"}, ``); - }, + }), }); // Registration @@ -43,6 +49,7 @@ function supportsObject(object, type) { return object.preview && object.preview.nodeType === nodeConstants.COMMENT_NODE; } +// Exports from this module module.exports = { rep: CommentNode, supportsObject: supportsObject diff --git a/src/reps/date-time.js b/src/reps/date-time.js index 3258759..49b3132 100644 --- a/src/reps/date-time.js +++ b/src/reps/date-time.js @@ -1,7 +1,11 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip } = require("./rep-utils"); +const { + isGrip, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -13,7 +17,8 @@ let DateTime = React.createClass({ displayName: "Date", propTypes: { - object: React.PropTypes.object.isRequired + object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getTitle: function (grip) { @@ -25,7 +30,7 @@ let DateTime = React.createClass({ return ""; }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; let date; try { @@ -38,8 +43,9 @@ let DateTime = React.createClass({ } catch (e) { date = span({className: "objectBox"}, "Invalid Date"); } + return date; - }, + }), }); // Registration @@ -52,6 +58,7 @@ function supportsObject(grip, type) { return (type == "Date" && grip.preview); } +// Exports from this module module.exports = { rep: DateTime, supportsObject: supportsObject diff --git a/src/reps/document.js b/src/reps/document.js index e429207..3bda1ae 100644 --- a/src/reps/document.js +++ b/src/reps/document.js @@ -1,7 +1,12 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip, getURLDisplayString } = require("./rep-utils"); +const { + isGrip, + getURLDisplayString, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -13,7 +18,8 @@ let Document = React.createClass({ displayName: "Document", propTypes: { - object: React.PropTypes.object.isRequired + object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getLocation: function (grip) { @@ -36,7 +42,7 @@ let Document = React.createClass({ return doc.location.href; }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; return ( @@ -47,7 +53,7 @@ let Document = React.createClass({ ) ) ); - }, + }), }); // Registration @@ -60,6 +66,7 @@ function supportsObject(object, type) { return (object.preview && type == "HTMLDocument"); } +// Exports from this module module.exports = { rep: Document, supportsObject: supportsObject diff --git a/src/reps/element-node.js b/src/reps/element-node.js index 24de9e2..04577c3 100644 --- a/src/reps/element-node.js +++ b/src/reps/element-node.js @@ -1,7 +1,11 @@ +// ReactJS const React = require("react"); // Utils -const { isGrip } = require("./rep-utils"); +const { + isGrip, + wrapRender, +} = require("./rep-utils"); const { MODE } = require("./constants"); const nodeConstants = require("../shared/dom-node-constants"); @@ -18,6 +22,9 @@ const ElementNode = React.createClass({ object: React.PropTypes.object.isRequired, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + onDOMNodeMouseOver: React.PropTypes.func, + onDOMNodeMouseOut: React.PropTypes.func, + objectLink: React.PropTypes.func, }, getElements: function (grip, mode) { @@ -78,7 +85,7 @@ const ElementNode = React.createClass({ ]; }, - render: function () { + render: wrapRender(function () { let { object, mode, @@ -104,7 +111,7 @@ const ElementNode = React.createClass({ return objectLink({object}, span(baseConfig, ...elements) ); - }, + }), }); // Registration @@ -115,6 +122,7 @@ function supportsObject(object, type) { return object.preview && object.preview.nodeType === nodeConstants.ELEMENT_NODE; } +// Exports from this module module.exports = { rep: ElementNode, supportsObject: supportsObject diff --git a/src/reps/error.js b/src/reps/error.js index b290687..229a6cc 100644 --- a/src/reps/error.js +++ b/src/reps/error.js @@ -1,6 +1,10 @@ +// ReactJS const React = require("react"); // Utils -const { isGrip } = require("./rep-utils"); +const { + isGrip, + wrapRender, +} = require("./rep-utils"); const { MODE } = require("./constants"); // Shortcuts const { span } = React.DOM; @@ -15,9 +19,10 @@ const ErrorRep = React.createClass({ object: React.PropTypes.object.isRequired, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, }, - render: function () { + render: wrapRender(function () { let object = this.props.object; let preview = object.preview; let name = preview && preview.name @@ -43,7 +48,7 @@ const ErrorRep = React.createClass({ span({}, content) ) ); - }, + }), }); // Registration @@ -54,6 +59,7 @@ function supportsObject(object, type) { return (object.preview && type === "Error"); } +// Exports from this module module.exports = { rep: ErrorRep, supportsObject: supportsObject diff --git a/src/reps/event.js b/src/reps/event.js index 0767561..0489530 100644 --- a/src/reps/event.js +++ b/src/reps/event.js @@ -1,8 +1,13 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip } = require("./rep-utils"); -const rep = React.createFactory(require("./grip").rep); +const { + createFactories, + isGrip, + wrapRender, +} = require("./rep-utils"); +const { rep } = createFactories(require("./grip").Grip); /** * Renders DOM event objects. @@ -24,7 +29,7 @@ let Event = React.createClass({ return title; }, - render: function () { + render: wrapRender(function () { // Use `Object.assign` to keep `this.props` without changes because: // 1. JSON.stringify/JSON.parse is slow. // 2. Immutable.js is planned for the future. @@ -70,10 +75,11 @@ let Event = React.createClass({ } return rep(props); - } + }) }); // Registration + function supportsObject(grip, type) { if (!isGrip(grip)) { return false; @@ -82,6 +88,7 @@ function supportsObject(grip, type) { return (grip.preview && grip.preview.kind == "DOMEvent"); } +// Exports from this module module.exports = { rep: Event, supportsObject: supportsObject diff --git a/src/reps/function.js b/src/reps/function.js index c24952d..421d669 100644 --- a/src/reps/function.js +++ b/src/reps/function.js @@ -1,7 +1,12 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip, cropString } = require("./rep-utils"); +const { + isGrip, + cropString, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -13,7 +18,8 @@ let Func = React.createClass({ displayName: "Func", propTypes: { - object: React.PropTypes.object.isRequired + object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getTitle: function (grip) { @@ -30,7 +36,7 @@ let Func = React.createClass({ return cropString(name + "()", 100); }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; return ( @@ -41,7 +47,7 @@ let Func = React.createClass({ this.summarizeFunction(grip) ) ); - }, + }), }); // Registration @@ -54,6 +60,8 @@ function supportsObject(grip, type) { return (type == "Function"); } +// Exports from this module + module.exports = { rep: Func, supportsObject: supportsObject diff --git a/src/reps/grip-array.js b/src/reps/grip-array.js index 7d30be4..e842bcb 100644 --- a/src/reps/grip-array.js +++ b/src/reps/grip-array.js @@ -1,6 +1,11 @@ +// Dependencies const React = require("react"); -const { isGrip } = require("./rep-utils"); -const Caption = React.createFactory(require("./caption")); +const { + createFactories, + isGrip, + wrapRender, +} = require("./rep-utils"); +const { Caption } = createFactories(require("./caption")); const { MODE } = require("./constants"); // Shortcuts @@ -18,6 +23,7 @@ let GripArray = React.createClass({ // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), provider: React.PropTypes.object, + objectLink: React.PropTypes.func, }, getLength: function (grip) { @@ -98,7 +104,7 @@ let GripArray = React.createClass({ return items; }, - render: function () { + render: wrapRender(function () { let { object, mode = MODE.SHORT @@ -143,7 +149,7 @@ let GripArray = React.createClass({ ) ) ); - }, + }), }); /** @@ -158,7 +164,7 @@ let GripArrayItem = React.createFactory(React.createClass({ }, render: function () { - let Rep = React.createFactory(require("./rep")); + let { Rep } = createFactories(require("./rep")); return ( span({}, @@ -183,6 +189,7 @@ function supportsObject(grip, type) { ); } +// Exports from this module module.exports = { rep: GripArray, supportsObject: supportsObject diff --git a/src/reps/grip-map.js b/src/reps/grip-map.js index 1417cbc..608393f 100644 --- a/src/reps/grip-map.js +++ b/src/reps/grip-map.js @@ -1,7 +1,12 @@ +// Dependencies const React = require("react"); -const { isGrip } = require("./rep-utils"); -const Caption = React.createFactory(require("./caption")); -const PropRep = React.createFactory(require("./prop-rep")); +const { + createFactories, + isGrip, + wrapRender, +} = require("./rep-utils"); +const { Caption } = createFactories(require("./caption")); +const { PropRep } = createFactories(require("./prop-rep")); const { MODE } = require("./constants"); // Shortcuts const { span } = React.DOM; @@ -16,6 +21,8 @@ const GripMap = React.createClass({ object: React.PropTypes.object, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, + isInterestingEntry: React.PropTypes.func, }, getTitle: function (object) { @@ -134,7 +141,7 @@ const GripMap = React.createClass({ }, []); }, - render: function () { + render: wrapRender(function () { let object = this.props.object; let props = this.safeEntriesIterator(object, (this.props.mode === MODE.LONG) ? 10 : 3); @@ -166,7 +173,7 @@ const GripMap = React.createClass({ }, " }") ) ); - }, + }), }); function supportsObject(grip, type) { @@ -176,6 +183,7 @@ function supportsObject(grip, type) { return (grip.preview && grip.preview.kind == "MapLike"); } +// Exports from this module module.exports = { rep: GripMap, supportsObject: supportsObject diff --git a/src/reps/grip.js b/src/reps/grip.js index 4848ccc..7c6cc46 100644 --- a/src/reps/grip.js +++ b/src/reps/grip.js @@ -1,8 +1,13 @@ +// ReactJS const React = require("react"); // Dependencies -const { isGrip } = require("./rep-utils"); -const Caption = React.createFactory(require("./caption")); -const PropRep = React.createFactory(require("./prop-rep")); +const { + createFactories, + isGrip, + wrapRender, +} = require("./rep-utils"); +const { Caption } = createFactories(require("./caption")); +const { PropRep } = createFactories(require("./prop-rep")); const { MODE } = require("./constants"); // Shortcuts const { span } = React.DOM; @@ -21,6 +26,7 @@ const GripRep = React.createClass({ mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), isInterestingProp: React.PropTypes.func, title: React.PropTypes.string, + objectLink: React.PropTypes.func, }, getTitle: function (object) { @@ -45,7 +51,7 @@ const GripRep = React.createClass({ propIterator: function (object, max) { if (object.preview && Object.keys(object.preview).includes("wrappedValue")) { - const Rep = React.createFactory(require("./rep")); + const { Rep } = createFactories(require("./rep")); return [Rep({ object: object.preview.wrappedValue, @@ -94,7 +100,7 @@ const GripRep = React.createClass({ props.push(Caption({ object: objectLink({ object: object - }, `${object.ownPropertyLength - max} more…`) + }, `${propertiesLength - max} more…`) })); } @@ -188,7 +194,7 @@ const GripRep = React.createClass({ return value; }, - render: function () { + render: wrapRender(function () { let object = this.props.object; let props = this.safePropIterator(object, (this.props.mode === MODE.LONG) ? 10 : 3); @@ -220,7 +226,7 @@ const GripRep = React.createClass({ }, " }") ) ); - }, + }), }); // Registration @@ -236,4 +242,5 @@ let Grip = { supportsObject: supportsObject }; +// Exports from this module module.exports = Grip; diff --git a/src/reps/infinity.js b/src/reps/infinity.js index 05814ce..aad1c5f 100644 --- a/src/reps/infinity.js +++ b/src/reps/infinity.js @@ -1,5 +1,8 @@ +// Dependencies const React = require("react"); +const { wrapRender } = require("./rep-utils"); + // Shortcuts const { span } = React.DOM; @@ -9,19 +12,24 @@ const { span } = React.DOM; const InfinityRep = React.createClass({ displayName: "Infinity", - render: function () { + propTypes: { + object: React.PropTypes.object.isRequired, + }, + + render: wrapRender(function () { return ( span({className: "objectBox objectBox-number"}, this.props.object.type ) ); - } + }) }); function supportsObject(object, type) { return type == "Infinity" || type == "-Infinity"; } +// Exports from this module module.exports = { rep: InfinityRep, supportsObject: supportsObject diff --git a/src/reps/load-reps.js b/src/reps/load-reps.js new file mode 100644 index 0000000..0043ae0 --- /dev/null +++ b/src/reps/load-reps.js @@ -0,0 +1,46 @@ +/* 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) { + let Rep; + let StringRep; + let Grip; + let MODE; + let createFactories; + let parseURLEncodedText; + let parseURLParams; + + // useRepsBundle hardcoded to false while we experiment with the reps bundle in + // bugs 1325401 and 1330779. Set it to true to test devtools using the reps bundle. + let useRepsBundle = false; + if (useRepsBundle) { + const bundle = require("devtools/client/shared/components/reps/reps"); + const { createFactory } = require("react"); + Rep = createFactory(bundle.Rep); + StringRep = createFactory(bundle.StringRep); + Grip = createFactory(bundle.Grip); + MODE = bundle.MODE; + createFactories = bundle.createFactories; + parseURLEncodedText = bundle.parseURLEncodedText; + parseURLParams = bundle.parseURLParams; + } else { + ({ createFactories, parseURLEncodedText, parseURLParams } = + require("devtools/client/shared/components/reps/rep-utils")); + Rep = createFactories(require("devtools/client/shared/components/reps/rep")).Rep; + StringRep = createFactories(require("devtools/client/shared/components/reps/string").StringRep).rep; + Grip = require("devtools/client/shared/components/reps/grip").Grip; + MODE = require("devtools/client/shared/components/reps/constants").MODE; + } + + exports.Rep = Rep; + exports.StringRep = StringRep; + exports.Grip = Grip; + exports.MODE = MODE; + exports.createFactories = createFactories; + exports.parseURLEncodedText = parseURLEncodedText; + exports.parseURLParams = parseURLParams; +}); diff --git a/src/reps/long-string.js b/src/reps/long-string.js index 8041eeb..77aee9c 100644 --- a/src/reps/long-string.js +++ b/src/reps/long-string.js @@ -1,5 +1,10 @@ +// Dependencies const React = require("react"); -const { sanitizeString, isGrip } = require("./rep-utils"); +const { + sanitizeString, + isGrip, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -12,6 +17,9 @@ const LongStringRep = React.createClass({ propTypes: { useQuotes: React.PropTypes.bool, style: React.PropTypes.object, + cropLimit: React.PropTypes.number.isRequired, + member: React.PropTypes.string, + object: React.PropTypes.object.isRequired, }, getDefaultProps: function () { @@ -20,7 +28,7 @@ const LongStringRep = React.createClass({ }; }, - render: function () { + render: wrapRender(function () { let { cropLimit, member, @@ -44,7 +52,7 @@ const LongStringRep = React.createClass({ } let formattedString = useQuotes ? `"${string}"` : string; return span(config, sanitizeString(formattedString)); - }, + }), }); function supportsObject(object, type) { @@ -54,7 +62,8 @@ function supportsObject(object, type) { return object.type === "longString"; } +// Exports from this module module.exports = { rep: LongStringRep, supportsObject: supportsObject, -}; +}; \ No newline at end of file diff --git a/src/reps/nan.js b/src/reps/nan.js index 72b0352..7abf535 100644 --- a/src/reps/nan.js +++ b/src/reps/nan.js @@ -1,5 +1,8 @@ +// Dependencies const React = require("react"); +const { wrapRender } = require("./rep-utils"); + // Shortcuts const { span } = React.DOM; @@ -9,19 +12,20 @@ const { span } = React.DOM; const NaNRep = React.createClass({ displayName: "NaN", - render: function () { + render: wrapRender(function () { return ( span({className: "objectBox objectBox-nan"}, "NaN" ) ); - } + }) }); function supportsObject(object, type) { return type == "NaN"; } +// Exports from this module module.exports = { rep: NaNRep, supportsObject: supportsObject diff --git a/src/reps/null.js b/src/reps/null.js index 80a9eab..6e6b978 100644 --- a/src/reps/null.js +++ b/src/reps/null.js @@ -1,5 +1,8 @@ +// Dependencies const React = require("react"); +const { wrapRender } = require("./rep-utils"); + // Shortcuts const { span } = React.DOM; @@ -9,13 +12,13 @@ const { span } = React.DOM; const Null = React.createClass({ displayName: "NullRep", - render: function () { + render: wrapRender(function () { return ( span({className: "objectBox objectBox-null"}, "null" ) ); - }, + }), }); function supportsObject(object, type) { @@ -26,6 +29,8 @@ function supportsObject(object, type) { return (object == null); } +// Exports from this module + module.exports = { rep: Null, supportsObject: supportsObject diff --git a/src/reps/number.js b/src/reps/number.js index 14d495c..8def82b 100644 --- a/src/reps/number.js +++ b/src/reps/number.js @@ -1,5 +1,8 @@ +// Dependencies const React = require("react"); +const { wrapRender } = require("./rep-utils"); + // Shortcuts const { span } = React.DOM; @@ -9,6 +12,13 @@ const { span } = React.DOM; const Number = React.createClass({ displayName: "Number", + propTypes: { + object: React.PropTypes.oneOfType([ + React.PropTypes.object, + React.PropTypes.number, + ]).isRequired + }, + stringify: function (object) { let isNegativeZero = Object.is(object, -0) || (object.type && object.type == "-0"); @@ -16,7 +26,7 @@ const Number = React.createClass({ return (isNegativeZero ? "-0" : String(object)); }, - render: function () { + render: wrapRender(function () { let value = this.props.object; return ( @@ -24,13 +34,15 @@ const Number = React.createClass({ this.stringify(value) ) ); - } + }) }); function supportsObject(object, type) { return ["boolean", "number", "-0"].includes(type); } +// Exports from this module + module.exports = { rep: Number, supportsObject: supportsObject diff --git a/src/reps/object-with-text.js b/src/reps/object-with-text.js index 9bc67ad..74e83ad 100644 --- a/src/reps/object-with-text.js +++ b/src/reps/object-with-text.js @@ -1,7 +1,11 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip } = require("./rep-utils"); +const { + isGrip, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -14,6 +18,7 @@ let ObjectWithText = React.createClass({ propTypes: { object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getTitle: function (grip) { @@ -35,7 +40,7 @@ let ObjectWithText = React.createClass({ return "\"" + grip.preview.text + "\""; }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; return ( span({className: "objectBox objectBox-" + this.getType(grip)}, @@ -45,7 +50,7 @@ let ObjectWithText = React.createClass({ ) ) ); - }, + }), }); // Registration @@ -58,6 +63,7 @@ function supportsObject(grip, type) { return (grip.preview && grip.preview.kind == "ObjectWithText"); } +// Exports from this module module.exports = { rep: ObjectWithText, supportsObject: supportsObject diff --git a/src/reps/object-with-url.js b/src/reps/object-with-url.js index 361bae3..b4c0461 100644 --- a/src/reps/object-with-url.js +++ b/src/reps/object-with-url.js @@ -1,7 +1,12 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip, getURLDisplayString } = require("./rep-utils"); +const { + isGrip, + getURLDisplayString, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -14,6 +19,7 @@ let ObjectWithURL = React.createClass({ propTypes: { object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getTitle: function (grip) { @@ -35,7 +41,7 @@ let ObjectWithURL = React.createClass({ return getURLDisplayString(grip.preview.url); }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; return ( span({className: "objectBox objectBox-" + this.getType(grip)}, @@ -45,7 +51,7 @@ let ObjectWithURL = React.createClass({ ) ) ); - }, + }), }); // Registration @@ -58,6 +64,7 @@ function supportsObject(grip, type) { return (grip.preview && grip.preview.kind == "ObjectWithURL"); } +// Exports from this module module.exports = { rep: ObjectWithURL, supportsObject: supportsObject diff --git a/src/reps/object.js b/src/reps/object.js index f6e1d78..e0840e8 100644 --- a/src/reps/object.js +++ b/src/reps/object.js @@ -1,6 +1,11 @@ +// Dependencies const React = require("react"); -const Caption = React.createFactory(require("./caption")); -const PropRep = React.createFactory(require("./prop-rep")); +const { + createFactories, + wrapRender, +} = require("./rep-utils"); +const { Caption } = createFactories(require("./caption")); +const { PropRep } = createFactories(require("./prop-rep")); const { MODE } = require("./constants"); // Shortcuts const { span } = React.DOM; @@ -15,6 +20,7 @@ const Obj = React.createClass({ object: React.PropTypes.object, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, }, getTitle: function (object) { @@ -121,7 +127,7 @@ const Obj = React.createClass({ return props; }, - render: function () { + render: wrapRender(function () { let object = this.props.object; let props = this.safePropIterator(object); let objectLink = this.props.objectLink || span; @@ -148,13 +154,14 @@ const Obj = React.createClass({ }, " }") ) ); - }, + }), }); function supportsObject(object, type) { return true; } +// Exports from this module module.exports = { rep: Obj, supportsObject: supportsObject -}; +}; \ No newline at end of file diff --git a/src/reps/promise.js b/src/reps/promise.js index f560626..4f86c54 100644 --- a/src/reps/promise.js +++ b/src/reps/promise.js @@ -1,7 +1,13 @@ +// ReactJS const React = require("react"); // Dependencies -const { isGrip } = require("./rep-utils"); -const PropRep = React.createFactory(require("./prop-rep")); +const { + createFactories, + isGrip, + wrapRender, +} = require("./rep-utils"); + +const { PropRep } = createFactories(require("./prop-rep")); const { MODE } = require("./constants"); // Shortcuts const { span } = React.DOM; @@ -16,6 +22,7 @@ const PromiseRep = React.createClass({ object: React.PropTypes.object.isRequired, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, }, getTitle: function (object) { @@ -45,13 +52,13 @@ const PromiseRep = React.createClass({ }); }, - render: function () { + render: wrapRender(function () { const object = this.props.object; const {promiseState} = object; let objectLink = this.props.objectLink || span; if (this.props.mode === MODE.TINY) { - let Rep = React.createFactory(require("./rep")); + let { Rep } = createFactories(require("./rep")); return ( span({className: "objectBox objectBox-object"}, @@ -84,7 +91,7 @@ const PromiseRep = React.createClass({ }, " }") ) ); - }, + }), }); // Registration @@ -95,6 +102,7 @@ function supportsObject(object, type) { return type === "Promise"; } +// Exports from this module module.exports = { rep: PromiseRep, supportsObject: supportsObject diff --git a/src/reps/prop-rep.js b/src/reps/prop-rep.js index 3d6a7da..a792cb4 100644 --- a/src/reps/prop-rep.js +++ b/src/reps/prop-rep.js @@ -1,4 +1,9 @@ +// Dependencies const React = require("react"); +const { + createFactories, + wrapRender, +} = require("./rep-utils"); const { MODE } = require("./constants"); // Shortcuts const { span } = React.DOM; @@ -8,7 +13,7 @@ const { span } = React.DOM; * and GripMap (remote JS maps and weakmaps) reps. * It's used to render object properties. */ -let PropRep = React.createFactory(React.createClass({ +let PropRep = React.createClass({ displayName: "PropRep", propTypes: { @@ -23,11 +28,12 @@ let PropRep = React.createFactory(React.createClass({ delim: React.PropTypes.string, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, }, - render: function () { - const Grip = require("./grip"); - let Rep = React.createFactory(require("./rep")); + render: wrapRender(function () { + const { Grip } = require("./grip"); + let { Rep } = createFactories(require("./rep")); let key; // The key can be a simple string, for plain objects, @@ -55,7 +61,8 @@ let PropRep = React.createFactory(React.createClass({ }, this.props.delim) ) ); - } -})); + }) +}); -module.exports = PropRep; +// Exports from this module +module.exports = PropRep; \ No newline at end of file diff --git a/src/reps/regexp.js b/src/reps/regexp.js index 1200fcf..8bec89b 100644 --- a/src/reps/regexp.js +++ b/src/reps/regexp.js @@ -1,7 +1,11 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip } = require("./rep-utils"); +const { + isGrip, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -14,13 +18,14 @@ let RegExp = React.createClass({ propTypes: { object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getSource: function (grip) { return grip.displayString; }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; let objectLink = this.props.objectLink || span; @@ -32,7 +37,7 @@ let RegExp = React.createClass({ }, this.getSource(grip)) ) ); - }, + }), }); // Registration @@ -45,6 +50,7 @@ function supportsObject(object, type) { return (type == "RegExp"); } +// Exports from this module module.exports = { rep: RegExp, supportsObject: supportsObject diff --git a/src/reps/rep-utils.js b/src/reps/rep-utils.js index 1facc3d..ae3ed93 100644 --- a/src/reps/rep-utils.js +++ b/src/reps/rep-utils.js @@ -1,3 +1,4 @@ +// Dependencies const React = require("react"); /** @@ -135,11 +136,33 @@ function splitURLTrue(url) { }; } +/** + * Wrap the provided render() method of a rep in a try/catch block that will render a + * fallback rep if the render fails. + */ +function wrapRender(renderMethod) { + return function () { + try { + return renderMethod.call(this); + } catch (e) { + return React.DOM.span( + { + className: "objectBox objectBox-failure", + title: "This object could not be rendered, " + + "please file a bug on bugzilla.mozilla.org" + }, + /* Labels have to be hardcoded for reps, see Bug 1317038. */ + "Invalid object"); + } + }; +} + module.exports = { createFactories, isGrip, cropString, sanitizeString, + wrapRender, cropMultipleLines, parseURLParams, parseURLEncodedText, diff --git a/src/reps/rep.js b/src/reps/rep.js index 8cebca6..ab84da9 100644 --- a/src/reps/rep.js +++ b/src/reps/rep.js @@ -132,4 +132,37 @@ function getRep(object, defaultRep = Obj) { return React.createFactory(defaultRep.rep); } -module.exports = Rep; +module.exports = { + Rep, + REPS: { + ArrayRep, + Attribute, + CommentNode, + DateTime, + Document, + ElementNode, + ErrorRep, + Event, + Func, + Grip, + GripArray, + GripMap, + InfinityRep, + LongStringRep, + NaNRep, + Null, + Number, + Obj, + ObjectWithText, + ObjectWithURL, + PromiseRep, + RegExp, + Rep, + StringRep, + StyleSheet, + SymbolRep, + TextNode, + Undefined, + Window, + } +}; diff --git a/src/reps/string.js b/src/reps/string.js index 1561b41..88ec0bf 100644 --- a/src/reps/string.js +++ b/src/reps/string.js @@ -1,5 +1,10 @@ +// Dependencies const React = require("react"); -const { cropString } = require("./rep-utils"); + +const { + cropString, + wrapRender, +} = require("./rep-utils"); // Shortcuts const { span } = React.DOM; @@ -13,6 +18,9 @@ const StringRep = React.createClass({ propTypes: { useQuotes: React.PropTypes.bool, style: React.PropTypes.object, + object: React.PropTypes.string.isRequired, + member: React.PropTypes.any, + cropLimit: React.PropTypes.number, }, getDefaultProps: function () { @@ -21,7 +29,7 @@ const StringRep = React.createClass({ }; }, - render: function () { + render: wrapRender(function () { let text = this.props.object; let member = this.props.member; let style = this.props.style; @@ -42,13 +50,15 @@ const StringRep = React.createClass({ "\"" + croppedString + "\"" : croppedString; return span(config, formattedString); - }, + }), }); function supportsObject(object, type) { return (type == "string"); } +// Exports from this module + module.exports = { rep: StringRep, supportsObject: supportsObject, diff --git a/src/reps/stylesheet.js b/src/reps/stylesheet.js index 2b9a646..68fe4ee 100644 --- a/src/reps/stylesheet.js +++ b/src/reps/stylesheet.js @@ -1,7 +1,12 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip, getURLDisplayString } = require("./rep-utils"); +const { + isGrip, + getURLDisplayString, + wrapRender +} = require("./rep-utils"); // Shortcuts const DOM = React.DOM; @@ -14,6 +19,7 @@ let StyleSheet = React.createClass({ propTypes: { object: React.PropTypes.object.isRequired, + objectLink: React.PropTypes.func, }, getTitle: function (grip) { @@ -34,7 +40,7 @@ let StyleSheet = React.createClass({ return url ? getURLDisplayString(url) : ""; }, - render: function () { + render: wrapRender(function () { let grip = this.props.object; return ( @@ -45,7 +51,7 @@ let StyleSheet = React.createClass({ ) ) ); - }, + }), }); // Registration @@ -58,6 +64,8 @@ function supportsObject(object, type) { return (type == "CSSStyleSheet"); } +// Exports from this module + module.exports = { rep: StyleSheet, supportsObject: supportsObject diff --git a/src/reps/symbol.js b/src/reps/symbol.js index a5eb0e5..7c803d6 100644 --- a/src/reps/symbol.js +++ b/src/reps/symbol.js @@ -1,5 +1,8 @@ +// Dependencies const React = require("react"); +const { wrapRender } = require("./rep-utils"); + // Shortcuts const { span } = React.DOM; @@ -13,7 +16,7 @@ const SymbolRep = React.createClass({ object: React.PropTypes.object.isRequired }, - render: function () { + render: wrapRender(function () { let {object} = this.props; let {name} = object; @@ -22,13 +25,14 @@ const SymbolRep = React.createClass({ `Symbol(${name || ""})` ) ); - }, + }), }); function supportsObject(object, type) { return (type == "symbol"); } +// Exports from this module module.exports = { rep: SymbolRep, supportsObject: supportsObject, diff --git a/src/reps/text-node.js b/src/reps/text-node.js index b984da4..f51c14a 100644 --- a/src/reps/text-node.js +++ b/src/reps/text-node.js @@ -1,7 +1,12 @@ +// ReactJS const React = require("react"); // Reps -const { isGrip, cropString } = require("./rep-utils"); +const { + isGrip, + cropString, + wrapRender, +} = require("./rep-utils"); const { MODE } = require("./constants"); // Shortcuts @@ -17,6 +22,9 @@ let TextNode = React.createClass({ object: React.PropTypes.object.isRequired, // @TODO Change this to Object.values once it's supported in Node's version of V8 mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, + onDOMNodeMouseOver: React.PropTypes.func, + onDOMNodeMouseOut: React.PropTypes.func, }, getTextContent: function (grip) { @@ -33,7 +41,7 @@ let TextNode = React.createClass({ return title; }, - render: function () { + render: wrapRender(function () { let { object: grip, mode = MODE.SHORT, @@ -65,7 +73,7 @@ let TextNode = React.createClass({ ) ) ); - }, + }), }); // Registration @@ -78,6 +86,7 @@ function supportsObject(grip, type) { return (grip.preview && grip.class == "Text"); } +// Exports from this module module.exports = { rep: TextNode, supportsObject: supportsObject diff --git a/src/reps/undefined.js b/src/reps/undefined.js index c5b9e83..27eacde 100644 --- a/src/reps/undefined.js +++ b/src/reps/undefined.js @@ -1,5 +1,8 @@ +// Dependencies const React = require("react"); +const { wrapRender } = require("./rep-utils"); + // Shortcuts const { span } = React.DOM; @@ -9,13 +12,13 @@ const { span } = React.DOM; const Undefined = React.createClass({ displayName: "UndefinedRep", - render: function () { + render: wrapRender(function () { return ( span({className: "objectBox objectBox-undefined"}, "undefined" ) ); - }, + }), }); function supportsObject(object, type) { @@ -26,6 +29,8 @@ function supportsObject(object, type) { return (type == "undefined"); } +// Exports from this module + module.exports = { rep: Undefined, supportsObject: supportsObject diff --git a/src/reps/window.js b/src/reps/window.js index 128753b..c787683 100644 --- a/src/reps/window.js +++ b/src/reps/window.js @@ -1,8 +1,12 @@ +// ReactJS const React = require("react"); -const { MODE } = require("./constants"); // Reps -const { isGrip, getURLDisplayString } = require("./rep-utils"); +const { + isGrip, + getURLDisplayString, + wrapRender +} = require("./rep-utils"); // Shortcuts const DOM = React.DOM; @@ -15,7 +19,7 @@ let Window = React.createClass({ propTypes: { object: React.PropTypes.object.isRequired, - mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])), + objectLink: React.PropTypes.func, }, getTitle: function (grip) { @@ -33,26 +37,18 @@ let Window = React.createClass({ return getURLDisplayString(grip.preview.url); }, - getDisplayValue: function (grip) { - if (this.props.mode === MODE.TINY) { - return grip.isGlobal ? "Global" : "Window"; - } - - return this.getLocation(grip); - }, - - render: function () { + render: wrapRender(function () { let grip = this.props.object; return ( DOM.span({className: "objectBox objectBox-Window"}, this.getTitle(grip), DOM.span({className: "objectPropValue"}, - this.getDisplayValue(grip) + this.getLocation(grip) ) ) ); - }, + }), }); // Registration @@ -65,6 +61,7 @@ function supportsObject(object, type) { return (object.preview && type == "Window"); } +// Exports from this module module.exports = { rep: Window, supportsObject: supportsObject diff --git a/src/test/mochitest/chrome.ini b/src/test/mochitest/chrome.ini index 3aa3f65..5f5c14e 100644 --- a/src/test/mochitest/chrome.ini +++ b/src/test/mochitest/chrome.ini @@ -2,11 +2,6 @@ support-files = head.js -[test_frame_01.html] -[test_HSplitBox_01.html] -[test_notification_box_01.html] -[test_notification_box_02.html] -[test_notification_box_03.html] [test_reps_array.html] [test_reps_attribute.html] [test_reps_comment-node.html] @@ -15,6 +10,7 @@ support-files = [test_reps_element-node.html] [test_reps_error.html] [test_reps_event.html] +[test_reps_failure.html] [test_reps_function.html] [test_reps_grip.html] [test_reps_grip-array.html] @@ -34,19 +30,4 @@ support-files = [test_reps_symbol.html] [test_reps_text-node.html] [test_reps_undefined.html] -[test_reps_window.html] -[test_sidebar_toggle.html] -[test_stack-trace.html] -[test_tabs_accessibility.html] -[test_tabs_menu.html] -[test_tree_01.html] -[test_tree_02.html] -[test_tree_03.html] -[test_tree_04.html] -[test_tree_05.html] -[test_tree_06.html] -[test_tree_07.html] -[test_tree_08.html] -[test_tree_09.html] -[test_tree_10.html] -[test_tree_11.html] +[test_reps_window.html] \ No newline at end of file diff --git a/src/test/mochitest/head.js b/src/test/mochitest/head.js index b66b728..3e5d874 100644 --- a/src/test/mochitest/head.js +++ b/src/test/mochitest/head.js @@ -11,16 +11,8 @@ var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); var { Assert } = require("resource://testing-common/Assert.jsm"); var { gDevTools } = require("devtools/client/framework/devtools"); var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {}); -var promise = require("promise"); -var defer = require("devtools/shared/defer"); -var Services = require("Services"); -var { DebuggerServer } = require("devtools/server/main"); -var { DebuggerClient } = require("devtools/shared/client/main"); -var DevToolsUtils = require("devtools/shared/DevToolsUtils"); var flags = require("devtools/shared/flags"); var { Task } = require("devtools/shared/task"); -var { TargetFactory } = require("devtools/client/framework/target"); -var { Toolbox } = require("devtools/client/framework/toolbox"); flags.testing = true; var { require: browserRequire } = BrowserLoader({ @@ -32,158 +24,6 @@ let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom"); let React = browserRequire("devtools/client/shared/vendor/react"); var TestUtils = React.addons.TestUtils; -var EXAMPLE_URL = "http://example.com/browser/browser/devtools/shared/test/"; - -function forceRender(comp) { - return setState(comp, {}) - .then(() => setState(comp, {})); -} - -// All tests are asynchronous. -SimpleTest.waitForExplicitFinish(); - -function onNextAnimationFrame(fn) { - return () => - requestAnimationFrame(() => - requestAnimationFrame(fn)); -} - -function setState(component, newState) { - return new Promise(resolve => { - component.setState(newState, onNextAnimationFrame(resolve)); - }); -} - -function setProps(component, newProps) { - return new Promise(resolve => { - component.setProps(newProps, onNextAnimationFrame(resolve)); - }); -} - -function dumpn(msg) { - dump(`SHARED-COMPONENTS-TEST: ${msg}\n`); -} - -/** - * Tree - */ - -var TEST_TREE_INTERFACE = { - getParent: x => TEST_TREE.parent[x], - getChildren: x => TEST_TREE.children[x], - renderItem: (x, depth, focused) => "-".repeat(depth) + x + ":" + focused + "\n", - getRoots: () => ["A", "M"], - getKey: x => "key-" + x, - itemHeight: 1, - onExpand: x => TEST_TREE.expanded.add(x), - onCollapse: x => TEST_TREE.expanded.delete(x), - isExpanded: x => TEST_TREE.expanded.has(x), -}; - -function isRenderedTree(actual, expectedDescription, msg) { - const expected = expectedDescription.map(x => x + "\n").join(""); - dumpn(`Expected tree:\n${expected}`); - dumpn(`Actual tree:\n${actual}`); - is(actual, expected, msg); -} - -// Encoding of the following tree/forest: -// -// A -// |-- B -// | |-- E -// | | |-- K -// | | `-- L -// | |-- F -// | `-- G -// |-- C -// | |-- H -// | `-- I -// `-- D -// `-- J -// M -// `-- N -// `-- O -var TEST_TREE = { - children: { - A: ["B", "C", "D"], - B: ["E", "F", "G"], - C: ["H", "I"], - D: ["J"], - E: ["K", "L"], - F: [], - G: [], - H: [], - I: [], - J: [], - K: [], - L: [], - M: ["N"], - N: ["O"], - O: [] - }, - parent: { - A: null, - B: "A", - C: "A", - D: "A", - E: "B", - F: "B", - G: "B", - H: "C", - I: "C", - J: "D", - K: "E", - L: "E", - M: null, - N: "M", - O: "N" - }, - expanded: new Set(), -}; - -/** - * Frame - */ -function checkFrameString({ - el, file, line, column, source, functionName, shouldLink, tooltip -}) { - let $ = selector => el.querySelector(selector); - - let $func = $(".frame-link-function-display-name"); - let $source = $(".frame-link-source"); - let $sourceInner = $(".frame-link-source-inner"); - let $filename = $(".frame-link-filename"); - let $line = $(".frame-link-line"); - - is($filename.textContent, file, "Correct filename"); - is(el.getAttribute("data-line"), line ? `${line}` : null, "Expected `data-line` found"); - is(el.getAttribute("data-column"), - column ? `${column}` : null, "Expected `data-column` found"); - is($sourceInner.getAttribute("title"), tooltip, "Correct tooltip"); - is($source.tagName, shouldLink ? "A" : "SPAN", "Correct linkable status"); - if (shouldLink) { - is($source.getAttribute("href"), source, "Correct source"); - } - - if (line != null) { - let lineText = `:${line}`; - if (column != null) { - lineText += `:${column}`; - } - - is($line.textContent, lineText, "Correct line number"); - } else { - ok(!$line, "Should not have an element for `line`"); - } - - if (functionName != null) { - is($func.textContent, functionName, "Correct function name"); - } else { - ok(!$func, "Should not have an element for `functionName`"); - } -} - function renderComponent(component, props) { const el = React.createElement(component, props, {}); // By default, renderIntoDocument() won't work for stateless components, but @@ -206,7 +46,7 @@ function shallowRenderComponent(component, props) { */ function testRepRenderModes(modeTests, testName, componentUnderTest, gripStub) { modeTests.forEach(({mode, expectedOutput, message}) => { - const modeString = typeof mode === "undefined" ? "no mode" : mode; + const modeString = typeof mode === "undefined" ? "no mode" : mode.toString(); if (!message) { message = `${testName}: ${modeString} renders correctly.`; } diff --git a/src/test/mochitest/test_reps_array.html b/src/test/mochitest/test_reps_array.html index 6ad7f2c..24fb11e 100644 --- a/src/test/mochitest/test_reps_array.html +++ b/src/test/mochitest/test_reps_array.html @@ -20,13 +20,13 @@ /* import-globals-from head.js */ window.onload = Task.async(function* () { - let { Rep } = browserRequire("devtools/client/shared/components/reps/rep"); - let { ArrayRep } = browserRequire("devtools/client/shared/components/reps/array"); + const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/load-reps"); + let { Rep, ArrayRep } = REPS; let componentUnderTest = ArrayRep; const maxLength = { short: 3, - long: 300 + long: 10 }; try { @@ -65,15 +65,15 @@ expectedOutput: defaultOutput, }, { - mode: "tiny", + mode: MODE.TINY, expectedOutput: `[]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: defaultOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: defaultOutput, } ]; @@ -91,15 +91,15 @@ expectedOutput: defaultOutput, }, { - mode: "tiny", + mode: MODE.TINY, expectedOutput: `[3]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: defaultOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: defaultOutput, } ]; @@ -117,15 +117,15 @@ expectedOutput: defaultShortOutput, }, { - mode: "tiny", + mode: MODE.TINY, expectedOutput: `[${maxLength.short + 1}]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: defaultShortOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: `[ ${Array(maxLength.short + 1).fill("\"foo\"").join(", ")} ]`, } ]; @@ -144,15 +144,15 @@ expectedOutput: defaultShortOutput, }, { - mode: "tiny", + mode: MODE.TINY, expectedOutput: `[${maxLength.long + 1}]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: defaultShortOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: defaultLongOutput, } ]; @@ -171,15 +171,15 @@ expectedOutput: defaultOutput, }, { - mode: "tiny", + mode: MODE.TINY, expectedOutput: `[2]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: defaultOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: defaultOutput, } ]; @@ -204,15 +204,15 @@ expectedOutput: defaultOutput, }, { - mode: "tiny", + mode: MODE.TINY, expectedOutput: `[1]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: defaultOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: defaultOutput, } ]; @@ -222,14 +222,10 @@ function testArray() { let stub = [ - "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", - "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" - ]; + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; - const defaultOutput = `[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",` + - ` "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",` + - ` "u", "v", "w", "x", "y", "z" ]`; - const shortOutput = `[ "a", "b", "c", 23 more… ]`; + const defaultOutput = `[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" ]`; + const shortOutput = `[ "a", "b", "c", 7 more… ]`; const modeTests = [ { @@ -237,15 +233,15 @@ expectedOutput: shortOutput, }, { - mode: "tiny", - expectedOutput: `[26]`, + mode: MODE.TINY, + expectedOutput: `[10]`, }, { - mode: "short", + mode: MODE.SHORT, expectedOutput: shortOutput, }, { - mode: "long", + mode: MODE.LONG, expectedOutput: defaultOutput, } ]; diff --git a/src/test/mochitest/test_reps_attribute.html b/src/test/mochitest/test_reps_attribute.html index aa8a5df..a19a868 100644 --- a/src/test/mochitest/test_reps_attribute.html +++ b/src/test/mochitest/test_reps_attribute.html @@ -18,8 +18,8 @@ + + + +
+
+
+
+ + \ No newline at end of file diff --git a/src/test/mochitest/test_reps_function.html b/src/test/mochitest/test_reps_function.html index ede6943..606391a 100644 --- a/src/test/mochitest/test_reps_function.html +++ b/src/test/mochitest/test_reps_function.html @@ -17,8 +17,8 @@