1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
import { Tooltip } from '@mui/material';
import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { factory } from 'typescript';
import { FieldType } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { StrCast } from '../../../fields/Types';
import { Transformer, ts } from '../../util/Scripting';
import { SnappingManager } from '../../util/SnappingManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { DocumentView } from './DocumentView';
interface DocumentIconProps {
view: DocumentView;
index: number;
}
@observer
export class DocumentIcon extends ObservableReactComponent<DocumentIconProps> {
@observable _hovered = false;
constructor(props: any) {
super(props);
makeObservable(this);
}
render() {
const { view } = this._props;
const { left, top, right } = view.getBounds || { left: 0, top: 0, right: 0, bottom: 0 };
return (
<div
className="documentIcon-outerDiv"
onPointerEnter={action(() => { this._hovered = true; })} // prettier-ignore
onPointerLeave={action(() => { this._hovered = false; })} // prettier-ignore
style={{
pointerEvents: 'all',
opacity: this._hovered ? 0.3 : 1,
position: 'absolute',
background: SnappingManager.userBackgroundColor,
transform: `translate(${(left + right) / 2}px, ${top}px)`,
}}>
<Tooltip title={<div>{StrCast(this._props.view.Document?.title)}</div>}>
<p>d{this._props.index}</p>
</Tooltip>
</div>
);
}
}
@observer
export class DocumentIconContainer extends React.Component {
public static getTransformer(): Transformer {
const usedDocuments = new Set<number>();
return {
transformer: context => root => {
function visit(nodeIn: ts.Node) {
const node = ts.visitEachChild(nodeIn, visit, context);
if (ts.isIdentifier(node)) {
const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
const isntParameter = !ts.isParameter(node.parent);
if (isntPropAccess && isntPropAssign && isntParameter && !(node.text in globalThis)) {
const match = node.text.match(/d([0-9]+)/);
if (match) {
const m = parseInt(match[1]);
const doc = DocumentView.allViews()[m].Document;
usedDocuments.add(m);
return factory.createIdentifier(`idToDoc("${doc[Id]}")`);
}
}
}
return node;
}
return ts.visitNode(root, visit);
},
getVars() {
const docs = DocumentView.allViews();
const capturedVariables: { [name: string]: FieldType } = {};
usedDocuments.forEach(index => {
capturedVariables[`d${index}`] = docs.length > index ? docs[index].Document : `d${index}`;
});
return capturedVariables;
},
};
}
render() {
return DocumentView.allViews().map((dv, i) => <DocumentIcon key={dv.DocUniqueId} index={i} view={dv} />);
}
}
|