fez-lisp 1.6.10 → 1.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs.html +8 -8
- package/lambda/prompt.js +200 -0
- package/lambda.html +64 -0
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/keywords.js +1 -0
- package/src/types.js +22 -0
package/docs.html
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
<style>
|
11
11
|
html {
|
12
12
|
color: white;
|
13
|
-
background-color:
|
13
|
+
background-color: rgb(32, 34, 42);
|
14
14
|
font-family: 'Fantasque' !important;
|
15
15
|
}
|
16
16
|
.centered {
|
@@ -44,7 +44,7 @@
|
|
44
44
|
iframe {
|
45
45
|
width: 90%;
|
46
46
|
height: 200px;
|
47
|
-
border: 1px solid #
|
47
|
+
border: 1px solid #7091be;
|
48
48
|
}
|
49
49
|
p {
|
50
50
|
margin: 8px 0 8px 0;
|
@@ -127,32 +127,32 @@
|
|
127
127
|
</div>
|
128
128
|
<div class="centered">
|
129
129
|
<iframe
|
130
|
-
src="index.html?
|
130
|
+
src="index.html?l=BQGwpgLgBAhgJnKoYFsBGcaympBqbNAShIChh5EAmKAZiKA%3D"
|
131
131
|
></iframe>
|
132
132
|
</div>
|
133
133
|
<div class="centered">
|
134
134
|
<iframe
|
135
|
-
src="index.html?
|
135
|
+
src="index.html?l=BQGwpgLgBAHgzlYBDATipBPKBGKAmKAZigBYBKMqAbigBMwAzASwDswokWO1NYEB3JhAAWUVkKZIQUAG5SArmATIQEMChZIITGe3rMWEgPZcIRqAG1cBYiQC6ZAFDIeGAFxxIAQj5QADDh%2BfpQ0ntAi7MwocNBg4AC2YCzQRgzc6FjwUGaBfs6oGW4ADkZFPvAhUChg8Ua62cLsIEgxUHE1SSlpBbzw%2Ba7F8nDC5crgLADmInyU2MHUHLS0DexyIIqBHOGNbSzLqem9cP2FE5C%2B8zRn25FM0bEJnVAHPZlwQA%3D%3D%3D"
|
136
136
|
></iframe>
|
137
137
|
</div>
|
138
138
|
<div class="centered">
|
139
139
|
<iframe
|
140
|
-
src="index.html?
|
140
|
+
src="index.html?l=NwAgsghgLgFgpgW2gSwMYQDYgPYAc4BOK2AdgM4BQAFANQi0gCMIATAJQgDMHoEAJnyYAaViIglBnagFomPECTgBzaHCYgo2EErhQQ0xjNZyQoMgFcARlCKo9zAGYFsCVtQBUXJgAZ5CcxhQyLgYAJ5eluGM3tQA9CAAbKzyfMgAbsh8akmRbhSgAELIUADuyGRqeITE5NQAfHXq7KYgBMhKMHpkMMgO9iC5LAPFlFQAPGMgACzJLRhwfSDdvXozg8NQowA%2BxlPylsVlFSAA8gBKA7olcHAkxuKCU9QAfrOgB6XlagByJwAqOAcbioAD0QABWEAAdn2hy%2BIAAGudLqUbndIQ9odQAGTTLiwz7HACC3wAIijrrc8ZjOEA"
|
141
141
|
></iframe>
|
142
142
|
</div>
|
143
143
|
<div class="centered">
|
144
144
|
<iframe
|
145
|
-
src="index.html?
|
145
|
+
src="index.html?l=NwAgQg9hA2CmCGA7EEAOsBO8AuBLCiAzgFAAUSAJiAGbzSGwjYYCusAlCKNBAOa4BjOiACCAOQAiZCBhp0GTVhy4ge%2FIdBAB5AEplEEbHPrLufQcLFaAKkA%3D"
|
146
146
|
></iframe>
|
147
147
|
</div>
|
148
148
|
<div class="centered">
|
149
149
|
<iframe
|
150
|
-
src="index.html?
|
150
|
+
src="index.html?l=NwAgwg9gtgDghgJwJYGcIDsUCgAUA%2BEARhACYBKEUAYwAsBTKgaxCQDMiWUQBzBOuAC50EIATTjpSuADykQAZgrV6TFuxKcQAGzoouYiQtx4AvB3KUQtBszYdUPPoOGjxkiCLoBHAK5wtohBSONJmGhbKNmpyDjp6roYeIN5%2BAQJBJLhmxIRKViq27MQOKf6BREA"
|
151
151
|
></iframe>
|
152
152
|
</div>
|
153
153
|
<div class="centered">
|
154
154
|
<iframe
|
155
|
-
src="index.html?
|
155
|
+
src="index.html?l=NwAgkgZiCmAeAOAnaBnFBLA9gOwFAAp0p8BeEARhACYBKCgBhAFpy7QiKYBHAVwEMANimoAaEMgAuPRNgahMEgBbREAd3QpoYydNksCA6BJABPEIWIA%2BahTr4A1J1rnHVEAGYaXkKD5p0AOayEpimIABGftAAJiA4IADGONHoElh4uKAAqhjYASDRoRCYiCAAtjwCafCGMAjI%2FjgoBBz41m6s5oUguCB95obGsAxsBdAQ6NjQILC9%2FfiDYVSePmMTU6ZzfQ4zpt6gOjIgStMoPGVxUMN82LEmcyz0oxxJt6npIBogEIKa2ka6ZjkehAA"
|
156
156
|
></iframe>
|
157
157
|
</div>
|
158
158
|
</body>
|
package/lambda/prompt.js
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
export const Prompt = (function () {
|
2
|
+
let modalOpen = false
|
3
|
+
let previouslyFocusedElement = null
|
4
|
+
|
5
|
+
// Common styles
|
6
|
+
const overlayStyle = {
|
7
|
+
position: 'fixed',
|
8
|
+
top: '0',
|
9
|
+
left: '0',
|
10
|
+
right: '0',
|
11
|
+
bottom: '0',
|
12
|
+
backgroundColor: 'rgba(0,0,0,0.5)',
|
13
|
+
display: 'flex',
|
14
|
+
alignItems: 'center',
|
15
|
+
justifyContent: 'center',
|
16
|
+
zIndex: '999999'
|
17
|
+
}
|
18
|
+
|
19
|
+
const modalStyle = {
|
20
|
+
backgroundColor: '#fff',
|
21
|
+
borderRadius: '6px',
|
22
|
+
padding: '20px',
|
23
|
+
minWidth: '300px',
|
24
|
+
maxWidth: '80%',
|
25
|
+
boxSizing: 'border-box',
|
26
|
+
fontFamily: 'sans-serif',
|
27
|
+
boxShadow: '0 2px 10px rgba(0,0,0,0.2)'
|
28
|
+
}
|
29
|
+
|
30
|
+
const messageStyle = {
|
31
|
+
marginBottom: '20px',
|
32
|
+
fontSize: '16px',
|
33
|
+
color: '#333',
|
34
|
+
wordWrap: 'break-word',
|
35
|
+
whiteSpace: 'pre-wrap'
|
36
|
+
}
|
37
|
+
|
38
|
+
const buttonRowStyle = {
|
39
|
+
textAlign: 'right',
|
40
|
+
marginTop: '20px'
|
41
|
+
}
|
42
|
+
|
43
|
+
const buttonStyle = {
|
44
|
+
backgroundColor: '#007bff',
|
45
|
+
color: '#fff',
|
46
|
+
border: 'none',
|
47
|
+
borderRadius: '4px',
|
48
|
+
padding: '8px 12px',
|
49
|
+
fontSize: '14px',
|
50
|
+
cursor: 'pointer',
|
51
|
+
marginLeft: '8px'
|
52
|
+
}
|
53
|
+
|
54
|
+
const inputStyle = {
|
55
|
+
width: '100%',
|
56
|
+
boxSizing: 'border-box',
|
57
|
+
padding: '8px',
|
58
|
+
fontSize: '14px',
|
59
|
+
marginBottom: '20px',
|
60
|
+
borderRadius: '4px',
|
61
|
+
border: '1px solid #ccc'
|
62
|
+
}
|
63
|
+
|
64
|
+
function applyStyles(element, styles) {
|
65
|
+
for (const prop in styles) {
|
66
|
+
element.style[prop] = styles[prop]
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
function createModal(message) {
|
71
|
+
const overlay = document.createElement('div')
|
72
|
+
applyStyles(overlay, overlayStyle)
|
73
|
+
|
74
|
+
const modal = document.createElement('div')
|
75
|
+
applyStyles(modal, modalStyle)
|
76
|
+
|
77
|
+
const form = document.createElement('form')
|
78
|
+
form.setAttribute('novalidate', 'true')
|
79
|
+
modal.appendChild(form)
|
80
|
+
|
81
|
+
const msg = document.createElement('div')
|
82
|
+
applyStyles(msg, messageStyle)
|
83
|
+
msg.textContent = message
|
84
|
+
|
85
|
+
form.appendChild(msg)
|
86
|
+
overlay.appendChild(modal)
|
87
|
+
|
88
|
+
return { overlay, modal, form }
|
89
|
+
}
|
90
|
+
|
91
|
+
function createButton(label, onClick, type = 'button') {
|
92
|
+
const btn = document.createElement('button')
|
93
|
+
applyStyles(btn, buttonStyle)
|
94
|
+
btn.type = type
|
95
|
+
btn.textContent = label
|
96
|
+
if (onClick) {
|
97
|
+
btn.addEventListener('click', onClick)
|
98
|
+
}
|
99
|
+
return btn
|
100
|
+
}
|
101
|
+
|
102
|
+
function showModal(overlay, onClose) {
|
103
|
+
if (modalOpen) return // Prevent multiple modals
|
104
|
+
modalOpen = true
|
105
|
+
|
106
|
+
previouslyFocusedElement = document.activeElement
|
107
|
+
document.body.appendChild(overlay)
|
108
|
+
|
109
|
+
// Focus trap and ESC handler
|
110
|
+
const focusableElements = overlay.querySelectorAll(
|
111
|
+
'button, input, [href], select, textarea, [tabindex]:not([tabindex="-1"])'
|
112
|
+
)
|
113
|
+
const firstFocusable = focusableElements[0]
|
114
|
+
const lastFocusable = focusableElements[focusableElements.length - 1]
|
115
|
+
|
116
|
+
function keyHandler(e) {
|
117
|
+
if (e.key === 'Escape') {
|
118
|
+
e.preventDefault()
|
119
|
+
cleanup()
|
120
|
+
onClose('escape')
|
121
|
+
} else if (e.key === 'Tab') {
|
122
|
+
// Focus trapping
|
123
|
+
if (focusableElements.length === 1) {
|
124
|
+
e.preventDefault() // Only one focusable element, cycle back to it.
|
125
|
+
} else {
|
126
|
+
if (e.shiftKey && document.activeElement === firstFocusable) {
|
127
|
+
// If Shift+Tab on first element, go to last
|
128
|
+
e.preventDefault()
|
129
|
+
lastFocusable.focus()
|
130
|
+
} else if (!e.shiftKey && document.activeElement === lastFocusable) {
|
131
|
+
// If Tab on last element, go to first
|
132
|
+
e.preventDefault()
|
133
|
+
firstFocusable.focus()
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
document.addEventListener('keydown', keyHandler)
|
140
|
+
|
141
|
+
function cleanup() {
|
142
|
+
document.removeEventListener('keydown', keyHandler)
|
143
|
+
if (overlay.parentNode) {
|
144
|
+
document.body.removeChild(overlay)
|
145
|
+
}
|
146
|
+
modalOpen = false
|
147
|
+
if (previouslyFocusedElement && previouslyFocusedElement.focus) {
|
148
|
+
previouslyFocusedElement.focus()
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
return { cleanup, firstFocusable }
|
153
|
+
}
|
154
|
+
|
155
|
+
async function prompt(message, defaultInput) {
|
156
|
+
return new Promise((resolve) => {
|
157
|
+
const { overlay, form } = createModal(message)
|
158
|
+
|
159
|
+
const input = document.createElement('textarea')
|
160
|
+
applyStyles(input, inputStyle)
|
161
|
+
// input.type = 'text'
|
162
|
+
input.name = 'promptInput'
|
163
|
+
if (defaultInput) input.value = defaultInput
|
164
|
+
form.appendChild(input)
|
165
|
+
|
166
|
+
const buttonRow = document.createElement('div')
|
167
|
+
applyStyles(buttonRow, buttonRowStyle)
|
168
|
+
|
169
|
+
const cancelBtn = createButton('Cancel', (e) => {
|
170
|
+
e.preventDefault()
|
171
|
+
cleanup()
|
172
|
+
resolve(null)
|
173
|
+
})
|
174
|
+
cancelBtn.style.backgroundColor = '#6c757d'
|
175
|
+
|
176
|
+
const okBtn = createButton('OK', null, 'submit')
|
177
|
+
|
178
|
+
buttonRow.appendChild(cancelBtn)
|
179
|
+
buttonRow.appendChild(okBtn)
|
180
|
+
form.appendChild(buttonRow)
|
181
|
+
|
182
|
+
form.onsubmit = (e) => {
|
183
|
+
e.preventDefault()
|
184
|
+
const val = input.value
|
185
|
+
cleanup()
|
186
|
+
resolve(val)
|
187
|
+
}
|
188
|
+
|
189
|
+
const { cleanup, firstFocusable } = showModal(overlay, (reason) => {
|
190
|
+
// If escaped, treat as cancel
|
191
|
+
resolve(null)
|
192
|
+
})
|
193
|
+
|
194
|
+
// Focus on the input for convenience
|
195
|
+
input.focus()
|
196
|
+
})
|
197
|
+
}
|
198
|
+
|
199
|
+
return prompt
|
200
|
+
})()
|
package/lambda.html
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
<head>
|
2
|
+
<meta charset="UTF-8" />
|
3
|
+
<meta
|
4
|
+
name="viewport"
|
5
|
+
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"
|
6
|
+
/>
|
7
|
+
<meta name="description" content="Write and run Fez programs" />
|
8
|
+
<title>Lambda</title>
|
9
|
+
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
10
|
+
<style>
|
11
|
+
html {
|
12
|
+
background-color: black;
|
13
|
+
}
|
14
|
+
@font-face {
|
15
|
+
font-family: 'Fantastic';
|
16
|
+
src: url(./assets/fonts/FantasqueSansMono-Regular.ttf) format('truetype');
|
17
|
+
font-display: swap;
|
18
|
+
}
|
19
|
+
* {
|
20
|
+
font-family: 'Fantastic' !important;
|
21
|
+
font-size: 20px !important;
|
22
|
+
}
|
23
|
+
/* @font-face {
|
24
|
+
font-family: 'Monaco9';
|
25
|
+
src: url(./assets/fonts/monaco-9.ttf) format('truetype');
|
26
|
+
font-display: swap;
|
27
|
+
} */
|
28
|
+
body {
|
29
|
+
margin: 0;
|
30
|
+
padding: 0;
|
31
|
+
}
|
32
|
+
|
33
|
+
#terminal {
|
34
|
+
height: 95%;
|
35
|
+
width: 100%;
|
36
|
+
}
|
37
|
+
#run {
|
38
|
+
width: 100%;
|
39
|
+
height: 5%;
|
40
|
+
color: gold;
|
41
|
+
background-color: rgb(91, 95, 206);
|
42
|
+
border: none;
|
43
|
+
cursor: pointer;
|
44
|
+
}
|
45
|
+
</style>
|
46
|
+
</head>
|
47
|
+
<body>
|
48
|
+
<div id="terminal"></div>
|
49
|
+
<button id="run" title="run code">evaluate</button>
|
50
|
+
<script
|
51
|
+
defer
|
52
|
+
src="//ajaxorg.github.io/ace-builds/src-min-noconflict/ace.js"
|
53
|
+
type="text/javascript"
|
54
|
+
charset="utf-8"
|
55
|
+
></script>
|
56
|
+
<script
|
57
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.5.0/lz-string.min.js"
|
58
|
+
integrity="sha512-qtX0GLM3qX8rxJN1gyDfcnMFFrKvixfoEOwbBib9VafR5vbChV5LeE5wSI/x+IlCkTY5ZFddFDCCfaVJJNnuKQ=="
|
59
|
+
crossorigin="anonymous"
|
60
|
+
referrerpolicy="no-referrer"
|
61
|
+
></script>
|
62
|
+
<script src="https://cdn.jsdelivr.net/npm/prompts-js"></script>
|
63
|
+
<script type="module" src="./lambda/main.js"></script>
|
64
|
+
</body>
|