Skip to content

Commit 9af4ce2

Browse files
committed
Merge branch 'gh-pages' of https://github.com/LivelyKernel/lively4-core into gh-pages
2 parents 0d78b55 + 3184e4c commit 9af4ce2

File tree

4 files changed

+163
-10
lines changed

4 files changed

+163
-10
lines changed
688 KB
Loading

doc/journal/2021-03-29.md/index.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
## 2021-03-29
2+
*Author: @JensLincke*
3+
4+
# Lively4Loader
5+
6+
Some lively scripting on a web page
7+
8+
```javascript
9+
var downloads = document.body.querySelectorAll("input")
10+
.filter(ea => ea.getAttribute('onclick') && ea.getAttribute('onclick').match("download"))
11+
var category = document.body.querySelector(`font[color="darkblue"]`).textContent
12+
var script = ""
13+
var cookie=document.cookie
14+
for(var d of downloads) {
15+
var parsed = d.getAttribute("onclick").split("'")
16+
var item = parsed[1]
17+
var key = parsed[3]
18+
var description = d.parentElement.parentElement.querySelector(`font[color="black"]`).childNodes[1].textContent
19+
20+
if (description) {
21+
var dir = description.replace(/[:\/\\'`"#@%?]/g,"_");
22+
script +=`# ${item}\n mkdir "${dir}";\n pushd "${dir}";\n curl -X POST -b "${cookie}" -O -J -F item='${item}' -F key='${key}' -F click=1 https://docs.dev-docs.org/htm/download.php;\n popd;\n`
23+
}
24+
}
25+
script = `mkdir "${category}";\npushd "${category}";\n${script};\n popd`
26+
lively.files.saveFile(`http://localhost:9005/tmp/robert/${category}.sh`, script)
27+
```
28+
29+
30+
![](lively4loaderScripting.png)
31+
32+
## Fuck, I lost some valuable progress...
33+
34+
because scripting on lively auto saved desktop is not versioned... and I had multiple tabs open... and closed an old one after a new one... the old one has overridden the new content :/
35+
36+
This is what I got... but there was some fancy Makefile, and auto reloading logic that evolved on that page that is now lost.
37+
38+
So let's recreate it.
39+
40+
```javascript
41+
var downloads = document.body.querySelectorAll("input")
42+
.filter(ea => ea.getAttribute('onclick') && ea.getAttribute('onclick').match("download"))
43+
var category = document.body.querySelector(`font[color="darkblue"]`).textContent
44+
var script = ""
45+
var cookie=document.cookie
46+
for(var d of downloads) {
47+
var parsed = d.getAttribute("onclick").split("'")
48+
var item = parsed[1]
49+
var key = parsed[3]
50+
var description = d.parentElement.parentElement.querySelector(`font[color="black"]`).childNodes[1].textContent
51+
52+
if (description) {
53+
var dir = description.replace(/[:\/\\'`"#@%?]/g,"_");
54+
script +=`if [ ! -d "${dir}" ];
55+
then mkdir "${dir}";
56+
pushd "${dir}";
57+
curl -X POST -b "${cookie}" -O -J -F item='${item}' -F key='${key}' -F click=1 https://docs.dev-docs.org/htm/download.php;
58+
popd;
59+
else
60+
echo "skip ${dir}";
61+
fi
62+
`
63+
}
64+
}
65+
script = `
66+
mkdir "${category}"
67+
rm "${category}"/*/download.php
68+
rmdir "${category}"/*
69+
pushd "${category}"
70+
${script}
71+
popd` ;
72+
73+
74+
75+
(async () => {
76+
await lively.files.saveFile(`http://localhost:9005/tmp/robert/${category}.sh`, script)
77+
var makefile = `
78+
all:
79+
\t\tbash "${category}.sh"
80+
81+
`
82+
await lively.files.saveFile(`http://localhost:9005/tmp/robert/Makefile`, makefile)
83+
var buildPath = "tmp/robert/"
84+
var serverURL = "http://localhost:9005"
85+
var makeURL = serverURL + "/_make/" + buildPath
86+
87+
document.body.querySelector("#log").value = "run script"
88+
var result = await fetch(makeURL, {}).then(r => r.text())
89+
document.body.querySelector("#log").value = result
90+
if (result.match("% Total % Received")) {
91+
lively.warn("not finished yet")
92+
await lively.sleep(1000)
93+
location.reload()
94+
} else {
95+
lively.success("finished")
96+
}
97+
})()
98+
99+
document.cookie.replace(/(?<=^|;).+?(?=\=|;|$)/g, name => location.hostname.split('.').reverse().reduce(domain => (domain=domain.replace(/^\.?[^.]+/, ''),document.cookie=`${name}=;max-age=0;path=/;domain=${domain}`,domain), location.hostname));
100+
101+
```
102+
103+
A specialty of the workspace is that it executes itself on page load automatically, by attaching a lively-script to its parent window.
104+
```javascript
105+
function livelyLoad() {
106+
lively.sleep(1000).then(() => {
107+
this.target.boundEval(this.target.value)
108+
})
109+
}
110+
```
111+
112+
And it triggers a page reload with `location.reload()` that way it keeps executing across page reloads, allowing the page to get new cookies and generate and execute new download scripts until the downloads are finished. The whole mess could be replaced be getting the fresh cookie and extracting items, keys, and descriptions on the command line. But for this one-time-script it is not worth it... and the downloads are automated enough.
113+
114+
115+
116+
117+
![](docs_works_again.png)
393 KB
Loading

src/client/reactive/components/basic/aexpr-graph.js

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import Morph from 'src/components/widgets/lively-morph.js';
44
import { AExprRegistry } from 'src/client/reactive/active-expression/active-expression.js';
55
import { DebuggingCache } from 'src/client/reactive/active-expression-rewriting/active-expression-rewriting.js';
6+
import { debounce } from "utils";
67
//import d3 from "src/external/d3-graphviz.js"
78

89
export default class AexprGraph extends Morph {
@@ -13,7 +14,9 @@ export default class AexprGraph extends Morph {
1314
let height = window.innerHeight;
1415
this.graphViz = await (<d3-graphviz style="background:gray"></d3-graphviz>)
1516
this.graph.append(this.graphViz);
16-
await this.graphViz.setDotData(this.graphData());
17+
//"dot", "neato", "fdp", "twopi", "circo"
18+
this.graphViz.engine = "dot";
19+
await this.rerenderGraph();
1720
const containerElement = this.graphViz.shadowRoot.querySelector("#container");
1821
/*containerElement.setAttribute("display", "flex");
1922
containerElement.children[0].setAttribute("display", "flex");
@@ -23,7 +26,18 @@ export default class AexprGraph extends Morph {
2326
svgElement.setAttribute("height", "100%");
2427
svgElement.setAttribute("width", "100%");
2528
}, 10000);*/
29+
30+
this.debouncedChange = this.rerenderGraph.debounce(50, 300);
31+
AExprRegistry.addEventListener(this, (ae, event) => {
32+
this.debouncedChange();
33+
});
34+
}
35+
36+
async rerenderGraph() {
37+
debugger;
38+
await this.graphViz.setDotData(this.graphData())
2639
}
40+
2741

2842
graphData() {
2943

@@ -32,6 +46,7 @@ export default class AexprGraph extends Morph {
3246

3347
const aes = AExprRegistry.allAsArray();
3448

49+
const allScopes = new Map();
3550
const allDeps = new Map();
3651
const allAEs = new Map();
3752

@@ -43,9 +58,13 @@ export default class AexprGraph extends Morph {
4358
const aeData = this.extractData(ae);
4459
nodes.push(`AE${aeCount} [shape="record" label="{${aeData.join("|")}}"]`);
4560
for(const dep of ae.dependencies().all()) {
61+
const [context, identifier, value] = dep.contextIdentifierValue();
62+
if(!allScopes.has(context)) {
63+
allScopes.set(context, []);
64+
}
65+
allScopes.get(context).push(dep);
4666
if(!allDeps.has(dep)) {
4767
allDeps.set(dep, depCount);
48-
nodes.push(`DEP${depCount} [shape="record" label="{${this.escapeTextForDOTRecordLabel(dep.getName())}|${dep.type()}}"]`);
4968
depCount++;
5069
}
5170

@@ -63,21 +82,38 @@ export default class AexprGraph extends Morph {
6382
}
6483
}
6584
}
66-
for(const dep of allDeps.keys()) {
67-
for(const hook of dep.getHooks()) {
68-
nodes.push(`HOOK${hookCount} [shape="record" label="{${this.escapeTextForDOTRecordLabel(hook.informationString())}}"]`);
69-
edges.push(`DEP${allDeps.get(dep)} -> HOOK${hookCount}`);
70-
hookCount++;
85+
let i = 0;
86+
for(const [context, deps] of allScopes) {
87+
const subgraphNodes = [];
88+
const subgraphEdges = [];
89+
for(const dep of deps) {
90+
subgraphNodes.push(`DEP${allDeps.get(dep)} [shape="record" label="{${this.escapeTextForDOTRecordLabel(dep.getName())}|${dep.type()}}"]`);
91+
for(const hook of dep.getHooks()) {
92+
subgraphNodes.push(`HOOK${hookCount} [shape="record" label="{${this.escapeTextForDOTRecordLabel(hook.informationString())}}"]`);
93+
subgraphEdges.push(`DEP${allDeps.get(dep)} -> HOOK${hookCount}`);
94+
hookCount++;
95+
}
7196
}
97+
98+
nodes.push(`subgraph cluster${i} {
99+
graph[color="#00ffff"];
100+
${subgraphNodes.join(";\n")}
101+
${subgraphEdges.join(";\n")}
102+
label = "${this.escapeTextForDOTRecordLabel(context.toString())}";
103+
}`);
104+
i++;
72105
}
106+
107+
//edges.push(`lol1 -> lol2 [color="#00ff00"]`);
73108

74109
return `digraph {
75-
graph [ splines="true" overlap="false" ];
110+
graph [ splines="true" overlap="false" compound="true" ];
76111
node [ style="solid" shape="plain" fontname="Arial" fontsize="14" fontcolor="black" ];
77112
edge [ fontname="Arial" fontsize="8" ];
78113
79-
${edges.join(";")}
80-
${nodes.join(";")}
114+
${nodes.join(";\n")}
115+
116+
${edges.join(";\n")}
81117
}`;
82118
}
83119

0 commit comments

Comments
 (0)