@bivy/bivy 0.17.3-staging.14 → 0.17.3-staging.15
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/dist/apps/inspector.js +19 -28
- package/dist/server.js +6 -0
- package/package.json +1 -1
package/dist/apps/inspector.js
CHANGED
|
@@ -32,35 +32,20 @@ const selector=el=>{
|
|
|
32
32
|
}
|
|
33
33
|
return parts.join(' > ')||el.localName;
|
|
34
34
|
};
|
|
35
|
-
let box=null,
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
// A second listener, so stopping (which the shell does right after a pick)
|
|
42
|
-
// doesn't also drop the guard on the rest of the tap. The tap's click ends it.
|
|
43
|
-
const aftermath=e=>{swallow(e);if(e.type==='click')listen(false,aftermath);};
|
|
44
|
-
const listen=(on,handler=swallow)=>{
|
|
45
|
-
const method=on?addEventListener:removeEventListener;
|
|
46
|
-
if(handler===swallow){method('pointermove',hover,true);method('pointerup',pick,true);method('keydown',key,true);}
|
|
47
|
-
for(const type of SWALLOW)method(type,handler,true);
|
|
48
|
-
};
|
|
49
|
-
const stop=()=>{box?.remove();box=null;target=null;listen(false);};
|
|
35
|
+
let box=null,layer=null,onPicked=post,host=null;
|
|
36
|
+
// While pointing, a clear layer over the page takes every tap itself, so the
|
|
37
|
+
// app never sees one and no browser's event order matters (iOS sends no click
|
|
38
|
+
// to a window listener for most taps). The element is looked up beneath it.
|
|
39
|
+
const stop=()=>{box?.remove();layer?.remove();box=layer=null;removeEventListener('keydown',key,true);};
|
|
40
|
+
const under=e=>document.elementsFromPoint(e.clientX,e.clientY).find(el=>el!==layer&&el!==box&&el!==host);
|
|
50
41
|
const hover=e=>{
|
|
51
|
-
const el=
|
|
52
|
-
if(!el||el===box||el===host)return;target=el;const r=el.getBoundingClientRect();
|
|
42
|
+
const el=under(e);if(!el)return;const r=el.getBoundingClientRect();
|
|
53
43
|
Object.assign(box.style,{left:r.left+'px',top:r.top+'px',width:r.width+'px',height:r.height+'px'});
|
|
54
44
|
};
|
|
55
45
|
const pick=e=>{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const el=e.target instanceof Element?e.target:document.elementFromPoint(e.clientX,e.clientY)||target;
|
|
60
|
-
if(!el)return;stop();
|
|
61
|
-
// Keep eating the click (and iOS's delayed mouse events) this tap still fires.
|
|
62
|
-
listen(true,aftermath);setTimeout(()=>listen(false,aftermath),500);
|
|
63
|
-
if(el===host){onPicked({type:'picked',cancelled:true});return;}const r=el.getBoundingClientRect();
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
const el=under(e);if(!el)return;stop();
|
|
48
|
+
const r=el.getBoundingClientRect();
|
|
64
49
|
onPicked({type:'picked',selector:selector(el),tag:el.localName,text:(el.innerText||el.getAttribute('aria-label')||el.getAttribute('alt')||'').trim().replace(/\\s+/g,' ').slice(0,200),
|
|
65
50
|
rect:{x:Math.round(r.left),y:Math.round(r.top),width:Math.round(r.width),height:Math.round(r.height)},
|
|
66
51
|
viewport:{width:innerWidth,height:innerHeight},path:location.pathname+location.search+location.hash});
|
|
@@ -71,8 +56,13 @@ function startPointing(){
|
|
|
71
56
|
box=document.createElement('div');
|
|
72
57
|
box.setAttribute('aria-hidden','true');
|
|
73
58
|
Object.assign(box.style,{position:'fixed',zIndex:2147483647,pointerEvents:'none',outline:'2px solid Highlight',outlineOffset:'2px',borderRadius:'4px',transition:'all 60ms ease-out'});
|
|
74
|
-
|
|
75
|
-
|
|
59
|
+
// One below the reviewer dock, so its controls stay usable while pointing.
|
|
60
|
+
layer=document.createElement('div');
|
|
61
|
+
layer.setAttribute('aria-hidden','true');
|
|
62
|
+
Object.assign(layer.style,{position:'fixed',inset:0,zIndex:2147483646,cursor:'crosshair',background:'transparent',touchAction:'manipulation',userSelect:'none',webkitUserSelect:'none',webkitTouchCallout:'none'});
|
|
63
|
+
layer.addEventListener('pointermove',hover);layer.addEventListener('pointerdown',hover);layer.addEventListener('click',pick);
|
|
64
|
+
document.documentElement.append(layer,box);
|
|
65
|
+
addEventListener('keydown',key,true);
|
|
76
66
|
}
|
|
77
67
|
addEventListener('message',e=>{
|
|
78
68
|
if(!framed||e.origin!==SHELL||e.source!==parent||e.data?.type!=='bivy:point')return;
|
|
@@ -87,7 +77,8 @@ if(REVIEWER&&!framed){
|
|
|
87
77
|
+'button{border:1px solid ButtonBorder;background:ButtonFace;color:ButtonText;border-radius:999px;padding:10px 14px;font-weight:600;cursor:pointer;min-height:44px}'
|
|
88
78
|
+'.primary{background:CanvasText;color:Canvas;border-color:CanvasText}'
|
|
89
79
|
+'form{width:min(340px,calc(100vw - 24px));background:Canvas;color:CanvasText;border:1px solid GrayText;border-radius:14px;padding:12px;box-shadow:0 8px 30px rgb(0 0 0/.25)}'
|
|
90
|
-
|
|
80
|
+
// 16px: smaller, and iOS zooms the page in when the note box is focused.
|
|
81
|
+
+'textarea{width:100%;min-height:5em;margin:8px 0;border:1px solid GrayText;border-radius:8px;padding:8px;background:Canvas;color:CanvasText;resize:vertical;font-size:16px}'
|
|
91
82
|
+'.row{display:flex;justify-content:flex-end;gap:8px}.muted{color:GrayText;font-size:12px;overflow-wrap:anywhere}[hidden]{display:none!important}</style>'
|
|
92
83
|
+'<div class="dock"><p class="muted" role="status" id="status" hidden></p>'
|
|
93
84
|
+'<form id="form" hidden><label for="note">Your note</label><div class="muted" id="about"></div><textarea id="note" required maxlength="1000"></textarea>'
|
package/dist/server.js
CHANGED
|
@@ -1987,6 +1987,12 @@ const appService = new AppService(appRegistry, appGateway ?? remotePreview, {
|
|
|
1987
1987
|
has: (id) => terminals.has(id),
|
|
1988
1988
|
close: (id) => { terminals.close(id); },
|
|
1989
1989
|
}, { screenshots: { enabled: appScreenshotsEnabled }, displays: appDisplays });
|
|
1990
|
+
// A reviewer's note shows up in an open Apps sheet without reopening it.
|
|
1991
|
+
appRegistry.on("notes", (viewId) => {
|
|
1992
|
+
const entry = appRegistry.getView(viewId);
|
|
1993
|
+
if (entry)
|
|
1994
|
+
broadcast({ type: "apps.changed", sessionId: entry.app.sessionId });
|
|
1995
|
+
});
|
|
1990
1996
|
const RELAY_COMMANDS = {
|
|
1991
1997
|
...createAppCommands(appService, (id) => { const record = resolveSession(id); return record ? harnessDirFor(record) : undefined; }, (app) => {
|
|
1992
1998
|
const record = resolveSession(app.sessionId);
|
package/package.json
CHANGED