pinokiod 3.48.0 → 3.50.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/kernel/environment.js +6 -0
- package/package.json +1 -1
- package/server/index.js +37 -13
- package/server/public/common.js +85 -8
- package/server/public/style.css +15 -27
- package/server/public/urldropdown.css +174 -0
- package/server/public/urldropdown.js +396 -0
- package/server/public/window_storage.js +30 -0
- package/server/views/app.ejs +19 -27
- package/server/views/columns.ejs +59 -30
- package/server/views/connect.ejs +21 -1
- package/server/views/container.ejs +21 -1
- package/server/views/download.ejs +2 -0
- package/server/views/index.ejs +20 -1
- package/server/views/init/index.ejs +4 -0
- package/server/views/net.ejs +21 -1
- package/server/views/network.ejs +21 -1
- package/server/views/review.ejs +8 -0
- package/server/views/rows.ejs +61 -16
- package/server/views/screenshots.ejs +21 -1
- package/server/views/settings.ejs +22 -2
- package/server/views/setup.ejs +2 -0
- package/server/views/tools.ejs +21 -1
package/server/views/rows.ejs
CHANGED
|
@@ -13,6 +13,18 @@ body {
|
|
|
13
13
|
display: grid;
|
|
14
14
|
grid-template-rows: var(--row0, 1fr) 6px var(--row1, 1fr);
|
|
15
15
|
gap: 0px;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
#dragger {
|
|
19
|
+
-webkit-app-region: drag;
|
|
20
|
+
cursor: drag;
|
|
21
|
+
position: absolute;
|
|
22
|
+
top: 0;
|
|
23
|
+
left: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
height: 20px;
|
|
26
|
+
width: 100%;
|
|
27
|
+
z-index: 1000000000000;
|
|
16
28
|
}
|
|
17
29
|
body iframe {
|
|
18
30
|
border: none;
|
|
@@ -54,8 +66,10 @@ body.resizing {
|
|
|
54
66
|
.gutter:hover::before, body.resizing .gutter::before { background: #9e9e9e; }
|
|
55
67
|
.gutter:focus { outline: none; box-shadow: inset 0 0 0 2px #90caf9; }
|
|
56
68
|
</style>
|
|
69
|
+
<script src="/window_storage.js"></script>
|
|
57
70
|
</head>
|
|
58
71
|
<body class='<%=theme%>'>
|
|
72
|
+
<div id='dragger'></div>
|
|
59
73
|
<iframe id='row0' data-src="<%=src%>"></iframe>
|
|
60
74
|
<div id="gutter" class="gutter" tabindex="0" role="separator" aria-orientation="horizontal" aria-label="Resize panels" aria-valuemin="120" aria-valuemax="0" aria-valuenow="0"></div>
|
|
61
75
|
<iframe id='row1' data-src="<%=src%>"></iframe>
|
|
@@ -105,7 +119,7 @@ body.resizing {
|
|
|
105
119
|
const total = computeTotal();
|
|
106
120
|
if (total > 0) {
|
|
107
121
|
const ratio = clamp(topPx / total, 0, 1);
|
|
108
|
-
|
|
122
|
+
windowStorage.setItem(splitKey, String(ratio));
|
|
109
123
|
}
|
|
110
124
|
}
|
|
111
125
|
|
|
@@ -121,7 +135,7 @@ body.resizing {
|
|
|
121
135
|
function restorePaneURL(pane) {
|
|
122
136
|
const key = urlKeyFor(pane.name);
|
|
123
137
|
try {
|
|
124
|
-
const saved =
|
|
138
|
+
const saved = windowStorage.getItem(key);
|
|
125
139
|
const fallback = pane.getAttribute('data-src') || pane.getAttribute('src') || '';
|
|
126
140
|
const target = (saved && typeof saved === 'string') ? saved : fallback;
|
|
127
141
|
if (target && pane.src !== target) pane.src = target;
|
|
@@ -134,7 +148,7 @@ body.resizing {
|
|
|
134
148
|
const cw = pane.contentWindow;
|
|
135
149
|
if (!cw) return;
|
|
136
150
|
const notify = () => {
|
|
137
|
-
|
|
151
|
+
windowStorage.setItem(key, cw.location.href);
|
|
138
152
|
};
|
|
139
153
|
// Hook SPA navigations
|
|
140
154
|
const _ps = cw.history.pushState;
|
|
@@ -147,7 +161,7 @@ body.resizing {
|
|
|
147
161
|
else notify();
|
|
148
162
|
} catch (err) {
|
|
149
163
|
// Cross-origin: fall back to saving src only
|
|
150
|
-
|
|
164
|
+
windowStorage.setItem(key, pane.src);
|
|
151
165
|
}
|
|
152
166
|
}
|
|
153
167
|
|
|
@@ -174,8 +188,9 @@ body.resizing {
|
|
|
174
188
|
let overlay = null;
|
|
175
189
|
|
|
176
190
|
function refreshLayout (splitKey) {
|
|
177
|
-
let val =
|
|
191
|
+
let val = windowStorage.getItem(splitKey)
|
|
178
192
|
let id = splitKey.replace("splitRatio:", "")
|
|
193
|
+
console.log({ id, val })
|
|
179
194
|
if (val === "1" || val === "0") {
|
|
180
195
|
if (val === "1") {
|
|
181
196
|
id_to_hide = id + ".1"
|
|
@@ -184,8 +199,24 @@ body.resizing {
|
|
|
184
199
|
}
|
|
185
200
|
const el = document.querySelector(`iframe[name='${id_to_hide}']`)
|
|
186
201
|
el.remove()
|
|
187
|
-
document.
|
|
188
|
-
|
|
202
|
+
if (document.querySelector("#gutter")) {
|
|
203
|
+
document.querySelector("#gutter").remove()
|
|
204
|
+
}
|
|
205
|
+
let existing_iframe = document.querySelector("iframe")
|
|
206
|
+
if (existing_iframe) {
|
|
207
|
+
debugger
|
|
208
|
+
document.body.className = "single"
|
|
209
|
+
} else {
|
|
210
|
+
if (window.parent) {
|
|
211
|
+
// if all child iframes have been removed, remove self
|
|
212
|
+
window.parent.postMessage({
|
|
213
|
+
e: "close"
|
|
214
|
+
}, "*")
|
|
215
|
+
} else {
|
|
216
|
+
// if this is the top window, everything has been removed, so just redirect to home
|
|
217
|
+
location.href = "/"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
189
220
|
}
|
|
190
221
|
}
|
|
191
222
|
|
|
@@ -267,7 +298,7 @@ body.resizing {
|
|
|
267
298
|
|
|
268
299
|
// Initialize from saved ratio if available and set ARIA
|
|
269
300
|
try {
|
|
270
|
-
const saved = parseFloat(
|
|
301
|
+
const saved = parseFloat(windowStorage.getItem(splitKey) || '');
|
|
271
302
|
console.log({ saved })
|
|
272
303
|
if (!Number.isNaN(saved) && saved > 0 && saved < 1) {
|
|
273
304
|
console.log("< 1")
|
|
@@ -285,7 +316,7 @@ body.resizing {
|
|
|
285
316
|
// Re-apply on window resize to keep ratio
|
|
286
317
|
window.addEventListener('resize', () => {
|
|
287
318
|
try {
|
|
288
|
-
const saved = parseFloat(
|
|
319
|
+
const saved = parseFloat(windowStorage.getItem(splitKey) || '');
|
|
289
320
|
if (!Number.isNaN(saved) && saved > 0 && saved < 1) {
|
|
290
321
|
applyFromRatio(saved);
|
|
291
322
|
} else {
|
|
@@ -304,11 +335,17 @@ body.resizing {
|
|
|
304
335
|
|
|
305
336
|
let sourceFrameId = null;
|
|
306
337
|
|
|
307
|
-
if (event.source === row0.contentWindow) {
|
|
338
|
+
if (row0 && event.source === row0.contentWindow) {
|
|
308
339
|
sourceFrameId = 'row0';
|
|
309
|
-
} else if (event.source === row1.contentWindow) {
|
|
340
|
+
} else if (row1 && event.source === row1.contentWindow) {
|
|
310
341
|
sourceFrameId = 'row1';
|
|
311
342
|
}
|
|
343
|
+
|
|
344
|
+
if (!sourceFrameId) {
|
|
345
|
+
windowStorage.removeItem(splitKey)
|
|
346
|
+
location.href = "/"
|
|
347
|
+
return
|
|
348
|
+
}
|
|
312
349
|
|
|
313
350
|
console.log('Message received from iframe:', sourceFrameId);
|
|
314
351
|
|
|
@@ -317,16 +354,13 @@ body.resizing {
|
|
|
317
354
|
console.log({ splitKey })
|
|
318
355
|
for (let iframe of iframes) {
|
|
319
356
|
if (event.source === iframe.contentWindow) {
|
|
320
|
-
// const splitKey = `splitRatio:${iframe.name}`
|
|
321
357
|
if (iframe.id === "row0") {
|
|
322
358
|
// hide row0 => ratio:; 0
|
|
323
|
-
|
|
324
|
-
try { sessionStorage.setItem(splitKey, "0"); } catch (_) { console.log("> e", _)}
|
|
359
|
+
windowStorage.setItem(splitKey, "0");
|
|
325
360
|
refreshLayout(splitKey)
|
|
326
361
|
} else if (iframe.id === "row1") {
|
|
327
362
|
// hide row1 => ratio:; 1
|
|
328
|
-
|
|
329
|
-
try { sessionStorage.setItem(splitKey, "1"); } catch (_) {console.log(">>> e", _)}
|
|
363
|
+
windowStorage.setItem(splitKey, "1");
|
|
330
364
|
refreshLayout(splitKey)
|
|
331
365
|
}
|
|
332
366
|
console.log('Message from iframe with id:', iframe.id);
|
|
@@ -336,6 +370,17 @@ body.resizing {
|
|
|
336
370
|
}
|
|
337
371
|
})
|
|
338
372
|
})();
|
|
373
|
+
if (document.querySelector("#collapse") && window.windowStorage) {
|
|
374
|
+
document.querySelector("#collapse").addEventListener("click", (e) => {
|
|
375
|
+
document.body.classList.toggle("minimized")
|
|
376
|
+
let frame_key = window.frameElement?.name || "";
|
|
377
|
+
if (document.body.classList.contains("minimized")) {
|
|
378
|
+
windowStorage.setItem(frame_key + ":window_mode", "minimized")
|
|
379
|
+
} else {
|
|
380
|
+
windowStorage.setItem(frame_key + ":window_mode", "full")
|
|
381
|
+
}
|
|
382
|
+
})
|
|
383
|
+
}
|
|
339
384
|
</script>
|
|
340
385
|
</body>
|
|
341
386
|
</html>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<link href="/markdown.css" rel="stylesheet"/>
|
|
11
11
|
<link href="/noty.css" rel="stylesheet"/>
|
|
12
12
|
<link href="/style.css" rel="stylesheet"/>
|
|
13
|
+
<link href="/urldropdown.css" rel="stylesheet" />
|
|
13
14
|
<% if (agent === "electron") { %>
|
|
14
15
|
<link href="/electron.css" rel="stylesheet"/>
|
|
15
16
|
<% } %>
|
|
@@ -544,12 +545,14 @@ body.dark .gallery-item-timestamp {
|
|
|
544
545
|
justify-content: center;
|
|
545
546
|
}
|
|
546
547
|
|
|
548
|
+
/*
|
|
547
549
|
@media only screen and (max-width: 800px) {
|
|
548
550
|
body {
|
|
549
551
|
display: flex !important;
|
|
550
552
|
flex-direction: row !important;
|
|
551
553
|
}
|
|
552
554
|
}
|
|
555
|
+
*/
|
|
553
556
|
@media only screen and (max-width: 768px) {
|
|
554
557
|
.gallery-grid {
|
|
555
558
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
@@ -610,6 +613,7 @@ body.dark .gallery-item-timestamp {
|
|
|
610
613
|
}
|
|
611
614
|
}
|
|
612
615
|
</style>
|
|
616
|
+
<script src="/window_storage.js"></script>
|
|
613
617
|
<script src="/popper.min.js"></script>
|
|
614
618
|
<script src="/tippy-bundle.umd.min.js"></script>
|
|
615
619
|
<script src="/hotkeys.min.js"></script>
|
|
@@ -625,6 +629,15 @@ body.dark .gallery-item-timestamp {
|
|
|
625
629
|
<script src="/common.js"></script>
|
|
626
630
|
<script src="/opener.js"></script>
|
|
627
631
|
<script src="/nav.js"></script>
|
|
632
|
+
<script src="/urldropdown.js"></script>
|
|
633
|
+
<script>
|
|
634
|
+
// Initialize URL Dropdown with empty behavior for screenshots page
|
|
635
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
636
|
+
initUrlDropdown({
|
|
637
|
+
clearBehavior: 'empty'
|
|
638
|
+
});
|
|
639
|
+
});
|
|
640
|
+
</script>
|
|
628
641
|
<script src="/report.js"></script>
|
|
629
642
|
</head>
|
|
630
643
|
<body class='<%=theme%>' data-agent="<%=agent%>">
|
|
@@ -636,11 +649,18 @@ body.dark .gallery-item-timestamp {
|
|
|
636
649
|
<header class='navheader grabbable'>
|
|
637
650
|
<h1>
|
|
638
651
|
<a class='home' href="/"><img class='icon' src="/pinokio-black.png"></a>
|
|
652
|
+
<button id='collapse' class='btn2' data-tippy-content="toggle fullscreen view"><i class="fa-solid fa-bars"></i></button>
|
|
639
653
|
<button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
|
|
640
654
|
<button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
|
|
641
655
|
<button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
|
|
642
656
|
<button class='btn2' id='screenshot' data-tippy-content="take a screenshot"><i class="fa-solid fa-camera"></i></button>
|
|
643
|
-
<
|
|
657
|
+
<button class='btn2 mobile-link-button' id='mobile-link-button' data-tippy-content="enter url"><i class="fa-solid fa-link"></i></button>
|
|
658
|
+
<form class='urlbar'>
|
|
659
|
+
<div class='url-input-container'>
|
|
660
|
+
<input type='url' placeholder='enter a local url'>
|
|
661
|
+
<div class='url-dropdown' id='url-dropdown'></div>
|
|
662
|
+
</div>
|
|
663
|
+
</form>
|
|
644
664
|
<a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
|
|
645
665
|
<div><i class="fa-solid fa-table-columns"></i></div>
|
|
646
666
|
</a>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<link href="/markdown.css" rel="stylesheet"/>
|
|
11
11
|
<link href="/noty.css" rel="stylesheet"/>
|
|
12
12
|
<link href="/style.css" rel="stylesheet"/>
|
|
13
|
+
<link href="/urldropdown.css" rel="stylesheet" />
|
|
13
14
|
<% if (agent === "electron") { %>
|
|
14
15
|
<link href="/electron.css" rel="stylesheet"/>
|
|
15
16
|
<% } %>
|
|
@@ -279,12 +280,14 @@ aside .selected {
|
|
|
279
280
|
opacity: 1;
|
|
280
281
|
}
|
|
281
282
|
|
|
283
|
+
/*
|
|
282
284
|
@media only screen and (max-width: 800px) {
|
|
283
285
|
body {
|
|
284
286
|
display: flex !important;
|
|
285
287
|
flex-direction: row !important;
|
|
286
288
|
}
|
|
287
289
|
}
|
|
290
|
+
*/
|
|
288
291
|
@media only screen and (max-width: 600px) {
|
|
289
292
|
aside {
|
|
290
293
|
width: unset;
|
|
@@ -332,6 +335,7 @@ aside .selected {
|
|
|
332
335
|
}
|
|
333
336
|
}
|
|
334
337
|
</style>
|
|
338
|
+
<script src="/window_storage.js"></script>
|
|
335
339
|
<script src="/popper.min.js"></script>
|
|
336
340
|
<script src="/tippy-bundle.umd.min.js"></script>
|
|
337
341
|
<script src="/hotkeys.min.js"></script>
|
|
@@ -347,6 +351,15 @@ aside .selected {
|
|
|
347
351
|
<script src="/common.js"></script>
|
|
348
352
|
<script src="/opener.js"></script>
|
|
349
353
|
<script src="/nav.js"></script>
|
|
354
|
+
<script src="/urldropdown.js"></script>
|
|
355
|
+
<script>
|
|
356
|
+
// Initialize URL Dropdown with empty behavior for settings page
|
|
357
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
358
|
+
initUrlDropdown({
|
|
359
|
+
clearBehavior: 'empty'
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
</script>
|
|
350
363
|
<script src="/report.js"></script>
|
|
351
364
|
</head>
|
|
352
365
|
<body class='<%=theme%>' data-agent="<%=agent%>">
|
|
@@ -358,6 +371,7 @@ aside .selected {
|
|
|
358
371
|
<header class='navheader grabbable'>
|
|
359
372
|
<h1>
|
|
360
373
|
<a class='home' href="/"><img class='icon' src="/pinokio-black.png"></a>
|
|
374
|
+
<button id='collapse' class='btn2' data-tippy-content="toggle fullscreen view"><i class="fa-solid fa-bars"></i></button>
|
|
361
375
|
<button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
|
|
362
376
|
<button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
|
|
363
377
|
<button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
|
|
@@ -369,7 +383,13 @@ aside .selected {
|
|
|
369
383
|
<% } %>
|
|
370
384
|
<% }) %>
|
|
371
385
|
<button class='btn2' id='screenshot' data-tippy-content="take a screenshot"><i class="fa-solid fa-camera"></i></button>
|
|
372
|
-
<
|
|
386
|
+
<button class='btn2 mobile-link-button' id='mobile-link-button' data-tippy-content="enter url"><i class="fa-solid fa-link"></i></button>
|
|
387
|
+
<form class='urlbar'>
|
|
388
|
+
<div class='url-input-container'>
|
|
389
|
+
<input type='url' placeholder='enter a local url'>
|
|
390
|
+
<div class='url-dropdown' id='url-dropdown'></div>
|
|
391
|
+
</div>
|
|
392
|
+
</form>
|
|
373
393
|
<a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
|
|
374
394
|
<div><i class="fa-solid fa-table-columns"></i></div>
|
|
375
395
|
</a>
|
|
@@ -711,7 +731,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
711
731
|
})
|
|
712
732
|
})
|
|
713
733
|
}
|
|
714
|
-
document.querySelector("form").addEventListener("submit", async (e) => {
|
|
734
|
+
document.querySelector("main form").addEventListener("submit", async (e) => {
|
|
715
735
|
e.preventDefault()
|
|
716
736
|
e.stopPropagation()
|
|
717
737
|
let val = document.querySelector(`[name=home]`).value
|
package/server/views/setup.ejs
CHANGED
|
@@ -109,12 +109,14 @@ body {
|
|
|
109
109
|
.timestamp {
|
|
110
110
|
color: rgba(0,0,0,0.5);
|
|
111
111
|
}
|
|
112
|
+
/*
|
|
112
113
|
@media only screen and (max-width: 800px) {
|
|
113
114
|
body {
|
|
114
115
|
display: flex !important;
|
|
115
116
|
flex-direction: row !important;
|
|
116
117
|
}
|
|
117
118
|
}
|
|
119
|
+
*/
|
|
118
120
|
</style>
|
|
119
121
|
<script src="/hotkeys.min.js"></script>
|
|
120
122
|
<script src="/sweetalert2.js"></script>
|
package/server/views/tools.ejs
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<link href="/markdown.css" rel="stylesheet"/>
|
|
11
11
|
<link href="/noty.css" rel="stylesheet"/>
|
|
12
12
|
<link href="/style.css" rel="stylesheet"/>
|
|
13
|
+
<link href="/urldropdown.css" rel="stylesheet" />
|
|
13
14
|
<% if (agent === "electron") { %>
|
|
14
15
|
<link href="/electron.css" rel="stylesheet"/>
|
|
15
16
|
<% } %>
|
|
@@ -761,12 +762,14 @@ aside .selected {
|
|
|
761
762
|
}
|
|
762
763
|
}
|
|
763
764
|
|
|
765
|
+
/*
|
|
764
766
|
@media only screen and (max-width: 800px) {
|
|
765
767
|
body {
|
|
766
768
|
display: flex !important;
|
|
767
769
|
flex-direction: row !important;
|
|
768
770
|
}
|
|
769
771
|
}
|
|
772
|
+
*/
|
|
770
773
|
@media only screen and (max-width: 600px) {
|
|
771
774
|
aside {
|
|
772
775
|
width: unset;
|
|
@@ -802,6 +805,7 @@ aside .selected {
|
|
|
802
805
|
}
|
|
803
806
|
}
|
|
804
807
|
</style>
|
|
808
|
+
<script src="/window_storage.js"></script>
|
|
805
809
|
<script src="/popper.min.js"></script>
|
|
806
810
|
<script src="/tippy-bundle.umd.min.js"></script>
|
|
807
811
|
<script src="/hotkeys.min.js"></script>
|
|
@@ -817,6 +821,15 @@ aside .selected {
|
|
|
817
821
|
<script src="/common.js"></script>
|
|
818
822
|
<script src="/opener.js"></script>
|
|
819
823
|
<script src="/nav.js"></script>
|
|
824
|
+
<script src="/urldropdown.js"></script>
|
|
825
|
+
<script>
|
|
826
|
+
// Initialize URL Dropdown with empty behavior for tools page
|
|
827
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
828
|
+
initUrlDropdown({
|
|
829
|
+
clearBehavior: 'empty'
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
</script>
|
|
820
833
|
<script src="/report.js"></script>
|
|
821
834
|
</head>
|
|
822
835
|
<body class='<%=theme%>' data-agent="<%=agent%>">
|
|
@@ -828,11 +841,18 @@ aside .selected {
|
|
|
828
841
|
<header class='navheader grabbable'>
|
|
829
842
|
<h1>
|
|
830
843
|
<a class='home' href="/"><img class='icon' src="/pinokio-black.png"></a>
|
|
844
|
+
<button id='collapse' class='btn2' data-tippy-content="toggle fullscreen view"><i class="fa-solid fa-bars"></i></button>
|
|
831
845
|
<button class='btn2' id='back' data-tippy-content="back"><div><i class="fa-solid fa-chevron-left"></i></div></button>
|
|
832
846
|
<button class='btn2' id='forward' data-tippy-content="forward"><div><i class="fa-solid fa-chevron-right"></i></div></button>
|
|
833
847
|
<button class='btn2' id='refresh-page' data-tippy-content="refresh"><div><i class="fa-solid fa-rotate-right"></i></div></button>
|
|
834
848
|
<button class='btn2' id='screenshot' data-tippy-content="take a screenshot"><i class="fa-solid fa-camera"></i></button>
|
|
835
|
-
<
|
|
849
|
+
<button class='btn2 mobile-link-button' id='mobile-link-button' data-tippy-content="enter url"><i class="fa-solid fa-link"></i></button>
|
|
850
|
+
<form class='urlbar'>
|
|
851
|
+
<div class='url-input-container'>
|
|
852
|
+
<input type='url' placeholder='enter a local url'>
|
|
853
|
+
<div class='url-dropdown' id='url-dropdown'></div>
|
|
854
|
+
</div>
|
|
855
|
+
</form>
|
|
836
856
|
<a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
|
|
837
857
|
<div><i class="fa-solid fa-table-columns"></i></div>
|
|
838
858
|
</a>
|