Skip to content

Commit fabe2bd

Browse files
committed
feat(editor): report layout diagnostics through the editor-state API
- A black editor area could be Monaco holding a stale size or the pane itself being short, and the desktop window has no developer tools to tell them apart - The browser now sends Monaco's believed size, the container and pane sizes, the window size and the state of the once-a-second layout check along with the editor state, and GET /api/editor-state returns them untouched, so a live window can be inspected from outside while the symptom is on screen
1 parent 02ca3ff commit fabe2bd

3 files changed

Lines changed: 38 additions & 3 deletions

File tree

api/editor_state.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ type EditorState struct {
4343
Cursor *CursorPosition `json:"cursor,omitempty"`
4444
Selection *SelectionRange `json:"selection,omitempty"`
4545
Viewport *Viewport `json:"viewport,omitempty"`
46+
// Layout は描画の診断値。ブラウザが組み立てたものをそのまま返す。
47+
// サーバは中身を解釈しない (見たい項目は再現のたびに変わる)。
48+
Layout json.RawMessage `json:"layout,omitempty"`
4649
}
4750

4851
// editorStateCache は最新の EditorState とその受信時刻を保持する。
@@ -106,6 +109,9 @@ func (h *Handler) handleEditorState(w http.ResponseWriter, r *http.Request) {
106109
if state.Viewport != nil {
107110
resp["viewport"] = state.Viewport
108111
}
112+
if len(state.Layout) > 0 {
113+
resp["layout"] = state.Layout
114+
}
109115
jsonOK(w, resp)
110116
case http.MethodPut:
111117
var req EditorState

static/js/editor-state-sync.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,26 @@
5454
};
5555
}
5656
if (viewport) state.viewport = viewport;
57+
// 描画の診断。黒い領域が Monaco の認識ずれか、ペインの高さの問題かは、
58+
// これらの数字を並べないと決められない
59+
try {
60+
const li = monacoEditor.getLayoutInfo();
61+
const mc = document.getElementById('monaco-container');
62+
const pb = document.getElementById('peek-body');
63+
const pk = document.getElementById('peek');
64+
const pr = document.getElementById('pane-right');
65+
state.layout = {
66+
monaco: [li.width, li.height],
67+
container: mc ? [mc.clientWidth, mc.clientHeight] : null,
68+
peek_body: pb ? pb.clientHeight : null,
69+
peek: pk ? [pk.clientHeight, pk.style.height || ''] : null,
70+
pane_right: pr ? pr.clientHeight : null,
71+
window: [window.innerWidth, window.innerHeight, window.devicePixelRatio],
72+
hidden: document.hidden,
73+
resizing: (typeof peekResizing !== 'undefined') ? peekResizing : null,
74+
watch: window._layoutWatch || null,
75+
};
76+
} catch (_) {}
5777
return state;
5878
}
5979

static/js/editor.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,18 +1099,27 @@ async function ensureEditor() {
10991099
// 認識している大きさとコンテナの実寸を毎秒比べ、ずれていれば取り直す。
11001100
// 読むのは値 2 つで、ずれていない限り layout() は呼ばない。
11011101
let driftStreak = 0, driftKey = '';
1102+
// 外から読むための内部状態。デスクトップ窓には開発者ツールが無いので、
1103+
// 再現時に何が起きているかは /api/editor-state 経由でしか見られない
1104+
window._layoutWatch = { ticks: 0, skipped: '', streak: 0, recovered: 0, last: '' };
11021105
setInterval(() => {
1103-
if (!monacoEditor || document.hidden || peekResizing) return;
1106+
const lw = window._layoutWatch;
1107+
lw.ticks++;
1108+
lw.skipped = !monacoEditor ? 'no-editor' : document.hidden ? 'hidden' : peekResizing ? 'resizing' : '';
1109+
if (lw.skipped) return;
11041110
const el = id('monaco-container');
1105-
if (!el || !el.offsetParent) return; // エディタを閉じているとき
1111+
if (!el || !el.offsetParent) { lw.skipped = 'closed'; return; } // エディタを閉じているとき
11061112
const w = el.clientWidth, h = el.clientHeight;
1107-
if (!layoutDrifted(w, h, monacoEditor.getLayoutInfo())) { driftStreak = 0; return; }
1113+
if (!layoutDrifted(w, h, monacoEditor.getLayoutInfo())) { driftStreak = 0; lw.streak = 0; return; }
11081114
// 同じ実寸で 3 回直しても合わないなら、そのサイズでは諦める(毎秒描き直しの連打を防ぐ)
11091115
const key = w + 'x' + h;
11101116
if (key !== driftKey) { driftKey = key; driftStreak = 0; }
1117+
lw.streak = driftStreak + 1;
11111118
if (++driftStreak > 3) return;
11121119
const before = monacoEditor.getLayoutInfo();
11131120
relayout();
1121+
lw.recovered++;
1122+
lw.last = before.width + 'x' + before.height + '->' + w + 'x' + h;
11141123
// 効いたことを見えるようにする。「保険が動いたのに直らない」と「動いていない」は
11151124
// 原因が別で、画面からは区別できない
11161125
st('エディタの描画を復旧しました (' + before.width + 'x' + before.height + ' → ' + w + 'x' + h + ')');

0 commit comments

Comments
 (0)