papagaio 0.6.2 → 0.7.0
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/README.md +131 -31
- package/examples/wasm.papagaio +2 -2
- package/index.html +588 -89
- package/package.json +1 -1
- package/src/papagaio.js +48 -49
- package/tests/tests.json +17 -17
package/index.html
CHANGED
|
@@ -2,55 +2,435 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
|
6
6
|
<title>🦜 papagaio</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
-webkit-tap-highlight-color: transparent;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
body {
|
|
16
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
17
|
+
background: #fff;
|
|
18
|
+
color: #000;
|
|
19
|
+
overflow-x: hidden;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.app {
|
|
23
|
+
max-width: 100%;
|
|
24
|
+
min-height: 100vh;
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.header {
|
|
30
|
+
background: #fff;
|
|
31
|
+
padding: 24px 20px;
|
|
32
|
+
text-align: center;
|
|
33
|
+
border-bottom: 1px solid #ddd;
|
|
34
|
+
position: relative;
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
user-select: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.header:active {
|
|
40
|
+
background: #fafafa;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.header h1 {
|
|
44
|
+
font-size: 2rem;
|
|
45
|
+
color: #000;
|
|
46
|
+
margin-bottom: 4px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.header p {
|
|
50
|
+
font-size: 0.9rem;
|
|
51
|
+
color: #666;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.tabs {
|
|
55
|
+
display: flex;
|
|
56
|
+
background: #fff;
|
|
57
|
+
border-bottom: 1px solid #ddd;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.tab {
|
|
61
|
+
flex: 1;
|
|
62
|
+
padding: 18px;
|
|
63
|
+
text-align: center;
|
|
64
|
+
font-size: 1rem;
|
|
65
|
+
font-weight: 500;
|
|
66
|
+
background: #f5f5f5;
|
|
67
|
+
border: none;
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
transition: all 0.2s;
|
|
70
|
+
color: #666;
|
|
71
|
+
border-right: 1px solid #ddd;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.tab:last-child {
|
|
75
|
+
border-right: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.tab.active {
|
|
79
|
+
background: #fff;
|
|
80
|
+
color: #000;
|
|
81
|
+
border-bottom: 2px solid #000;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.content {
|
|
85
|
+
flex: 1;
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
overflow: hidden;
|
|
89
|
+
padding-bottom: 130px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.editor-container {
|
|
93
|
+
display: none;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
flex: 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.editor-container.active {
|
|
99
|
+
display: flex;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
textarea {
|
|
103
|
+
flex: 1;
|
|
104
|
+
padding: 20px;
|
|
105
|
+
border: none;
|
|
106
|
+
font-family:
|
|
107
|
+
ui-monospace,
|
|
108
|
+
SFMono-Regular,
|
|
109
|
+
Menlo,
|
|
110
|
+
Consolas,
|
|
111
|
+
"Liberation Mono",
|
|
112
|
+
monospace;
|
|
113
|
+
|
|
114
|
+
font-size: 15px; /* melhor que 1rem no mobile */
|
|
115
|
+
line-height: 1.55;
|
|
116
|
+
font-weight: 500; /* 👈 chave pra não ficar fina */
|
|
117
|
+
letter-spacing: 0.2px;
|
|
118
|
+
|
|
119
|
+
resize: none;
|
|
120
|
+
background: #fff;
|
|
121
|
+
color: #000;
|
|
122
|
+
|
|
123
|
+
white-space: pre;
|
|
124
|
+
overflow-x: auto;
|
|
125
|
+
overflow-y: auto;
|
|
126
|
+
word-break: normal;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
textarea:focus {
|
|
130
|
+
outline: none;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#output {
|
|
134
|
+
background: #fafafa;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.action-bar {
|
|
138
|
+
position: fixed;
|
|
139
|
+
left: 0;
|
|
140
|
+
right: 0;
|
|
141
|
+
bottom: 48px;
|
|
142
|
+
background: #fff;
|
|
143
|
+
padding: 16px 20px;
|
|
144
|
+
border-top: 1px solid #ddd;
|
|
145
|
+
transition: bottom 0.15s ease-out;
|
|
146
|
+
z-index: 100;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.process-btn {
|
|
150
|
+
width: 100%;
|
|
151
|
+
padding: 18px;
|
|
152
|
+
background: #000;
|
|
153
|
+
color: #fff;
|
|
154
|
+
border: 1px solid #000;
|
|
155
|
+
border-radius: 4px;
|
|
156
|
+
font-size: 1.1rem;
|
|
157
|
+
font-weight: 500;
|
|
158
|
+
cursor: pointer;
|
|
159
|
+
transition: background 0.2s;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.process-btn:active {
|
|
163
|
+
background: #333;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
input[type="file"] {
|
|
167
|
+
display: none;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.status {
|
|
171
|
+
position: fixed;
|
|
172
|
+
left: 0;
|
|
173
|
+
right: 0;
|
|
174
|
+
bottom: 0;
|
|
175
|
+
padding: 12px;
|
|
176
|
+
text-align: center;
|
|
177
|
+
font-size: 0.85rem;
|
|
178
|
+
color: #999;
|
|
179
|
+
background: #fff;
|
|
180
|
+
border-top: 1px solid #ddd;
|
|
181
|
+
transition: bottom 0.15s ease-out;
|
|
182
|
+
z-index: 100;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.drawer-overlay {
|
|
186
|
+
position: fixed;
|
|
187
|
+
top: 0;
|
|
188
|
+
left: 0;
|
|
189
|
+
right: 0;
|
|
190
|
+
bottom: 0;
|
|
191
|
+
background: rgba(0,0,0,0.5);
|
|
192
|
+
z-index: 199;
|
|
193
|
+
display: none;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.drawer-overlay.active {
|
|
197
|
+
display: block;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.drawer {
|
|
201
|
+
position: fixed;
|
|
202
|
+
top: 0;
|
|
203
|
+
left: 0;
|
|
204
|
+
bottom: 0;
|
|
205
|
+
width: 85%;
|
|
206
|
+
max-width: 400px;
|
|
207
|
+
background: #fff;
|
|
208
|
+
z-index: 200;
|
|
209
|
+
transform: translateX(-100%);
|
|
210
|
+
transition: transform 0.3s;
|
|
211
|
+
display: flex;
|
|
212
|
+
flex-direction: column;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.drawer.active {
|
|
216
|
+
transform: translateX(0);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.drawer-header {
|
|
220
|
+
padding: 24px 20px;
|
|
221
|
+
border-bottom: 1px solid #ddd;
|
|
222
|
+
display: flex;
|
|
223
|
+
justify-content: space-between;
|
|
224
|
+
align-items: center;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.drawer-header h2 {
|
|
228
|
+
font-size: 1.3rem;
|
|
229
|
+
font-weight: 600;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.drawer-close {
|
|
233
|
+
width: 36px;
|
|
234
|
+
height: 36px;
|
|
235
|
+
border: 1px solid #ddd;
|
|
236
|
+
border-radius: 4px;
|
|
237
|
+
background: #fff;
|
|
238
|
+
font-size: 1.2rem;
|
|
239
|
+
cursor: pointer;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.drawer-close:active {
|
|
243
|
+
background: #f5f5f5;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.drawer-content {
|
|
247
|
+
flex: 1;
|
|
248
|
+
overflow-y: auto;
|
|
249
|
+
padding: 16px 20px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.sketch-item {
|
|
253
|
+
padding: 16px;
|
|
254
|
+
margin-bottom: 8px;
|
|
255
|
+
border: 1px solid #ddd;
|
|
256
|
+
border-radius: 4px;
|
|
257
|
+
background: #fff;
|
|
258
|
+
cursor: pointer;
|
|
259
|
+
transition: background 0.2s;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.sketch-item:active {
|
|
263
|
+
background: #f5f5f5;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.sketch-item.active {
|
|
267
|
+
background: #000;
|
|
268
|
+
color: #fff;
|
|
269
|
+
border-color: #000;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.sketch-item-name {
|
|
273
|
+
font-size: 1rem;
|
|
274
|
+
font-weight: 500;
|
|
275
|
+
margin-bottom: 4px;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.sketch-item-date {
|
|
279
|
+
font-size: 0.8rem;
|
|
280
|
+
color: #999;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.sketch-item.active .sketch-item-date {
|
|
284
|
+
color: #ccc;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.sketch-item-actions {
|
|
288
|
+
display: flex;
|
|
289
|
+
gap: 8px;
|
|
290
|
+
margin-top: 12px;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.sketch-item-btn {
|
|
294
|
+
flex: 1;
|
|
295
|
+
padding: 8px;
|
|
296
|
+
border: 1px solid #ddd;
|
|
297
|
+
border-radius: 4px;
|
|
298
|
+
background: #fff;
|
|
299
|
+
font-size: 0.85rem;
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.sketch-item.active .sketch-item-btn {
|
|
304
|
+
border-color: #fff;
|
|
305
|
+
color: #fff;
|
|
306
|
+
background: transparent;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.sketch-item-btn:active {
|
|
310
|
+
background: #f5f5f5;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.sketch-item.active .sketch-item-btn:active {
|
|
314
|
+
background: rgba(255,255,255,0.1);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.drawer-footer {
|
|
318
|
+
padding: 16px 20px;
|
|
319
|
+
border-top: 1px solid #ddd;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.drawer-action-btn {
|
|
323
|
+
width: 100%;
|
|
324
|
+
padding: 14px;
|
|
325
|
+
margin-bottom: 8px;
|
|
326
|
+
background: #fff;
|
|
327
|
+
color: #000;
|
|
328
|
+
border: 1px solid #ddd;
|
|
329
|
+
border-radius: 4px;
|
|
330
|
+
font-size: 0.95rem;
|
|
331
|
+
font-weight: 400;
|
|
332
|
+
cursor: pointer;
|
|
333
|
+
display: flex;
|
|
334
|
+
align-items: center;
|
|
335
|
+
justify-content: center;
|
|
336
|
+
gap: 8px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.drawer-action-btn:active {
|
|
340
|
+
background: #f5f5f5;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.drawer-new-btn {
|
|
344
|
+
width: 100%;
|
|
345
|
+
padding: 16px;
|
|
346
|
+
background: #000;
|
|
347
|
+
color: #fff;
|
|
348
|
+
border: none;
|
|
349
|
+
border-radius: 4px;
|
|
350
|
+
font-size: 1rem;
|
|
351
|
+
font-weight: 500;
|
|
352
|
+
cursor: pointer;
|
|
353
|
+
margin-top: 8px;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.drawer-new-btn:active {
|
|
357
|
+
background: #333;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.empty-state {
|
|
361
|
+
text-align: center;
|
|
362
|
+
padding: 40px 20px;
|
|
363
|
+
color: #999;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
@media (min-width: 768px) {
|
|
367
|
+
.app {
|
|
368
|
+
max-width: 600px;
|
|
369
|
+
margin: 0 auto;
|
|
370
|
+
border-left: 1px solid #ddd;
|
|
371
|
+
border-right: 1px solid #ddd;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.action-bar,
|
|
375
|
+
.status {
|
|
376
|
+
max-width: 600px;
|
|
377
|
+
left: 50%;
|
|
378
|
+
transform: translateX(-50%);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
</style>
|
|
7
382
|
</head>
|
|
8
383
|
<body>
|
|
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
|
-
|
|
384
|
+
<div class="app">
|
|
385
|
+
<div class="header" onclick="toggleDrawer()">
|
|
386
|
+
<h1>🦜 papagaio</h1>
|
|
387
|
+
<p>easy yet powerful text preprocessor</p>
|
|
388
|
+
</div>
|
|
389
|
+
|
|
390
|
+
<div class="tabs">
|
|
391
|
+
<button class="tab active" onclick="switchTab('input')">INPUT</button>
|
|
392
|
+
<button class="tab" onclick="switchTab('output')">OUTPUT</button>
|
|
393
|
+
</div>
|
|
394
|
+
|
|
395
|
+
<div class="content">
|
|
396
|
+
<div class="editor-container active" id="inputContainer">
|
|
397
|
+
<textarea id="input"></textarea>
|
|
398
|
+
</div>
|
|
399
|
+
<div class="editor-container" id="outputContainer">
|
|
400
|
+
<textarea id="output" readonly></textarea>
|
|
401
|
+
</div>
|
|
402
|
+
</div>
|
|
403
|
+
|
|
404
|
+
<div class="action-bar" id="actionBar">
|
|
405
|
+
<button class="process-btn" onclick="processCode()">Process</button>
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
<div class="status" id="statusBar">
|
|
409
|
+
Last saved: <span id="lastSaved">never</span>
|
|
410
|
+
</div>
|
|
411
|
+
|
|
412
|
+
<div class="drawer-overlay" id="drawerOverlay" onclick="toggleDrawer()"></div>
|
|
413
|
+
<div class="drawer" id="drawer">
|
|
414
|
+
<div class="drawer-header">
|
|
415
|
+
<h2 id="drawerTitle">Sketches</h2>
|
|
416
|
+
<button class="drawer-close" onclick="toggleDrawer()">×</button>
|
|
417
|
+
</div>
|
|
418
|
+
<div class="drawer-content" id="drawerContent"></div>
|
|
419
|
+
<div class="drawer-footer">
|
|
420
|
+
<button class="drawer-action-btn" onclick="exportSketches()">
|
|
421
|
+
↓ Export Sketches
|
|
422
|
+
</button>
|
|
423
|
+
<label for="importFileInput" class="drawer-action-btn">
|
|
424
|
+
↑ Import Sketches
|
|
425
|
+
</label>
|
|
426
|
+
<input type="file" id="importFileInput" onchange="importSketches(this.files[0])" accept=".json">
|
|
427
|
+
<button class="drawer-new-btn" onclick="createNewSketchFromDrawer()">+ New Sketch</button>
|
|
428
|
+
</div>
|
|
429
|
+
</div>
|
|
35
430
|
</div>
|
|
36
|
-
|
|
37
|
-
<hr>
|
|
38
|
-
|
|
39
|
-
<h3>INPUT</h3>
|
|
40
|
-
<textarea id="input" rows="15" cols="80" style="width: 70%; font-family: monospace;"></textarea>
|
|
41
|
-
|
|
42
|
-
<br><br>
|
|
43
|
-
|
|
44
|
-
<button onclick="processCode()">Process</button>
|
|
45
|
-
|
|
46
|
-
<br><br>
|
|
47
|
-
|
|
48
|
-
<h3>OUTPUT</h3>
|
|
49
|
-
<textarea id="output" rows="15" cols="80" style="width: 70%; font-family: monospace;" readonly></textarea>
|
|
50
431
|
|
|
51
432
|
<script type="module">
|
|
52
433
|
import { Papagaio } from './src/papagaio.js';
|
|
53
|
-
|
|
54
434
|
class SketchesManager {
|
|
55
435
|
constructor() {
|
|
56
436
|
this.sketches = this.loadSketches();
|
|
@@ -139,13 +519,86 @@
|
|
|
139
519
|
|
|
140
520
|
let processor = new Papagaio();
|
|
141
521
|
let sketchesManager;
|
|
522
|
+
let currentTab = 'input';
|
|
523
|
+
|
|
524
|
+
function setupKeyboardAdjustment() {
|
|
525
|
+
if (window.visualViewport) {
|
|
526
|
+
const actionBar = document.getElementById('actionBar');
|
|
527
|
+
const statusBar = document.getElementById('statusBar');
|
|
528
|
+
const statusHeight = 48;
|
|
529
|
+
|
|
530
|
+
window.visualViewport.addEventListener('resize', () => {
|
|
531
|
+
const viewportHeight = window.visualViewport.height;
|
|
532
|
+
const windowHeight = window.innerHeight;
|
|
533
|
+
const keyboardHeight = windowHeight - viewportHeight;
|
|
534
|
+
|
|
535
|
+
if (keyboardHeight > 100) {
|
|
536
|
+
actionBar.style.bottom = `${keyboardHeight + statusHeight}px`;
|
|
537
|
+
statusBar.style.bottom = `${keyboardHeight}px`;
|
|
538
|
+
} else {
|
|
539
|
+
actionBar.style.bottom = `${statusHeight}px`;
|
|
540
|
+
statusBar.style.bottom = '0px';
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
window.visualViewport.addEventListener('scroll', () => {
|
|
545
|
+
const viewportHeight = window.visualViewport.height;
|
|
546
|
+
const windowHeight = window.innerHeight;
|
|
547
|
+
const keyboardHeight = windowHeight - viewportHeight;
|
|
548
|
+
|
|
549
|
+
if (keyboardHeight > 100) {
|
|
550
|
+
actionBar.style.bottom = `${keyboardHeight + statusHeight}px`;
|
|
551
|
+
statusBar.style.bottom = `${keyboardHeight}px`;
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
142
556
|
|
|
143
557
|
window.addEventListener('load', () => {
|
|
144
558
|
sketchesManager = new SketchesManager();
|
|
145
559
|
loadOrCreateDefaultSketch();
|
|
146
|
-
|
|
560
|
+
renderDrawerSketches();
|
|
561
|
+
setupSwipeGestures();
|
|
562
|
+
setupKeyboardAdjustment();
|
|
147
563
|
});
|
|
148
564
|
|
|
565
|
+
function setupSwipeGestures() {
|
|
566
|
+
let touchStartX = 0;
|
|
567
|
+
let touchStartY = 0;
|
|
568
|
+
let touchEndX = 0;
|
|
569
|
+
let touchEndY = 0;
|
|
570
|
+
|
|
571
|
+
document.addEventListener('touchstart', (e) => {
|
|
572
|
+
touchStartX = e.changedTouches[0].screenX;
|
|
573
|
+
touchStartY = e.changedTouches[0].screenY;
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
document.addEventListener('touchend', (e) => {
|
|
577
|
+
touchEndX = e.changedTouches[0].screenX;
|
|
578
|
+
touchEndY = e.changedTouches[0].screenY;
|
|
579
|
+
handleSwipe();
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
function handleSwipe() {
|
|
583
|
+
const diffX = touchEndX - touchStartX;
|
|
584
|
+
const diffY = touchEndY - touchStartY;
|
|
585
|
+
|
|
586
|
+
if (touchStartX < 50 && diffX > 100 && Math.abs(diffY) < 100) {
|
|
587
|
+
const drawer = document.getElementById('drawer');
|
|
588
|
+
if (!drawer.classList.contains('active')) {
|
|
589
|
+
toggleDrawer();
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (diffX < -100 && Math.abs(diffY) < 100) {
|
|
594
|
+
const drawer = document.getElementById('drawer');
|
|
595
|
+
if (drawer.classList.contains('active')) {
|
|
596
|
+
toggleDrawer();
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
149
602
|
function loadOrCreateDefaultSketch() {
|
|
150
603
|
let sketch = null;
|
|
151
604
|
if (sketchesManager.currentSketchId) {
|
|
@@ -166,39 +619,45 @@
|
|
|
166
619
|
if (sketch) {
|
|
167
620
|
document.getElementById('input').value = sketch.input;
|
|
168
621
|
document.getElementById('output').value = '';
|
|
622
|
+
updateDrawerTitle(sketch.name);
|
|
169
623
|
}
|
|
170
624
|
}
|
|
171
625
|
|
|
626
|
+
function updateDrawerTitle(name) {
|
|
627
|
+
document.getElementById('drawerTitle').textContent = `${name}`;
|
|
628
|
+
}
|
|
629
|
+
|
|
172
630
|
function saveCurrentSketch() {
|
|
173
631
|
if (sketchesManager.currentSketchId) {
|
|
174
632
|
sketchesManager.updateSketch(sketchesManager.currentSketchId, {
|
|
175
633
|
input: document.getElementById('input').value
|
|
176
634
|
});
|
|
635
|
+
updateLastSaved();
|
|
177
636
|
}
|
|
178
637
|
}
|
|
179
638
|
|
|
180
|
-
function
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const sketches = sketchesManager.getAllSketches();
|
|
185
|
-
sketches.forEach(sketch => {
|
|
186
|
-
const option = document.createElement('option');
|
|
187
|
-
option.value = sketch.id;
|
|
188
|
-
option.textContent = sketch.name;
|
|
189
|
-
if (sketch.id === sketchesManager.currentSketchId) {
|
|
190
|
-
option.selected = true;
|
|
191
|
-
}
|
|
192
|
-
select.appendChild(option);
|
|
193
|
-
});
|
|
639
|
+
function updateLastSaved() {
|
|
640
|
+
const now = new Date();
|
|
641
|
+
const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
|
|
642
|
+
document.getElementById('lastSaved').textContent = timeStr;
|
|
194
643
|
}
|
|
195
644
|
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
const id = select.value;
|
|
645
|
+
function switchTab(tab) {
|
|
646
|
+
currentTab = tab;
|
|
199
647
|
|
|
200
|
-
|
|
648
|
+
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
|
649
|
+
document.querySelectorAll('.editor-container').forEach(c => c.classList.remove('active'));
|
|
201
650
|
|
|
651
|
+
if (tab === 'input') {
|
|
652
|
+
document.querySelectorAll('.tab')[0].classList.add('active');
|
|
653
|
+
document.getElementById('inputContainer').classList.add('active');
|
|
654
|
+
} else {
|
|
655
|
+
document.querySelectorAll('.tab')[1].classList.add('active');
|
|
656
|
+
document.getElementById('outputContainer').classList.add('active');
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
function selectSketch(id) {
|
|
202
661
|
saveCurrentSketch();
|
|
203
662
|
sketchesManager.setCurrentSketchId(id);
|
|
204
663
|
const sketch = sketchesManager.getSketch(id);
|
|
@@ -206,59 +665,83 @@
|
|
|
206
665
|
if (sketch) {
|
|
207
666
|
document.getElementById('input').value = sketch.input;
|
|
208
667
|
document.getElementById('output').value = '';
|
|
668
|
+
updateDrawerTitle(sketch.name);
|
|
669
|
+
renderDrawerSketches();
|
|
209
670
|
}
|
|
210
671
|
}
|
|
211
672
|
|
|
212
|
-
function
|
|
673
|
+
function createNewSketchFromDrawer() {
|
|
213
674
|
const name = prompt('Enter sketch name:');
|
|
214
675
|
if (!name || !name.trim()) {
|
|
215
|
-
alert('Please enter a valid sketch name');
|
|
216
676
|
return;
|
|
217
677
|
}
|
|
218
678
|
|
|
219
679
|
const id = sketchesManager.createSketch(name.trim());
|
|
220
|
-
populateSketchSelect();
|
|
221
|
-
|
|
222
680
|
const sketch = sketchesManager.getSketch(id);
|
|
223
681
|
if (sketch) {
|
|
224
682
|
document.getElementById('input').value = sketch.input;
|
|
225
683
|
document.getElementById('output').value = '';
|
|
684
|
+
updateDrawerTitle(sketch.name);
|
|
685
|
+
renderDrawerSketches();
|
|
226
686
|
}
|
|
227
687
|
}
|
|
228
688
|
|
|
229
|
-
function
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const sketch = sketchesManager.getSketch(sketchesManager.currentSketchId);
|
|
689
|
+
function renameSketchFromDrawer(id, event) {
|
|
690
|
+
event.stopPropagation();
|
|
691
|
+
const sketch = sketchesManager.getSketch(id);
|
|
236
692
|
const newName = prompt('Enter new name:', sketch.name);
|
|
237
693
|
|
|
238
694
|
if (!newName || !newName.trim()) {
|
|
239
|
-
alert('Please enter a valid name');
|
|
240
695
|
return;
|
|
241
696
|
}
|
|
242
697
|
|
|
243
|
-
sketchesManager.renameSketch(
|
|
244
|
-
|
|
698
|
+
sketchesManager.renameSketch(id, newName.trim());
|
|
699
|
+
|
|
700
|
+
if (id === sketchesManager.currentSketchId) {
|
|
701
|
+
updateDrawerTitle(newName.trim());
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
renderDrawerSketches();
|
|
245
705
|
}
|
|
246
706
|
|
|
247
|
-
function
|
|
248
|
-
|
|
249
|
-
|
|
707
|
+
function deleteSketchFromDrawer(id, event) {
|
|
708
|
+
event.stopPropagation();
|
|
709
|
+
const sketch = sketchesManager.getSketch(id);
|
|
710
|
+
|
|
711
|
+
if (!confirm(`Delete "${sketch.name}"?`)) {
|
|
250
712
|
return;
|
|
251
713
|
}
|
|
252
714
|
|
|
253
|
-
|
|
715
|
+
sketchesManager.deleteSketch(id);
|
|
716
|
+
loadOrCreateDefaultSketch();
|
|
717
|
+
renderDrawerSketches();
|
|
718
|
+
|
|
719
|
+
const currentSketch = sketchesManager.getSketch(sketchesManager.currentSketchId);
|
|
720
|
+
if (currentSketch) {
|
|
721
|
+
updateDrawerTitle(currentSketch.name);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
function renderDrawerSketches() {
|
|
726
|
+
const content = document.getElementById('drawerContent');
|
|
727
|
+
const sketches = sketchesManager.getAllSketches();
|
|
254
728
|
|
|
255
|
-
if (
|
|
729
|
+
if (sketches.length === 0) {
|
|
730
|
+
content.innerHTML = '<div class="empty-state">No sketches yet<br>Create one to get started</div>';
|
|
256
731
|
return;
|
|
257
732
|
}
|
|
258
733
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
734
|
+
content.innerHTML = sketches.map(sketch => `
|
|
735
|
+
<div class="sketch-item ${sketch.id === sketchesManager.currentSketchId ? 'active' : ''}"
|
|
736
|
+
onclick="selectSketch('${sketch.id}')">
|
|
737
|
+
<div class="sketch-item-name">${sketch.name}</div>
|
|
738
|
+
<div class="sketch-item-date">${sketch.createdAt}</div>
|
|
739
|
+
<div class="sketch-item-actions">
|
|
740
|
+
<button class="sketch-item-btn" onclick="renameSketchFromDrawer('${sketch.id}', event)">Rename</button>
|
|
741
|
+
<button class="sketch-item-btn" onclick="deleteSketchFromDrawer('${sketch.id}', event)">Delete</button>
|
|
742
|
+
</div>
|
|
743
|
+
</div>
|
|
744
|
+
`).join('');
|
|
262
745
|
}
|
|
263
746
|
|
|
264
747
|
function processCode() {
|
|
@@ -267,11 +750,25 @@
|
|
|
267
750
|
const output = processor.process(input);
|
|
268
751
|
document.getElementById('output').value = output;
|
|
269
752
|
saveCurrentSketch();
|
|
753
|
+
switchTab('output');
|
|
270
754
|
} catch (err) {
|
|
271
755
|
document.getElementById('output').value = `Error: ${err.message}`;
|
|
272
756
|
}
|
|
273
757
|
}
|
|
274
758
|
|
|
759
|
+
function toggleDrawer() {
|
|
760
|
+
const drawer = document.getElementById('drawer');
|
|
761
|
+
const overlay = document.getElementById('drawerOverlay');
|
|
762
|
+
|
|
763
|
+
// Fecha o teclado ao abrir o drawer
|
|
764
|
+
if (!drawer.classList.contains('active')) {
|
|
765
|
+
document.activeElement?.blur();
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
drawer.classList.toggle('active');
|
|
769
|
+
overlay.classList.toggle('active');
|
|
770
|
+
}
|
|
771
|
+
|
|
275
772
|
function exportSketches() {
|
|
276
773
|
const data = {
|
|
277
774
|
papagaio_sketches: localStorage.getItem('papagaio_sketches'),
|
|
@@ -308,7 +805,7 @@
|
|
|
308
805
|
}
|
|
309
806
|
location.reload();
|
|
310
807
|
} catch (err) {
|
|
311
|
-
alert('Error importing
|
|
808
|
+
alert('Error importing: ' + err.message);
|
|
312
809
|
}
|
|
313
810
|
};
|
|
314
811
|
|
|
@@ -317,15 +814,17 @@
|
|
|
317
814
|
|
|
318
815
|
setInterval(() => {
|
|
319
816
|
saveCurrentSketch();
|
|
320
|
-
},
|
|
817
|
+
}, 2000);
|
|
321
818
|
|
|
322
819
|
window.processCode = processCode;
|
|
323
|
-
window.
|
|
324
|
-
window.
|
|
325
|
-
window.
|
|
326
|
-
window.
|
|
820
|
+
window.selectSketch = selectSketch;
|
|
821
|
+
window.createNewSketchFromDrawer = createNewSketchFromDrawer;
|
|
822
|
+
window.renameSketchFromDrawer = renameSketchFromDrawer;
|
|
823
|
+
window.deleteSketchFromDrawer = deleteSketchFromDrawer;
|
|
327
824
|
window.exportSketches = exportSketches;
|
|
328
825
|
window.importSketches = importSketches;
|
|
826
|
+
window.switchTab = switchTab;
|
|
827
|
+
window.toggleDrawer = toggleDrawer;
|
|
329
828
|
</script>
|
|
330
829
|
</body>
|
|
331
830
|
</html>
|