зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1370139 - Escape slashes in TreeView paths. r=Honza
This commit is contained in:
Родитель
5d8aa01e08
Коммит
d4593a2a0d
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
define(function (require, exports, module) {
|
define(function (require, exports, module) {
|
||||||
const { DOM: dom, createFactory, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
|
const { DOM: dom, createFactory, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
|
||||||
const TreeView = createFactory(require("devtools/client/shared/components/tree/tree-view"));
|
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
|
||||||
|
const TreeView = createFactory(TreeViewClass);
|
||||||
|
|
||||||
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
|
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
|
||||||
const { createFactories } = require("devtools/client/shared/react-utils");
|
const { createFactories } = require("devtools/client/shared/react-utils");
|
||||||
|
@ -65,28 +66,6 @@ define(function (require, exports, module) {
|
||||||
return json.toLowerCase().indexOf(this.props.searchFilter.toLowerCase()) >= 0;
|
return json.toLowerCase().indexOf(this.props.searchFilter.toLowerCase()) >= 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
getExpandedNodes: function (object, path = "", level = 0) {
|
|
||||||
if (typeof object != "object") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level > AUTO_EXPAND_MAX_LEVEL) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let expandedNodes = new Set();
|
|
||||||
for (let prop in object) {
|
|
||||||
let nodePath = path + "/" + prop;
|
|
||||||
expandedNodes.add(nodePath);
|
|
||||||
|
|
||||||
let nodes = this.getExpandedNodes(object[prop], nodePath, level + 1);
|
|
||||||
if (nodes) {
|
|
||||||
expandedNodes = new Set([...expandedNodes, ...nodes]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return expandedNodes;
|
|
||||||
},
|
|
||||||
|
|
||||||
renderValue: props => {
|
renderValue: props => {
|
||||||
let member = props.member;
|
let member = props.member;
|
||||||
|
|
||||||
|
@ -112,7 +91,10 @@ define(function (require, exports, module) {
|
||||||
// Expand the document by default if its size isn't bigger than 100KB.
|
// Expand the document by default if its size isn't bigger than 100KB.
|
||||||
let expandedNodes = new Set();
|
let expandedNodes = new Set();
|
||||||
if (this.props.jsonTextLength <= AUTO_EXPAND_MAX_SIZE) {
|
if (this.props.jsonTextLength <= AUTO_EXPAND_MAX_SIZE) {
|
||||||
expandedNodes = this.getExpandedNodes(this.props.data);
|
expandedNodes = TreeViewClass.getExpandedNodes(
|
||||||
|
this.props.data,
|
||||||
|
{maxLevel: AUTO_EXPAND_MAX_LEVEL}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render tree component.
|
// Render tree component.
|
||||||
|
|
|
@ -35,6 +35,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
||||||
[browser_jsonview_save_json.js]
|
[browser_jsonview_save_json.js]
|
||||||
support-files =
|
support-files =
|
||||||
!/toolkit/content/tests/browser/common/mockTransfer.js
|
!/toolkit/content/tests/browser/common/mockTransfer.js
|
||||||
|
[browser_jsonview_slash.js]
|
||||||
[browser_jsonview_utf8.js]
|
[browser_jsonview_utf8.js]
|
||||||
[browser_jsonview_valid_json.js]
|
[browser_jsonview_valid_json.js]
|
||||||
[browser_json_refresh.js]
|
[browser_json_refresh.js]
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
add_task(function* () {
|
||||||
|
info("Test JSON with NUL started.");
|
||||||
|
|
||||||
|
const TEST_JSON_URL = "data:application/json,{\"a/b\":[1,2],\"a\":{\"b\":[3,4]}}";
|
||||||
|
yield addJsonViewTab(TEST_JSON_URL);
|
||||||
|
|
||||||
|
let countBefore = yield getElementCount(".jsonPanelBox .treeTable .treeRow");
|
||||||
|
ok(countBefore == 7, "There must be seven rows");
|
||||||
|
});
|
|
@ -20,7 +20,8 @@ const { FILTER_SEARCH_DELAY } = require("../constants");
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
const SearchBox = createFactory(require("devtools/client/shared/components/search-box"));
|
const SearchBox = createFactory(require("devtools/client/shared/components/search-box"));
|
||||||
const TreeView = createFactory(require("devtools/client/shared/components/tree/tree-view"));
|
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
|
||||||
|
const TreeView = createFactory(TreeViewClass);
|
||||||
const TreeRow = createFactory(require("devtools/client/shared/components/tree/tree-row"));
|
const TreeRow = createFactory(require("devtools/client/shared/components/tree/tree-row"));
|
||||||
const SourceEditor = createFactory(require("./source-editor"));
|
const SourceEditor = createFactory(require("./source-editor"));
|
||||||
|
|
||||||
|
@ -137,38 +138,6 @@ const PropertiesView = createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getExpandedNodes: function (object, path = "", level = 0) {
|
|
||||||
if (typeof object != "object") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level > AUTO_EXPAND_MAX_LEVEL) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let expandedNodes = new Set();
|
|
||||||
for (let prop in object) {
|
|
||||||
if (expandedNodes.size > AUTO_EXPAND_MAX_NODES) {
|
|
||||||
// If we reached the limit of expandable nodes, bail out to avoid performance
|
|
||||||
// issues.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let nodePath = path + "/" + prop;
|
|
||||||
expandedNodes.add(nodePath);
|
|
||||||
|
|
||||||
let nodes = this.getExpandedNodes(object[prop], nodePath, level + 1);
|
|
||||||
if (nodes) {
|
|
||||||
let newSize = expandedNodes.size + nodes.size;
|
|
||||||
if (newSize < AUTO_EXPAND_MAX_NODES) {
|
|
||||||
// Avoid having a subtree half expanded.
|
|
||||||
expandedNodes = new Set([...expandedNodes, ...nodes]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return expandedNodes;
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
decorator,
|
decorator,
|
||||||
|
@ -205,7 +174,10 @@ const PropertiesView = createClass({
|
||||||
enableInput,
|
enableInput,
|
||||||
expandableStrings,
|
expandableStrings,
|
||||||
useQuotes: false,
|
useQuotes: false,
|
||||||
expandedNodes: this.getExpandedNodes(object),
|
expandedNodes: TreeViewClass.getExpandedNodes(
|
||||||
|
object,
|
||||||
|
{maxLevel: AUTO_EXPAND_MAX_LEVEL, maxNodes: AUTO_EXPAND_MAX_NODES}
|
||||||
|
),
|
||||||
onFilter: (props) => this.onFilter(props, sectionNames),
|
onFilter: (props) => this.onFilter(props, sectionNames),
|
||||||
renderRow: renderRow || this.renderRowWithEditor,
|
renderRow: renderRow || this.renderRowWithEditor,
|
||||||
renderValue: renderValue || this.renderValueWithRep,
|
renderValue: renderValue || this.renderValueWithRep,
|
||||||
|
|
|
@ -13,6 +13,7 @@ const { L10N } = require("../utils/l10n");
|
||||||
const { getUrlHost } = require("../utils/request-utils");
|
const { getUrlHost } = require("../utils/request-utils");
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
|
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
|
||||||
const PropertiesView = createFactory(require("./properties-view"));
|
const PropertiesView = createFactory(require("./properties-view"));
|
||||||
|
|
||||||
const { div, input, span } = DOM;
|
const { div, input, span } = DOM;
|
||||||
|
@ -95,7 +96,7 @@ function SecurityPanel({ request }) {
|
||||||
object,
|
object,
|
||||||
renderValue: (props) => renderValue(props, securityInfo.weaknessReasons),
|
renderValue: (props) => renderValue(props, securityInfo.weaknessReasons),
|
||||||
enableFilter: false,
|
enableFilter: false,
|
||||||
expandedNodes: getExpandedNodes(object),
|
expandedNodes: TreeViewClass.getExpandedNodes(object),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -139,22 +140,4 @@ function renderValue(props, weaknessReasons = []) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExpandedNodes(object, path = "", level = 0) {
|
|
||||||
if (typeof object !== "object") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let expandedNodes = new Set();
|
|
||||||
for (let prop in object) {
|
|
||||||
let nodePath = path + "/" + prop;
|
|
||||||
expandedNodes.add(nodePath);
|
|
||||||
|
|
||||||
let nodes = getExpandedNodes(object[prop], nodePath, level + 1);
|
|
||||||
if (nodes) {
|
|
||||||
expandedNodes = new Set([...expandedNodes, ...nodes]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return expandedNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = SecurityPanel;
|
module.exports = SecurityPanel;
|
||||||
|
|
|
@ -277,7 +277,7 @@ define(function (require, exports, module) {
|
||||||
|
|
||||||
return children.map(child => {
|
return children.map(child => {
|
||||||
let key = provider.getKey(child);
|
let key = provider.getKey(child);
|
||||||
let nodePath = path + "/" + key;
|
let nodePath = TreeView.subPath(path, key);
|
||||||
let type = provider.getType(child);
|
let type = provider.getType(child);
|
||||||
let hasChildren = provider.hasChildren(child);
|
let hasChildren = provider.hasChildren(child);
|
||||||
|
|
||||||
|
@ -419,6 +419,55 @@ define(function (require, exports, module) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TreeView.subPath = function (path, subKey) {
|
||||||
|
return path + "/" + subKey.replace(/[\\/]/g, "\\$&");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a set with the paths of the nodes that should be expanded by default
|
||||||
|
* according to the passed options.
|
||||||
|
* @param {Object} The root node of the tree.
|
||||||
|
* @param {Object} [optional] An object with the following optional parameters:
|
||||||
|
* - maxLevel: nodes nested deeper than this level won't be expanded.
|
||||||
|
* - maxNodes: maximum number of nodes that can be expanded. The traversal is
|
||||||
|
breadth-first, so expanding nodes nearer to the root will be preferred.
|
||||||
|
Sibling nodes will either be all expanded or none expanded.
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
TreeView.getExpandedNodes = function (rootObj,
|
||||||
|
{ maxLevel = Infinity, maxNodes = Infinity } = {}
|
||||||
|
) {
|
||||||
|
let expandedNodes = new Set();
|
||||||
|
let queue = [{
|
||||||
|
object: rootObj,
|
||||||
|
level: 1,
|
||||||
|
path: ""
|
||||||
|
}];
|
||||||
|
while (queue.length) {
|
||||||
|
let {object, level, path} = queue.shift();
|
||||||
|
if (Object(object) !== object) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let keys = Object.keys(object);
|
||||||
|
if (expandedNodes.size + keys.length > maxNodes) {
|
||||||
|
// Avoid having children half expanded.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (let key of keys) {
|
||||||
|
let nodePath = TreeView.subPath(path, key);
|
||||||
|
expandedNodes.add(nodePath);
|
||||||
|
if (level < maxLevel) {
|
||||||
|
queue.push({
|
||||||
|
object: object[key],
|
||||||
|
level: level + 1,
|
||||||
|
path: nodePath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return expandedNodes;
|
||||||
|
};
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Загрузка…
Ссылка в новой задаче