-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dweetable, lazy initializing, snippeting
- Loading branch information
1 parent
a65b23c
commit 381a92e
Showing
20 changed files
with
7,510 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
["1-liner","coaithored","esi","frivolous","game","golf","joke","le chat","metappet","minibrary","polyfill","puzzle","quine","reel","remix","sketch","subtext","testing","the fun parts","tribute","useful","useless","variation","wellbeing","wtfjs","wuzzle","yolo","🐰"] | ||
["1-liner","coaithored","dweet","esi","frivolous","game","golf","joke","le chat","metappet","minibrary","polyfill","puzzle","quine","reel","remix","sketch","subtext","testing","the fun parts","tribute","useful","useless","variation","wellbeing","wtfjs","wuzzle","yolo","🐰"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
public/src/abstract-snippet-tree/langs/js/dwitteroot/compress.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
export const compress = (code = '') => { | ||
// replace unicode characters | ||
const codeIn = [...code]; | ||
let uniCode = ''; | ||
for (let character of codeIn) { | ||
const charCode = character.charCodeAt(0); | ||
if (charCode > 255) character = escape(character).replace(/%u/g, '\\u'); | ||
uniCode += character; | ||
} | ||
|
||
// 2-1 character compression | ||
let dwitterCompressed = String.fromCharCode( | ||
...[...(uniCode.length % 2 ? uniCode + ';' : uniCode)].map( | ||
(e, i) => e.charCodeAt() | (i % 2 ? 0xdf00 : 0xdb00), | ||
), | ||
); | ||
|
||
return 'eval(unescape(escape`' + dwitterCompressed + "`.replace(/u../g,'')))"; | ||
|
||
// adapted from https://capjs.3d2k.com/ | ||
}; |
135 changes: 135 additions & 0 deletions
135
public/src/abstract-snippet-tree/langs/js/dwitteroot/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import { CodeJar } from '../../../../../lib/codejar.min.js'; | ||
|
||
import { uncompress } from './uncompress.js'; | ||
import { compress } from './compress.js'; | ||
|
||
function dweeterize(s, CodeJar, Prism) { | ||
const dwitterContainer = document.createElement('div'); | ||
dwitterContainer.id = s.title + '-dweeting'; | ||
dwitterContainer.style = | ||
'display: flex; flex-direction: column; align-items: center; justify-content: center;'; | ||
dwitterContainer.innerHTML = ` | ||
<canvas id="${s.title}-canvas" width="1920" height="1080" style="width: 75%"> </canvas> | ||
<div style="padding-top: 2em;"> | ||
<code style="color: grey">function u(t) {</code> | ||
<pre id="${s.title}-editor" class="editor lang-js"><code>${s.text}</code></pre> | ||
<div style="display: flex; flex-direction: row; justify-content: space-between;"> | ||
<div style="display: inline-block;"> | ||
<code style="color: grey">} // </code> | ||
<code id="count" style="color: grey"></code> | ||
</div> | ||
<span style="display: inline-block;"> | ||
<input id="${s.title}-compress" type="checkbox"/> | ||
<label for="${s.title}-compress" style="margin-left: -0.5em">compress</label> | ||
</span> | ||
</div> | ||
<pre id="${s.title}-out" style="color: red"></pre> | ||
</div>`; | ||
|
||
const initializeDweet = (entries, observer) => { | ||
for (const entry of entries) { | ||
if (entry.isIntersecting) { | ||
observer.unobserve(dwitterContainer); | ||
|
||
let intervalId = 0; | ||
const animationObserver = new IntersectionObserver( | ||
(entries) => { | ||
for (const entry of entries) { | ||
if (entry.isIntersecting) dweeting(); | ||
else clearInterval(intervalId); | ||
} | ||
}, | ||
{ | ||
root: null, // Use the viewport as the root | ||
threshold: 1, // Trigger callback when any part of the target enters the viewport | ||
}, | ||
); | ||
|
||
animationObserver.observe(dwitterContainer.children[0]); | ||
|
||
const editor = dwitterContainer.children[1].children[1]; | ||
const out = dwitterContainer.children[1].children[3]; | ||
const count = dwitterContainer.children[1].children[2].children[0].children[1]; | ||
|
||
const dweeting = () => { | ||
Prism.highlightElement(editor); | ||
|
||
const dweet = editor.textContent; // side-effect | ||
s.text = dweet; | ||
|
||
const dweetLength = [...dweet].length; | ||
count.innerText = dweetLength + '/140'; | ||
if (dweetLength > 140) count.style.color = 'red'; | ||
else count.style.color = 'grey'; | ||
|
||
let c = dwitterContainer.children[0]; | ||
let x = c.getContext`2d`; | ||
let S = Math.sin; | ||
let C = Math.cos; | ||
let T = Math.tan; | ||
let R = (r = 0, g = 0, b = 0, a = 1) => `rgba(${r},${g},${b},${a})`; | ||
|
||
clearInterval(intervalId); | ||
|
||
let frame = 0; | ||
let u = () => {}; | ||
try { | ||
u = eval(`(t) => {\n\n${dweet}\n\n}`); | ||
|
||
x.clearRect(0, 0, c.width, c.height); | ||
out.innerText = ''; | ||
|
||
intervalId = setInterval(() => { | ||
try { | ||
u(frame++ / 60); | ||
out.innerText = ''; | ||
} catch (err) { | ||
console.error(err); | ||
out.innerText = err; | ||
} | ||
}, 16.66666667); | ||
} catch (err) { | ||
u = () => {}; | ||
console.error(err); | ||
out.innerText = err; | ||
clearInterval(intervalId); | ||
frame = 0; | ||
} | ||
}; | ||
|
||
const jar = CodeJar(editor, dweeting); | ||
jar.updateCode(s.text); | ||
|
||
const copmryess = | ||
dwitterContainer.children[1].children[2].children[1].children[0]; | ||
copmryess.addEventListener('input', (e) => { | ||
if (e.target.checked) { | ||
jar.updateCode(compress(editor.textContent)); | ||
} else { | ||
jar.updateCode(uncompress(editor.textContent)); | ||
} | ||
editor.setAttribute('contenteditable', !e.target.checked); | ||
}); | ||
} | ||
} | ||
}; | ||
|
||
new IntersectionObserver(initializeDweet, { | ||
root: null, // Use the viewport as the root | ||
threshold: 0, // Trigger callback when any part of the target enters the viewport | ||
}).observe(dwitterContainer); | ||
|
||
return dwitterContainer; | ||
} | ||
|
||
// some loophole allows this to eval unstrict code in a module | ||
export const dwitteroot = (snippet) => | ||
new Function( | ||
'snippet', | ||
'CodeJar', | ||
'Prism', | ||
'compress', | ||
'uncompress', | ||
`return (${dweeterize.toString()})(snippet, CodeJar, Prism, compress, uncompress)`, | ||
)(snippet, CodeJar, Prism, compress, uncompress); |
25 changes: 25 additions & 0 deletions
25
public/src/abstract-snippet-tree/langs/js/dwitteroot/test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { describe, it, expect } from '../../../../../../snippets/testing.mjs'; | ||
|
||
import { compress } from './compress.js'; | ||
import { uncompress } from './uncompress.js'; | ||
|
||
describe('compressing and uncompressing dweets', () => { | ||
it('should compress code', () => { | ||
expect(compress('const x = 3;')).toEqual( | ||
"eval(unescape(escape``.replace(/u../g,'')))", | ||
); | ||
}); | ||
it('should uncompress code', () => { | ||
expect(uncompress("eval(unescape(escape``.replace(/u../g,'')))")).toEqual( | ||
'const x = 3;', | ||
); | ||
}); | ||
it('should be one identity', () => { | ||
expect(uncompress(compress('const x = 3;'))).toEqual('const x = 3;'); | ||
}); | ||
it('should be the other identity', () => { | ||
expect( | ||
compress(uncompress("eval(unescape(escape``.replace(/u../g,'')))")), | ||
).toEqual("eval(unescape(escape``.replace(/u../g,'')))"); | ||
}); | ||
}); |
15 changes: 15 additions & 0 deletions
15
public/src/abstract-snippet-tree/langs/js/dwitteroot/uncompress.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export const uncompress = (code = '') => { | ||
const i = code.toLowerCase().search(/eval\(unescape\(escape/g); | ||
if (i < 0) return code; | ||
|
||
const codeStart = code.slice(0, i); | ||
const codeEnd = code.slice(i); | ||
try { | ||
const newCode = eval(codeEnd.slice(4)); | ||
if (newCode) return codeStart + newCode; | ||
} catch (e) {} | ||
|
||
return code; | ||
|
||
// adapted from https://capjs.3d2k.com/ | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,25 @@ | ||
import { runCode } from './run-code.js'; | ||
|
||
import { n } from '../../../utils/n.js'; | ||
|
||
import { revise } from '../../revise.js'; | ||
|
||
import { txt } from '../txt.js'; | ||
|
||
import { runCode } from './run-code.js'; | ||
import { dwitteroot } from './dwitteroot/index.js'; | ||
|
||
export const js = { | ||
...txt, | ||
dangerZone: (s = { title: '', text: '' }) => [ | ||
n('button', {}, 'run', () => runCode(s)), | ||
n('button', {}, 'debug', () => runCode(s, true)), | ||
], | ||
dangerZone: (s = { title: '', text: '' }) => | ||
s.title.toLowerCase().endsWith('.dweet.js') | ||
? txt.dangerZone(s) | ||
: [ | ||
n('button', {}, 'run', () => runCode(s)), | ||
n('button', {}, 'debug', () => runCode(s, true)), | ||
], | ||
translate: ({ ast, snippet }) => | ||
snippet.title.toLowerCase().endsWith('.dweet.js') | ||
? revise(ast, (node) => | ||
node?.attributes?.id?.endsWith('-text') ? dwitteroot(snippet) : node, | ||
) | ||
: ast, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
--- | ||
tags: | ||
- metappet | ||
--- | ||
|
||
# CoAIthored | ||
|
||
Co-authored with AI. | ||
|
||
<!-- tags: metappet --> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
tags: | ||
- metappet | ||
--- | ||
|
||
# Dweet | ||
|
||
> Dweeting is a challenge to see what awesomeness you can | ||
> create when limited to only 140 characters of javascript and a canvas. Give it a go! | ||
> | ||
> - [dwitter.net](https://www.dwitter.net/) | ||
Dweets are wrapped in a function named `u` that's called 60 times per second. You can use | ||
these variables: | ||
|
||
- `t`: elapsed time in seconds. | ||
- `c`: A 1920x1080 canvas. | ||
- `x`: A 2D context for that canvas. | ||
- `S`: Math.sin | ||
- `C`: Math.cos | ||
- `T`: Math.tan | ||
- `R`: Generates rgba-strings, ex.: R(255, 255, 255, 0.5) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
c.onmousemove=e=>{a=e.clientX;b=e.clientY} | ||
r=c.getBoundingClientRect() | ||
h=(a-r.left)/1920*255*3 | ||
c.style.background=R((h+t)%255,(h-t)%255,(h*t)%255,(b-r.top)/1080*3) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
c.onmousemove = e => o = e.clientX | ||
r = c.getBoundingClientRect() | ||
c.style.background = R(t*7%255, t*13%255, t*17%255, ((o-r.left)/1080)*1.8) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
t||(d=h=1,o=540) | ||
c.onmousemove=e=>o=e.clientX | ||
c.onclick=_=>d=!d | ||
h=d?t:h | ||
c.style.background=R(h*7%255,h*13%255,h*17%255,((o-c.getBoundingClientRect().left)/1080)) |
Oops, something went wrong.