Skip to content

FIND_MONACO fails when a stale detached .pine-editor-monaco node precedes the live editor (querySelector picks the dead node) #333

Description

@rretsiem

Bug

pine_set_source, pine_open, pine_get_source etc. fail with "Could not open Pine Editor." even though the Pine Editor panel is open and Monaco is rendered.

Related to the symptom in PR #97, but a distinct root cause that PR #97 does not cover: its fast path needs window.monaco, which is undefined in my TV Desktop build (macOS, checked via ui_evaluate), and its fiber-walk fallback still uses single-node querySelector.

Root cause

The page can contain two .monaco-editor.pine-editor-monaco nodes — a stale detached one (left over from a previous editor mount, e.g. after opening a read-only community script or re-docking the panel) plus the live one. FIND_MONACO uses document.querySelector, which returns the first (dead) node. That node has no __reactFiber$ key anywhere in its ancestor chain, so the finder returns null and every editor op errors.

Diagnostic from my session (via ui_evaluate):

{"exact_match":true,"monaco_count":2,
 "classes":["monaco-editor pine-editor-monaco",
             "monaco-editor pine-editor-monaco no-user-select mac standalone showUnused showDeprecated vs-dark focused"]}
{"found":"node1 depth11","path":["node0: no fiber","node1: fiber ok, monacoEnv FOUND"],"winMonaco":false}

Fix

Iterate all matches instead of taking the first:

const FIND_MONACO = `
  (function findMonacoEditor() {
    // Stale detached editor nodes can precede the live one, so try every match
    var containers = document.querySelectorAll('.monaco-editor.pine-editor-monaco');
    for (var c = 0; c < containers.length; c++) {
      var el = containers[c];
      var fiberKey;
      for (var i = 0; i < 20; i++) {
        if (!el) break;
        fiberKey = Object.keys(el).find(function(k) { return k.startsWith('__reactFiber$'); });
        if (fiberKey) break;
        el = el.parentElement;
      }
      if (!fiberKey) continue;
      var current = el[fiberKey];
      for (var d = 0; d < 15; d++) {
        if (!current) break;
        if (current.memoizedProps && current.memoizedProps.value && current.memoizedProps.value.monacoEnv) {
          var env = current.memoizedProps.value.monacoEnv;
          if (env.editor && typeof env.editor.getEditors === 'function') {
            var editors = env.editor.getEditors();
            if (editors.length > 0) return { editor: editors[0], env: env };
          }
        }
        current = current.return;
      }
    }
    return null;
  })()
`;

Running this patch locally since; all editor ops work reliably, including 100KB+ pine_set_source payloads. The same multi-node loop would also make PR #97's fallback path robust. Happy to send a PR if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions