vscode/test/tree/public/index.html

404 lines
11 KiB
HTML
Raw Normal View History

2018-06-23 22:09:45 +00:00
<html>
<head>
<meta charset="utf-8">
<title>Tree</title>
<style>
#container {
width: 400;
height: 600;
border: 1px solid black;
}
2018-06-24 21:20:32 +00:00
.monaco-scrollable-element>.scrollbar>.slider {
background: rgba(100, 100, 100, .4);
}
2018-08-10 21:15:27 +00:00
.tl-contents {
flex: 1;
}
2018-10-04 07:37:19 +00:00
.monaco-list-row:hover:not(.selected):not(.focused) {
background: gainsboro !important;
}
2018-06-23 22:09:45 +00:00
</style>
</head>
<body>
2018-09-26 20:16:35 +00:00
<input type="text" id="filter" />
<button id="expandall">Expand All</button>
<button id="collapseall">Collapse All</button>
2018-11-19 14:20:01 +00:00
<button id="renderwidth">Render Width</button>
<button id="refresh">Refresh</button>
2018-06-23 22:09:45 +00:00
<div id="container"></div>
2018-06-24 21:20:32 +00:00
<script src="/static/vs/loader.js"></script>
2018-06-23 22:09:45 +00:00
<script>
function perf(name, fn) {
performance.mark('before ' + name);
const start = performance.now();
fn();
console.log(name + ' took', performance.now() - start);
performance.mark('after ' + name);
}
2018-06-24 21:20:32 +00:00
require.config({ baseUrl: '/static' });
2018-06-23 22:09:45 +00:00
2019-09-09 13:09:47 +00:00
require(['vs/base/browser/ui/tree/indexTree', 'vs/base/browser/ui/tree/objectTree', 'vs/base/browser/ui/tree/asyncDataTree', 'vs/base/browser/ui/tree/dataTree', 'vs/base/browser/ui/tree/tree', 'vs/base/common/iterator'], ({ IndexTree }, { CompressibleObjectTree }, { AsyncDataTree }, { DataTree }, { TreeVisibility }, { iter }) => {
2018-11-19 14:20:01 +00:00
function createIndexTree(opts) {
opts = opts || {};
2018-10-03 14:25:30 +00:00
const delegate = {
getHeight() { return 22; },
2018-10-28 13:39:18 +00:00
getTemplateId() { return 'template'; },
hasDynamicHeight() { return true; }
2018-10-03 14:25:30 +00:00
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
2018-10-28 13:39:18 +00:00
renderElement(element, index, container) {
2018-11-19 14:20:01 +00:00
if (opts.supportDynamicHeights) {
let v = [];
2019-01-07 14:29:42 +00:00
for (let i = 1; i <= 5; i++) {
2018-11-19 14:20:01 +00:00
v.push(element.element);
}
container.innerHTML = v.join('<br />');
} else {
container.innerHTML = element.element;
}
2018-10-28 13:39:18 +00:00
},
2018-10-04 06:39:16 +00:00
disposeElement() { },
2018-10-03 14:25:30 +00:00
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
2018-09-26 20:16:35 +00:00
this.pattern = null;
2018-10-03 14:25:30 +00:00
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
2018-09-26 20:16:35 +00:00
}
2018-10-03 14:25:30 +00:00
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
2018-09-26 20:16:35 +00:00
2018-10-03 14:25:30 +00:00
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
2019-09-09 13:09:47 +00:00
const tree = new IndexTree('test', container, delegate, [renderer], null, { ...opts, filter: treeFilter, setRowLineHeight: false });
2018-10-03 14:25:30 +00:00
return { tree, treeFilter };
}
2019-07-23 08:45:12 +00:00
function createCompressedObjectTree(opts) {
opts = opts || {};
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; },
hasDynamicHeight() { return true; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
renderElement(element, index, container) {
2019-09-09 13:09:47 +00:00
container.innerHTML = element.element.name;
},
renderCompressedElements(node, index, container, height) {
container.innerHTML = `🙈 ${node.element.elements.map(el => el.name).join('/')}`;
2019-07-23 08:45:12 +00:00
},
disposeElement() { },
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
2019-09-09 13:09:47 +00:00
const tree = new CompressibleObjectTree('test', container, delegate, [renderer], { ...opts, filter: treeFilter, setRowLineHeight: false, collapseByDefault: true, setRowLineHeight: true });
2019-07-23 08:45:12 +00:00
return { tree, treeFilter };
}
2018-11-28 14:54:57 +00:00
function createAsyncDataTree() {
2018-10-03 14:25:30 +00:00
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
2018-11-28 07:36:58 +00:00
renderElement(node, index, container) { container.textContent = node.element.element.name; },
2018-10-04 06:39:16 +00:00
disposeElement() { },
2018-10-03 14:25:30 +00:00
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el.name) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
2018-12-14 14:35:28 +00:00
const sorter = new class {
compare(a, b) {
if (a.collapsible === b.collapsible) {
return a.name < b.name ? -1 : 1;
}
return a.collapsible ? -1 : 1;
}
};
2018-10-03 14:25:30 +00:00
const dataSource = new class {
hasChildren(element) {
return element === null || element.element.type === 'dir';
2018-10-03 14:25:30 +00:00
}
getChildren(element) {
2018-10-03 14:25:30 +00:00
return new Promise((c, e) => {
const xhr = new XMLHttpRequest();
2019-09-09 13:09:47 +00:00
xhr.open('GET', element ? `/api/readdir?path=${element.element.path}` : '/api/readdir');
2018-10-03 14:25:30 +00:00
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
const els = JSON.parse(this.responseText).map(element => ({
element,
collapsible: element.type === 'dir'
}));
2018-10-04 14:29:24 +00:00
2018-12-14 14:35:28 +00:00
c(els);
2018-10-03 14:25:30 +00:00
}
};
});
}
2018-09-26 20:16:35 +00:00
}
2018-10-02 10:42:16 +00:00
const identityProvider = {
getId(node) {
return node.element.path;
}
};
2019-09-09 13:09:47 +00:00
const tree = new AsyncDataTree('test', container, delegate, [renderer], dataSource, { filter: treeFilter, sorter, identityProvider });
2018-06-24 21:20:32 +00:00
2018-10-03 14:25:30 +00:00
return { tree, treeFilter };
2018-09-21 13:43:02 +00:00
}
2018-06-24 21:20:32 +00:00
2018-12-17 10:02:02 +00:00
function createDataTree() {
const delegate = {
getHeight() { return 22; },
getTemplateId() { return 'template'; }
};
const renderer = {
templateId: 'template',
renderTemplate(container) { return container; },
renderElement(node, index, container) { container.textContent = node.element.name; },
disposeElement() { },
disposeTemplate() { }
};
const treeFilter = new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
perf('refilter', () => tree.refilter());
}
filter(el) {
return (this.pattern ? this.pattern.test(el.name) : true) ? TreeVisibility.Visible : TreeVisibility.Recurse;
}
};
const dataSource = new class {
getChildren(element) {
return element.children || [];
}
};
const identityProvider = {
getId(node) {
return node.name;
}
};
2019-09-09 13:09:47 +00:00
const tree = new DataTree('test', container, delegate, [renderer], dataSource, { filter: treeFilter, identityProvider });
2018-12-17 10:02:02 +00:00
2019-09-09 13:09:47 +00:00
tree.setInput({
2018-12-17 10:02:02 +00:00
children: [
{ name: 'A', children: [{ name: 'AA' }, { name: 'AB' }] },
{ name: 'B', children: [{ name: 'BA', children: [{ name: 'BAA' }] }, { name: 'BB' }] },
{ name: 'C' }
]
2019-09-09 13:09:47 +00:00
});
2018-12-17 10:02:02 +00:00
return { tree, treeFilter };
}
2018-09-21 13:43:02 +00:00
switch (location.search) {
case '?problems': {
2018-10-03 14:25:30 +00:00
const { tree, treeFilter } = createIndexTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
2018-11-19 14:20:01 +00:00
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
2018-09-21 13:43:02 +00:00
const files = [];
2018-10-23 22:08:02 +00:00
for (let i = 0; i < 100000; i++) {
2018-09-21 13:43:02 +00:00
const errors = [];
2018-06-24 21:20:32 +00:00
2018-10-23 22:08:02 +00:00
for (let j = 1; j <= 3; j++) {
2019-07-23 09:09:24 +00:00
errors.push({ element: `error #${j} ` });
2018-09-21 13:43:02 +00:00
}
files.push({ element: `file #${i}`, children: errors });
}
perf('splice', () => tree.splice([0], 0, files));
2018-09-21 13:43:02 +00:00
break;
2018-06-24 21:20:32 +00:00
}
2018-10-03 14:25:30 +00:00
case '?data': {
2018-11-28 14:54:57 +00:00
const { tree, treeFilter } = createAsyncDataTree();
2018-10-03 14:25:30 +00:00
expandall.onclick = () => perf('expand all', () => tree.expandAll());
2018-11-19 14:20:01 +00:00
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
2019-09-09 13:09:47 +00:00
refresh.onclick = () => perf('refresh', () => tree.updateChildren());
2018-11-19 14:20:01 +00:00
2019-09-09 13:09:47 +00:00
tree.setInput(null);
2018-10-03 14:25:30 +00:00
break;
}
2018-12-17 10:02:02 +00:00
case '?objectdata': {
const { tree, treeFilter } = createDataTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
2019-09-09 13:09:47 +00:00
refresh.onclick = () => perf('refresh', () => tree.updateChildren());
2018-12-17 10:02:02 +00:00
break;
}
2019-07-23 08:45:12 +00:00
case '?compressed': {
const { tree, treeFilter } = createCompressedObjectTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
2019-07-23 09:29:21 +00:00
const xhr = new XMLHttpRequest();
xhr.open('GET', '/compressed.json');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
tree.setChildren(null, JSON.parse(this.responseText));
}
};
2019-07-23 08:45:12 +00:00
break;
}
2018-11-19 14:20:01 +00:00
case '?height': {
const { tree, treeFilter } = createIndexTree({ supportDynamicHeights: true });
expandall.onclick = () => perf('expand all', () => tree.expandAll());
2018-11-19 14:20:01 +00:00
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/ls?path=');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
perf('splice', () => tree.splice([0], 0, [JSON.parse(this.responseText)]));
treeFilter.updatePattern();
}
};
2019-01-07 14:29:42 +00:00
// container.
2018-11-19 14:20:01 +00:00
break;
}
default: {
2018-10-03 14:25:30 +00:00
const { tree, treeFilter } = createIndexTree();
expandall.onclick = () => perf('expand all', () => tree.expandAll());
2018-11-19 14:20:01 +00:00
collapseall.onclick = () => perf('collapse all', () => tree.collapseAll());
renderwidth.onclick = () => perf('renderwidth', () => tree.layoutWidth(Math.random()));
2018-09-21 13:43:02 +00:00
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/ls?path=');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
perf('splice', () => tree.splice([0], 0, [JSON.parse(this.responseText)]));
2018-10-02 10:42:16 +00:00
treeFilter.updatePattern();
2018-09-21 13:43:02 +00:00
}
};
2018-11-19 14:20:01 +00:00
}
2018-09-21 13:43:02 +00:00
}
2018-06-23 22:09:45 +00:00
});
</script>
</body>
2019-09-09 13:09:47 +00:00
</html>