UNPKG

@launchmenu/core

Version:

An environment for visual keyboard controlled applets

137 lines 13.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SyntaxHighlighterSelection = exports.measureText = void 0; const react_1 = __importStar(require("react")); const Box_1 = require("../../../styling/box/Box"); const FillBox_1 = require("../../FillBox"); const getFrameSize_1 = require("./getFrameSize"); const useIOContext_1 = require("../../../context/react/useIOContext"); const baseSettings_1 = require("../../../application/settings/baseSettings/baseSettings"); const model_react_1 = require("model-react"); /** * Retrieves the pixel size of the text * @param element The element to get the text from, assumes characters are individually separated * @param end The end of the range to measure * @returns The number of pixels */ function measureText(element, end) { var _a, _b; const children = element.children; const { left, right } = getFrameSize_1.getFrameSize(element); const contentLength = ((_a = element.textContent) === null || _a === void 0 ? void 0 : _a.length) || 0; if (contentLength <= end) { return element.getBoundingClientRect().width - (contentLength == end ? right : 0); } else { let out = left; for (let child of children) { if (end <= 0) break; out += measureText(child, end); end -= ((_b = child.textContent) === null || _b === void 0 ? void 0 : _b.length) || 0; } return out; } } exports.measureText = measureText; /** * Renders a cursor and selection at the right place in the passed child element. * Assumes all characters are in a separate elements. */ const SyntaxHighlighterSelection = ({ selection, getPixelSelection, children, ...rest }) => { var _a, _b, _c, _d, _e; const [syntaxEl, setSyntaxEl] = react_1.useState(null); // Perform selection measurement const [selectionPixelRange, setSelectionPixelRange] = react_1.useState(undefined); react_1.useEffect(() => { setSelectionPixelRange(r => { let range; if (!syntaxEl) { range = undefined; } else { const start = measureText(syntaxEl, selection.start); const end = selection.start != selection.end ? measureText(syntaxEl, selection.end) : undefined; range = { start, end }; } if (getPixelSelection) getPixelSelection(range); return range; }); }, [selection.start, selection.end, syntaxEl]); // Cursor blinking const cursorVisible = useCursorBlink(selection); // Selection and measurement rendering const cursorPos = (_a = selectionPixelRange === null || selectionPixelRange === void 0 ? void 0 : selectionPixelRange.end) !== null && _a !== void 0 ? _a : selectionPixelRange === null || selectionPixelRange === void 0 ? void 0 : selectionPixelRange.start; const selectionLeft = Math.min((_b = selectionPixelRange === null || selectionPixelRange === void 0 ? void 0 : selectionPixelRange.start) !== null && _b !== void 0 ? _b : 0, (_c = selectionPixelRange === null || selectionPixelRange === void 0 ? void 0 : selectionPixelRange.end) !== null && _c !== void 0 ? _c : 0); const selectionRight = Math.max((_d = selectionPixelRange === null || selectionPixelRange === void 0 ? void 0 : selectionPixelRange.start) !== null && _d !== void 0 ? _d : 0, (_e = selectionPixelRange === null || selectionPixelRange === void 0 ? void 0 : selectionPixelRange.end) !== null && _e !== void 0 ? _e : 0); return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(Box_1.Box, Object.assign({ className: "syntax", display: "inline-block" }, rest, { elRef: setSyntaxEl }), children), react_1.default.createElement(FillBox_1.FillBox, { pointerEvents: "none", className: "selectionHandler" }, cursorPos != undefined && cursorVisible && (react_1.default.createElement(Box_1.Box, { className: "cursor", position: "absolute", top: "none", bottom: "none", css: { left: cursorPos } })), selectionPixelRange && selectionPixelRange.end != undefined && (react_1.default.createElement(Box_1.Box, { className: "selection", position: "absolute", top: "none", bottom: "none", width: selectionRight - selectionLeft, css: { left: selectionLeft } }))))); }; exports.SyntaxHighlighterSelection = SyntaxHighlighterSelection; // TODO: replace by some css animation magic for better performance const useCursorBlink = (selection) => { var _a, _b, _c; const ioContext = useIOContext_1.useIOContext(); const [h] = model_react_1.useDataHook(); const settings = ioContext === null || ioContext === void 0 ? void 0 : ioContext.settings.get(baseSettings_1.baseSettings).field; const blinkDelay = (_a = settings === null || settings === void 0 ? void 0 : settings.blinkDelay.get(h)) !== null && _a !== void 0 ? _a : 100; const blinkOnTime = (_b = settings === null || settings === void 0 ? void 0 : settings.blinkSpeed.onTime.get(h)) !== null && _b !== void 0 ? _b : 1000; const blinkOffTime = (_c = settings === null || settings === void 0 ? void 0 : settings.blinkSpeed.offTime.get(h)) !== null && _c !== void 0 ? _c : 1000; const [blinking, setBlinking] = react_1.useState(false); const [cursorVisible, setCursorVisible] = react_1.useState(true); react_1.useEffect(() => { setBlinking(false); const ID = setTimeout(() => { setBlinking(true); }, blinkDelay); return () => clearTimeout(ID); }, [blinkDelay, selection.start, selection.end]); react_1.useEffect(() => { if (!blinking) { setCursorVisible(true); } else { let destroyed = false; const blink = () => { setCursorVisible(false); setTimeout(() => { if (!destroyed) setCursorVisible(true); }, blinkOffTime); }; const ID = setInterval(blink, blinkOnTime + blinkOffTime); blink(); return () => { destroyed = true; clearInterval(ID); }; } }, [blinking]); return cursorVisible; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3ludGF4SGlnaGxpZ2h0ZXJTZWxlY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9maWVsZHMvc3ludGF4RmllbGQvU3ludGF4SGlnaGxpZ2h0ZXJTZWxlY3Rpb24udHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBcUQ7QUFFckQsa0RBQTZDO0FBQzdDLDJDQUFzQztBQUN0QyxpREFBNEM7QUFDNUMsc0VBQWlFO0FBQ2pFLDBGQUFxRjtBQUVyRiw2Q0FBd0M7QUFFeEM7Ozs7O0dBS0c7QUFDSCxTQUFnQixXQUFXLENBQUMsT0FBZ0IsRUFBRSxHQUFXOztJQUNyRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBQ2xDLE1BQU0sRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDLEdBQUcsMkJBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUU1QyxNQUFNLGFBQWEsR0FBRyxPQUFBLE9BQU8sQ0FBQyxXQUFXLDBDQUFFLE1BQU0sS0FBSSxDQUFDLENBQUM7SUFDdkQsSUFBSSxhQUFhLElBQUksR0FBRyxFQUFFO1FBQ3RCLE9BQU8sT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUMsS0FBSyxHQUFHLENBQUMsYUFBYSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNyRjtTQUFNO1FBQ0gsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDO1FBQ2YsS0FBSyxJQUFJLEtBQUssSUFBSSxRQUFRLEVBQUU7WUFDeEIsSUFBSSxHQUFHLElBQUksQ0FBQztnQkFBRSxNQUFNO1lBQ3BCLEdBQUcsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLEdBQUcsSUFBSSxPQUFBLEtBQUssQ0FBQyxXQUFXLDBDQUFFLE1BQU0sS0FBSSxDQUFDLENBQUM7U0FD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