From 86c2afef9c98625d09618f63983fd2d28150ebed Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Thu, 3 Nov 2016 18:08:16 +0100 Subject: [PATCH] Bug 1302982 - Add Rep for LongString; r=Honza Display a longString with what is available on the grip. Straight from the server, a longString grip has a "initial" property, which contains the first 10000 chars of the string. The grip can also contains a "fullText" property that should be set when the user want to display the full text of the string. For example, in the DOM Panel, it would be when the user click on the expand arrow. The fullText needs to be computed with the result of the LongStringClient.substring function, but it's not the responsability of the Reps to do such thing. In rep-utils, we extract the logic that replace non-printable characters in its own function and export it, so we can use it outside the cropString function. Add some test to make sure LongString are displayed as expected in the several modes. MozReview-Commit-ID: 3P9fPBixm2v --HG-- extra : rebase_source : 87ed610cb6d2e142728f0df9d35f1dd7a4748d18 --- .../shared/components/reps/long-string.js | 71 ++++++++++ .../client/shared/components/reps/moz.build | 1 + .../shared/components/reps/rep-utils.js | 21 +-- devtools/client/shared/components/reps/rep.js | 2 + .../components/test/mochitest/chrome.ini | 1 + .../test/mochitest/test_reps_long-string.html | 125 ++++++++++++++++++ 6 files changed, 212 insertions(+), 9 deletions(-) create mode 100644 devtools/client/shared/components/reps/long-string.js create mode 100644 devtools/client/shared/components/test/mochitest/test_reps_long-string.html diff --git a/devtools/client/shared/components/reps/long-string.js b/devtools/client/shared/components/reps/long-string.js new file mode 100644 index 000000000000..f19f020dcd67 --- /dev/null +++ b/devtools/client/shared/components/reps/long-string.js @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Make this available to both AMD and CJS environments +define(function (require, exports, module) { + // Dependencies + const React = require("devtools/client/shared/vendor/react"); + const { sanitizeString, isGrip } = require("./rep-utils"); + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a long string grip. + */ + const LongStringRep = React.createClass({ + displayName: "LongStringRep", + + propTypes: { + useQuotes: React.PropTypes.bool, + style: React.PropTypes.object, + }, + + getDefaultProps: function () { + return { + useQuotes: true, + }; + }, + + render: function () { + let { + cropLimit, + member, + object, + style, + useQuotes + } = this.props; + let {fullText, initial, length} = object; + + let config = {className: "objectBox objectBox-string"}; + if (style) { + config.style = style; + } + + let string = member && member.open + ? fullText || initial + : initial.substring(0, cropLimit); + + if (string.length < length) { + string += "\u2026"; + } + let formattedString = useQuotes ? `"${string}"` : string; + return span(config, sanitizeString(formattedString)); + }, + }); + + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + return object.type === "longString"; + } + + // Exports from this module + exports.LongStringRep = { + rep: LongStringRep, + supportsObject: supportsObject, + }; +}); diff --git a/devtools/client/shared/components/reps/moz.build b/devtools/client/shared/components/reps/moz.build index 0f54b1ae802e..f5df589f733d 100644 --- a/devtools/client/shared/components/reps/moz.build +++ b/devtools/client/shared/components/reps/moz.build @@ -18,6 +18,7 @@ DevToolsModules( 'grip-map.js', 'grip.js', 'infinity.js', + 'long-string.js', 'nan.js', 'null.js', 'number.js', diff --git a/devtools/client/shared/components/reps/rep-utils.js b/devtools/client/shared/components/reps/rep-utils.js index d26996b64af4..d9580ac8d46e 100644 --- a/devtools/client/shared/components/reps/rep-utils.js +++ b/devtools/client/shared/components/reps/rep-utils.js @@ -45,15 +45,8 @@ define(function (require, exports, module) { alternativeText = "\u2026"; } - // Make sure it's a string. - text = text + ""; - - // Replace all non-printable characters, except of - // (horizontal) tab (HT: \x09) and newline (LF: \x0A, CR: \x0D), - // with unicode replacement character (u+fffd). - // eslint-disable-next-line no-control-regex - let re = new RegExp("[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]", "g"); - text = text.replace(re, "\ufffd"); + // Make sure it's a string and sanitize it. + text = sanitizeString(text + ""); // Crop the string only if a limit is actually specified. if (!limit || limit <= 0) { @@ -76,6 +69,15 @@ define(function (require, exports, module) { return text; } + function sanitizeString(text) { + // Replace all non-printable characters, except of + // (horizontal) tab (HT: \x09) and newline (LF: \x0A, CR: \x0D), + // with unicode replacement character (u+fffd). + // eslint-disable-next-line no-control-regex + let re = new RegExp("[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]", "g"); + return text.replace(re, "\ufffd"); + } + function parseURLParams(url) { url = new URL(url); return parseURLEncodedText(url.searchParams); @@ -154,4 +156,5 @@ define(function (require, exports, module) { exports.parseURLEncodedText = parseURLEncodedText; exports.getFileName = getFileName; exports.getURLDisplayString = getURLDisplayString; + exports.sanitizeString = sanitizeString; }); diff --git a/devtools/client/shared/components/reps/rep.js b/devtools/client/shared/components/reps/rep.js index fde4ae08aae5..0891fe0cef2b 100644 --- a/devtools/client/shared/components/reps/rep.js +++ b/devtools/client/shared/components/reps/rep.js @@ -17,6 +17,7 @@ define(function (require, exports, module) { const { Undefined } = require("./undefined"); const { Null } = require("./null"); const { StringRep } = require("./string"); + const { LongStringRep } = require("./long-string"); const { Number } = require("./number"); const { ArrayRep } = require("./array"); const { Obj } = require("./object"); @@ -55,6 +56,7 @@ define(function (require, exports, module) { ElementNode, TextNode, Attribute, + LongStringRep, Func, PromiseRep, ArrayRep, diff --git a/devtools/client/shared/components/test/mochitest/chrome.ini b/devtools/client/shared/components/test/mochitest/chrome.ini index a375f26a1026..27a4be137fed 100644 --- a/devtools/client/shared/components/test/mochitest/chrome.ini +++ b/devtools/client/shared/components/test/mochitest/chrome.ini @@ -19,6 +19,7 @@ support-files = [test_reps_grip-array.html] [test_reps_grip-map.html] [test_reps_infinity.html] +[test_reps_long-string.html] [test_reps_nan.html] [test_reps_null.html] [test_reps_number.html] diff --git a/devtools/client/shared/components/test/mochitest/test_reps_long-string.html b/devtools/client/shared/components/test/mochitest/test_reps_long-string.html new file mode 100644 index 000000000000..3caaac913637 --- /dev/null +++ b/devtools/client/shared/components/test/mochitest/test_reps_long-string.html @@ -0,0 +1,125 @@ + + + + + + + Rep test - LongString + + + + +
+
+
+
+ +