~glacambre/firenvim

ref: 1317fa8380df811a0a97ff9f805b5e523b7a37cd firenvim/src/content.ts -rw-r--r-- 2.2 KiB
1317fa83glacambre Add build instructions to README.md, add LICENSE.md 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { computeSelector } from "./CSSUtils";

browser.runtime.onMessage.addListener(async (request: any, sender: any, sendResponse: any) => {
    if (!functions[request.function]) {
        throw new Error(`Error: unhandled content request: ${request.toString()}.`);
    }
    return functions[request.function](...(request.args || []));
});

let lastEditorLocation = ["", ""];

function nvimify(evt: FocusEvent) {
    const elem = evt.target as HTMLElement;
    const rect = elem.getBoundingClientRect();
    const iframe = elem.ownerDocument
        .createElementNS("http://www.w3.org/1999/xhtml", "iframe") as HTMLIFrameElement;
    iframe.style.height = `${rect.height}px`;
    iframe.style.left = `${rect.left + window.scrollX}px`;
    iframe.style.position = "absolute";
    iframe.style.top = `${rect.top + window.scrollY}px`;
    iframe.style.width = `${rect.width}px`;
    iframe.src = (browser as any).extension.getURL("/NeovimFrame.html");
    const span = iframe.ownerDocument
        .createElementNS("http://www.w3.org/1999/xhtml", "span") as HTMLSpanElement;
    span.attachShadow({ mode: "closed" }).appendChild(iframe);
    elem.ownerDocument.body.appendChild(span);
    iframe.focus();
    lastEditorLocation = [document.location.href, computeSelector(evt.target as HTMLElement)];
}

function isEditable(elem: HTMLElement) {
    return elem.tagName === "TEXTAREA"
        || (elem.tagName === "INPUT" && (elem as HTMLInputElement).type === "text");
}

const functions: any = {
    getEditorLocation: () => lastEditorLocation,
    setElementContent: (selector: string, text: string) => {
        const e = document.querySelector(selector) as any;
        if (e.value) {
            e.value = text;
        } else {
            e.innerText = text;
        }
    },
};

(new MutationObserver(changes => {
    changes
        .filter((change: MutationRecord) => change.addedNodes.length > 0)
        .forEach((change: MutationRecord) => {
            Array.from(change.addedNodes)
                .filter(node => isEditable(node as HTMLElement))
                .forEach(node => node.addEventListener("focus", nvimify));
        });
})).observe(window.document, { subtree: true, childList: true });