pinokiod 7.5.39 → 7.5.40
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/package.json +1 -1
- package/server/views/app.ejs +19 -0
- package/test/launch-settings-ui.test.js +79 -0
package/package.json
CHANGED
package/server/views/app.ejs
CHANGED
|
@@ -16183,10 +16183,20 @@ const rerenderMenuSection = (container, html) => {
|
|
|
16183
16183
|
}
|
|
16184
16184
|
|
|
16185
16185
|
const desktopPeekMq = window.matchMedia("(min-width: 769px) and (hover: hover) and (pointer: fine)")
|
|
16186
|
+
const shouldAutoPeekOnIdle = <%- JSON.stringify(type === "run") %>
|
|
16186
16187
|
let peekCloseTimer = 0
|
|
16187
16188
|
|
|
16188
16189
|
const isCollapsed = () => appcanvas.classList.contains("sidebar-collapsed")
|
|
16189
16190
|
const isPeeking = () => appcanvas.classList.contains("sidebar-peeking")
|
|
16191
|
+
const hasVisibleBrowserSurface = () => {
|
|
16192
|
+
const browserview = document.querySelector("main.browserview")
|
|
16193
|
+
if (!browserview) return false
|
|
16194
|
+
if (browserview.querySelector("iframe:not(.hidden)")) return true
|
|
16195
|
+
const networkStatus = document.getElementById("browserview-network-status")
|
|
16196
|
+
if (networkStatus && !networkStatus.hidden) return true
|
|
16197
|
+
const launchStatus = document.querySelector("[data-launch-requirements-status]")
|
|
16198
|
+
return Boolean(launchStatus && !launchStatus.hidden)
|
|
16199
|
+
}
|
|
16190
16200
|
const syncSidebarVisibility = () => {
|
|
16191
16201
|
const peeking = isPeeking()
|
|
16192
16202
|
aside.setAttribute("aria-hidden", isCollapsed() && !peeking ? "true" : "false")
|
|
@@ -16243,6 +16253,11 @@ const rerenderMenuSection = (container, html) => {
|
|
|
16243
16253
|
setCollapsed(initialCollapsed, { persist: false })
|
|
16244
16254
|
requestAnimationFrame(() => {
|
|
16245
16255
|
appcanvas.classList.add("sidebar-motion-ready")
|
|
16256
|
+
requestAnimationFrame(() => {
|
|
16257
|
+
if (shouldAutoPeekOnIdle && initialCollapsed && !hasVisibleBrowserSurface()) {
|
|
16258
|
+
setPeeking(true)
|
|
16259
|
+
}
|
|
16260
|
+
})
|
|
16246
16261
|
})
|
|
16247
16262
|
|
|
16248
16263
|
toggle.addEventListener("click", (event) => {
|
|
@@ -16268,6 +16283,10 @@ const rerenderMenuSection = (container, html) => {
|
|
|
16268
16283
|
})
|
|
16269
16284
|
aside.addEventListener("pointerleave", closePeekSoon)
|
|
16270
16285
|
aside.addEventListener("focusout", closePeekSoon)
|
|
16286
|
+
aside.addEventListener("click", () => {
|
|
16287
|
+
if (!isPeeking()) return
|
|
16288
|
+
window.setTimeout(() => setPeeking(false), 0)
|
|
16289
|
+
})
|
|
16271
16290
|
document.addEventListener("pointerdown", (event) => {
|
|
16272
16291
|
if (!isPeeking()) return
|
|
16273
16292
|
const target = event.target
|
|
@@ -3,6 +3,7 @@ const fs = require("node:fs/promises")
|
|
|
3
3
|
const path = require("node:path")
|
|
4
4
|
const test = require("node:test")
|
|
5
5
|
const ejs = require("ejs")
|
|
6
|
+
const { JSDOM } = require("jsdom")
|
|
6
7
|
|
|
7
8
|
const root = path.resolve(__dirname, "..")
|
|
8
9
|
|
|
@@ -458,6 +459,84 @@ test("static guard: open without launching disables page-load script frame selec
|
|
|
458
459
|
assert.match(appView, /if \(!target && !automaticSelectionDisabled && preselected && preselected !== devTab\)/)
|
|
459
460
|
})
|
|
460
461
|
|
|
462
|
+
test("static guard: collapsed idle run page peeks without persisting sidebar state", async () => {
|
|
463
|
+
const appView = await fs.readFile(path.resolve(root, "server/views/app.ejs"), "utf8")
|
|
464
|
+
|
|
465
|
+
assert.match(appView, /const shouldAutoPeekOnIdle = <%- JSON\.stringify\(type === "run"\) %>/)
|
|
466
|
+
assert.match(appView, /const hasVisibleBrowserSurface = \(\) => \{[\s\S]*browserview\.querySelector\("iframe:not\(\.hidden\)"\)[\s\S]*browserview-network-status[\s\S]*data-launch-requirements-status/)
|
|
467
|
+
assert.match(appView, /if \(shouldAutoPeekOnIdle && initialCollapsed && !hasVisibleBrowserSurface\(\)\) \{[\s\S]*setPeeking\(true\)/)
|
|
468
|
+
assert.match(appView, /setCollapsed\(initialCollapsed, \{ persist: false \}\)/)
|
|
469
|
+
assert.match(appView, /aside\.addEventListener\("click", \(\) => \{[\s\S]*window\.setTimeout\(\(\) => setPeeking\(false\), 0\)/)
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
test("app sidebar auto-peeks on collapsed idle run page and dismisses after click", async () => {
|
|
473
|
+
const appView = await fs.readFile(path.resolve(root, "server/views/app.ejs"), "utf8")
|
|
474
|
+
const start = appView.indexOf('<script>\n(() => {\n const appcanvas = document.querySelector(".appcanvas")')
|
|
475
|
+
const end = appView.indexOf('</script>\n<script src="/tab-idle-notifier.js"></script>', start)
|
|
476
|
+
assert.notEqual(start, -1)
|
|
477
|
+
assert.notEqual(end, -1)
|
|
478
|
+
|
|
479
|
+
const sidebarScript = appView
|
|
480
|
+
.slice(start + "<script>\n".length, end)
|
|
481
|
+
.replace(/<%- JSON\.stringify\(typeof name === "string" \? name : ""\) %>/g, '"test-app"')
|
|
482
|
+
.replace(/<%- JSON\.stringify\(type === "run"\) %>/g, "true")
|
|
483
|
+
|
|
484
|
+
const createDom = (browserSurface = "") => {
|
|
485
|
+
return new JSDOM(`<!doctype html>
|
|
486
|
+
<button id="sidebar-toggle"></button>
|
|
487
|
+
<div class="appcanvas vertical">
|
|
488
|
+
<button type="button" data-app-sidebar-peek-trigger></button>
|
|
489
|
+
<aside id="app-sidebar"><button type="button" id="sidebar-action">Start</button></aside>
|
|
490
|
+
<main class="browserview">${browserSurface}</main>
|
|
491
|
+
</div>
|
|
492
|
+
<div id="browserview-network-status" hidden></div>
|
|
493
|
+
<div data-launch-requirements-status hidden></div>`, {
|
|
494
|
+
url: "http://127.0.0.1:42000/v/test-app",
|
|
495
|
+
runScripts: "outside-only",
|
|
496
|
+
pretendToBeVisual: true,
|
|
497
|
+
beforeParse(window) {
|
|
498
|
+
window.matchMedia = () => ({
|
|
499
|
+
matches: true,
|
|
500
|
+
addEventListener() {},
|
|
501
|
+
removeEventListener() {}
|
|
502
|
+
})
|
|
503
|
+
}
|
|
504
|
+
})
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const wait = (ms = 75) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
508
|
+
const storageKey = "pinokio.sidebar-collapsed:test-app"
|
|
509
|
+
|
|
510
|
+
const dom = createDom()
|
|
511
|
+
dom.window.localStorage.setItem(storageKey, "1")
|
|
512
|
+
dom.window.eval(sidebarScript)
|
|
513
|
+
await wait()
|
|
514
|
+
|
|
515
|
+
const appcanvas = dom.window.document.querySelector(".appcanvas")
|
|
516
|
+
const aside = dom.window.document.getElementById("app-sidebar")
|
|
517
|
+
assert.equal(appcanvas.classList.contains("sidebar-collapsed"), true)
|
|
518
|
+
assert.equal(appcanvas.classList.contains("sidebar-peeking"), true)
|
|
519
|
+
assert.equal(aside.getAttribute("aria-hidden"), "false")
|
|
520
|
+
assert.equal(dom.window.localStorage.getItem(storageKey), "1")
|
|
521
|
+
|
|
522
|
+
aside.querySelector("#sidebar-action").dispatchEvent(new dom.window.MouseEvent("click", { bubbles: true }))
|
|
523
|
+
await wait(5)
|
|
524
|
+
|
|
525
|
+
assert.equal(appcanvas.classList.contains("sidebar-collapsed"), true)
|
|
526
|
+
assert.equal(appcanvas.classList.contains("sidebar-peeking"), false)
|
|
527
|
+
assert.equal(dom.window.localStorage.getItem(storageKey), "1")
|
|
528
|
+
|
|
529
|
+
const activeDom = createDom('<iframe src="about:blank"></iframe>')
|
|
530
|
+
activeDom.window.localStorage.setItem(storageKey, "1")
|
|
531
|
+
activeDom.window.eval(sidebarScript)
|
|
532
|
+
await wait()
|
|
533
|
+
|
|
534
|
+
const activeCanvas = activeDom.window.document.querySelector(".appcanvas")
|
|
535
|
+
assert.equal(activeCanvas.classList.contains("sidebar-collapsed"), true)
|
|
536
|
+
assert.equal(activeCanvas.classList.contains("sidebar-peeking"), false)
|
|
537
|
+
assert.equal(activeDom.window.localStorage.getItem(storageKey), "1")
|
|
538
|
+
})
|
|
539
|
+
|
|
461
540
|
test("static guard: home run command selection opens without launching before selecting command", async () => {
|
|
462
541
|
const homeRunMenu = await fs.readFile(path.resolve(root, "server/views/partials/home_run_menu.ejs"), "utf8")
|
|
463
542
|
|