Bug 1264557 - Add expand all/collapse all buttons. r=Honza

This adds buttons to collapse and expand the JSON tree. If the file
is larger than 100kB the "Expand All" button is hidden for performance
reasonds, as well as test cases for the buttons.
This commit is contained in:
Ognjen Galic 2018-05-05 12:40:18 +02:00
Родитель 9800e813cf
Коммит d92f87e2e0
7 изменённых файлов: 79 добавлений и 4 удалений

Просмотреть файл

@ -40,6 +40,7 @@ define(function(require, exports, module) {
PropTypes.bool,
PropTypes.number
]),
dataSize: PropTypes.number,
expandedNodes: PropTypes.instanceOf(Set),
searchFilter: PropTypes.string,
actions: PropTypes.object,
@ -136,7 +137,7 @@ define(function(require, exports, module) {
return (
div({className: "jsonPanelBox tab-panel-inner"},
JsonToolbar({actions: this.props.actions}),
JsonToolbar({actions: this.props.actions, dataSize: this.props.dataSize}),
div({className: "panelContent"},
content
)

Просмотреть файл

@ -15,6 +15,9 @@ define(function(require, exports, module) {
const { SearchBox } = createFactories(require("./SearchBox"));
const { Toolbar, ToolbarButton } = createFactories(require("./reps/Toolbar"));
/* 100kB file */
const EXPAND_THRESHOLD = 100 * 1024;
/**
* This template represents a toolbar within the 'JSON' panel.
*/
@ -22,6 +25,7 @@ define(function(require, exports, module) {
static get propTypes() {
return {
actions: PropTypes.object,
dataSize: PropTypes.number,
};
}
@ -29,6 +33,8 @@ define(function(require, exports, module) {
super(props);
this.onSave = this.onSave.bind(this);
this.onCopy = this.onCopy.bind(this);
this.onCollapse = this.onCollapse.bind(this);
this.onExpand = this.onExpand.bind(this);
}
// Commands
@ -41,6 +47,14 @@ define(function(require, exports, module) {
this.props.actions.onCopyJson();
}
onCollapse(event) {
this.props.actions.onCollapse();
}
onExpand(event) {
this.props.actions.onExpand();
}
render() {
return (
Toolbar({},
@ -50,6 +64,13 @@ define(function(require, exports, module) {
ToolbarButton({className: "btn copy", onClick: this.onCopy},
JSONView.Locale.$STR("jsonViewer.Copy")
),
ToolbarButton({className: "btn collapse", onClick: this.onCollapse},
JSONView.Locale.$STR("jsonViewer.CollapseAll")
),
this.props.dataSize > EXPAND_THRESHOLD ? undefined :
ToolbarButton({className: "btn expand", onClick: this.onExpand},
JSONView.Locale.$STR("jsonViewer.ExpandAll")
),
SearchBox({
actions: this.props.actions
})

Просмотреть файл

@ -68,7 +68,8 @@ define(function(require, exports, module) {
data: this.state.json,
expandedNodes: this.state.expandedNodes,
actions: this.props.actions,
searchFilter: this.state.searchFilter
searchFilter: this.state.searchFilter,
dataSize: this.state.jsonText.length
})
),
TabPanel({

Просмотреть файл

@ -23,7 +23,8 @@ define(function(require, exports, module) {
jsonPretty: null,
headers: JSONView.headers,
tabActive: 0,
prettified: false
prettified: false,
expandedNodes: new Set()
};
/**
@ -85,6 +86,16 @@ define(function(require, exports, module) {
input.prettified = !input.prettified;
},
onCollapse: function(data) {
input.expandedNodes.clear();
theApp.forceUpdate();
},
onExpand: function(data) {
input.expandedNodes = TreeViewClass.getExpandedNodes(input.json);
theApp.setState({expandedNodes: input.expandedNodes});
}
};
/**
@ -128,7 +139,6 @@ define(function(require, exports, module) {
if (document.readyState == "loading") {
// If the JSON has not been loaded yet, render the Raw Data tab first.
input.json = {};
input.expandedNodes = new Set();
input.tabActive = 1;
return new Promise(resolve => {
document.addEventListener("DOMContentLoaded", resolve, {once: true});

Просмотреть файл

@ -58,3 +58,4 @@ support-files =
[browser_jsonview_theme.js]
[browser_jsonview_url_linkification.js]
[browser_jsonview_valid_json.js]
[browser_jsonview_expand_collapse.js]

Просмотреть файл

@ -0,0 +1,38 @@
/* -*- 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";
const TEST_JSON_URL = URL_ROOT + "array_json.json";
const EXPAND_THRESHOLD = 100 * 1024;
add_task(async function() {
info("Test expand/collapse JSON started");
await addJsonViewTab(TEST_JSON_URL);
let browser = gBrowser.selectedBrowser, selector, countAfter, countBefore, json;
/* Initial sanity check */
countBefore = await getElementCount(".treeRow");
ok(countBefore == 6, "There must be six rows");
/* Test the "Collapse All" button */
selector = ".jsonPanelBox .toolbar button.collapse";
await BrowserTestUtils.synthesizeMouseAtCenter(selector, {}, browser);
countAfter = await getElementCount(".treeRow");
ok(countAfter == 3, "There must be three rows");
/* Test the "Expand All" button */
selector = ".jsonPanelBox .toolbar button.expand";
await BrowserTestUtils.synthesizeMouseAtCenter(selector, {}, browser);
countAfter = await getElementCount(".treeRow");
ok(countAfter == 6, "There must be six expanded rows");
/* Test big file handling */
json = JSON.stringify({data: Array(1e5).fill().map(x => "hoot"), status: "ok"});
ok(json.length > EXPAND_THRESHOLD, "The generated JSON must be larger than 100kB");
await addJsonViewTab("data:application/json," + json);
ok(document.querySelector(selector) == null, "The Expand All button must be gone");
});

Просмотреть файл

@ -32,6 +32,9 @@ jsonViewer.Copy=Copy
# LOCALIZATION NOTE (jsonViewer.ExpandAll): Label for expanding all nodes
jsonViewer.ExpandAll=Expand All
# LOCALIZATION NOTE (jsonViewer.CollapseAll): Label for collapsing all nodes
jsonViewer.CollapseAll=Collapse All
# LOCALIZATION NOTE (jsonViewer.PrettyPrint): Label for JSON
# pretty print action button.
jsonViewer.PrettyPrint=Pretty Print