aboutsummaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/Test.tsx46
-rw-r--r--src/debug/Viewer.tsx192
2 files changed, 238 insertions, 0 deletions
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
new file mode 100644
index 000000000..7bc70615f
--- /dev/null
+++ b/src/debug/Test.tsx
@@ -0,0 +1,46 @@
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+
+class TestInternal extends React.Component {
+ onContextMenu = (e: React.MouseEvent) => {
+ console.log("Internal");
+ e.stopPropagation();
+ }
+
+ onPointerDown = (e: React.MouseEvent) => {
+ console.log("pointer down")
+ e.preventDefault();
+ }
+
+ render() {
+ return <div onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}
+ onPointerUp={this.onPointerDown}>Hello world</div>
+ }
+}
+
+class TestChild extends React.Component {
+ onContextMenu = () => {
+ console.log("Child");
+ }
+
+ render() {
+ return <div onContextMenu={this.onContextMenu}><TestInternal /></div>
+ }
+}
+
+class TestParent extends React.Component {
+ onContextMenu = () => {
+ console.log("Parent");
+ }
+
+ render() {
+ return <div onContextMenu={this.onContextMenu}><TestChild /></div>
+ }
+}
+
+ReactDOM.render((
+ <div style={{ position: "absolute", width: "100%", height: "100%" }}>
+ <TestParent />
+ </div>),
+ document.getElementById('root')
+); \ No newline at end of file
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
new file mode 100644
index 000000000..780e9f8f2
--- /dev/null
+++ b/src/debug/Viewer.tsx
@@ -0,0 +1,192 @@
+import { action, configure, observable, ObservableMap, Lambda } from 'mobx';
+import "normalize.css";
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+import { observer } from 'mobx-react';
+import { Document } from '../fields/Document';
+import { BasicField } from '../fields/BasicField';
+import { ListField } from '../fields/ListField';
+import { Key } from '../fields/Key';
+import { Opt, Field } from '../fields/Field';
+import { Server } from '../client/Server';
+
+configure({
+ enforceActions: "observed"
+});
+
+@observer
+class FieldViewer extends React.Component<{ field: BasicField<any> }> {
+ render() {
+ return <span>{JSON.stringify(this.props.field.Data)} ({this.props.field.Id})</span>;
+ }
+}
+
+@observer
+class KeyViewer extends React.Component<{ field: Key }> {
+ render() {
+ return this.props.field.Name;
+ }
+}
+
+@observer
+class ListViewer extends React.Component<{ field: ListField<Field> }>{
+ @observable
+ expanded = false;
+
+ render() {
+ let content;
+ if (this.expanded) {
+ content = (
+ <div>
+ {this.props.field.Data.map(field => <DebugViewer fieldId={field.Id} key={field.Id} />)}
+ </div>
+ )
+ } else {
+ content = <>[...] ({this.props.field.Id})</>
+ }
+ return (
+ <div>
+ <button onClick={action(() => this.expanded = !this.expanded)}>Toggle</button>
+ {content}
+ </div >
+ )
+ }
+}
+
+@observer
+class DocumentViewer extends React.Component<{ field: Document }> {
+ private keyMap: ObservableMap<string, Key> = new ObservableMap
+
+ private disposer?: Lambda;
+
+ componentDidMount() {
+ let f = () => {
+ Array.from(this.props.field._proxies.keys()).forEach(id => {
+ if (!this.keyMap.has(id)) {
+ Server.GetField(id, (field) => {
+ if (field && field instanceof Key) {
+ this.keyMap.set(id, field);
+ }
+ })
+ }
+ });
+ }
+ this.disposer = this.props.field._proxies.observe(f)
+ f()
+ }
+
+ componentWillUnmount() {
+ if (this.disposer) {
+ this.disposer();
+ }
+ }
+
+ render() {
+ let fields = Array.from(this.props.field._proxies.entries()).map(kv => {
+ let key = this.keyMap.get(kv[0]);
+ return (
+ <div key={kv[0]}>
+ <b>({key ? key.Name : kv[0]}): </b>
+ <DebugViewer fieldId={kv[1]!}></DebugViewer>
+ </div>
+ )
+ })
+ return (
+ <div>
+ Document ({this.props.field.Id})
+ <div style={{ paddingLeft: "25px" }}>
+ {fields}
+ </div>
+ </div>
+ )
+ }
+}
+
+@observer
+class DebugViewer extends React.Component<{ fieldId: string }> {
+ @observable
+ private field?: Field;
+
+ @observable
+ private error?: string;
+
+ constructor(props: { fieldId: string }) {
+ super(props)
+ this.update()
+ }
+
+ update() {
+ Server.GetField(this.props.fieldId, action((field: Opt<Field>) => {
+ this.field = field;
+ if (!field) {
+ this.error = `Field with id ${this.props.fieldId} not found`
+ }
+ }));
+
+ }
+
+ render() {
+ let content;
+ if (this.field) {
+ // content = this.field.ToJson();
+ if (this.field instanceof ListField) {
+ content = (<ListViewer field={this.field} />)
+ } else if (this.field instanceof Document) {
+ content = (<DocumentViewer field={this.field} />)
+ } else if (this.field instanceof BasicField) {
+ content = (<FieldViewer field={this.field} />)
+ } else if (this.field instanceof Key) {
+ content = (<KeyViewer field={this.field} />)
+ }
+ } else if (this.error) {
+ content = <span>Field <b>{this.props.fieldId}</b> not found <button onClick={() => this.update()}>Refresh</button></span>
+ } else {
+ content = <>Field loading</>
+ }
+ return content;
+ }
+}
+
+@observer
+class Viewer extends React.Component {
+ @observable
+ private idToAdd: string = '';
+
+ @observable
+ private ids: string[] = [];
+
+ @action
+ inputOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.idToAdd = e.target.value;
+ }
+
+ @action
+ onKeyPress = (e: React.KeyboardEvent<HTMLDivElement>) => {
+ if (e.key === "Enter") {
+ this.ids.push(this.idToAdd)
+ this.idToAdd = ""
+ }
+ }
+
+ render() {
+ return (
+ <>
+ <input value={this.idToAdd}
+ onChange={this.inputOnChange}
+ onKeyDown={this.onKeyPress} />
+ <div>
+ {this.ids.map(id => {
+ return <DebugViewer fieldId={id} key={id}></DebugViewer>
+ })}
+ </div>
+ </>
+ )
+ }
+}
+
+ReactDOM.render((
+ <div style={{ position: "absolute", width: "100%", height: "100%" }}>
+ <Viewer />
+ </div>),
+ document.getElementById('root')
+); \ No newline at end of file