json-joy
Version:
Collection of libraries for building collaborative editing apps.
145 lines (144 loc) • 7.78 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RenderCaret = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const nano_theme_1 = require("nano-theme");
const useWindowSize_1 = tslib_1.__importDefault(require("react-use/lib/useWindowSize"));
const useWindowScroll_1 = tslib_1.__importDefault(require("react-use/lib/useWindowScroll"));
const context_1 = require("../context");
const constants_1 = require("../../../../json-crdt-extensions/peritext/rga/constants");
const hooks_1 = require("../../../web/react/hooks");
const CharOverlay_1 = require("./CharOverlay");
const blockClass = (0, nano_theme_1.rule)({
pos: 'relative',
pe: 'none',
us: 'none',
w: '0px',
h: '100%',
va: 'bottom',
});
const RenderCaret = (props) => {
const { children } = props;
const ctx = (0, context_1.useDebugCtx)();
const enabled = (0, hooks_1.useSyncStore)(ctx.state.enabled);
if (!enabled || !ctx.ctx?.dom)
return children;
return React.createElement(RenderDebugCaret, { ...props });
};
exports.RenderCaret = RenderCaret;
const RenderDebugCaret = (props) => {
return (React.createElement("span", { className: blockClass },
props.children,
React.createElement(DebugOverlay, { ...props })));
};
const characterOverlayStyles = {
position: 'fixed',
display: 'inline-block',
visibility: 'hidden',
backgroundColor: 'rgba(0, 0, 255, 0.1)',
outline: '1px dashed blue',
};
const eolCharacterOverlayStyles = {
...characterOverlayStyles,
outline: '1px dotted blue',
};
const eowCharacterOverlayStyles = {
...characterOverlayStyles,
backgroundColor: 'rgba(127,127,127,.1)',
outline: '0',
};
const DebugOverlay = ({ point }) => {
(0, useWindowSize_1.default)();
(0, useWindowScroll_1.default)();
const { ctx, state } = (0, context_1.useDebugCtx)();
const showCursorInfo = (0, hooks_1.useSyncStore)(state.showCursorInfo);
const leftCharRef = React.useRef(null);
const rightCharRef = React.useRef(null);
const leftLineEndCharRef = React.useRef(null);
const rightLineEndCharRef = React.useRef(null);
const leftPrevLineEndCharRef = React.useRef(null);
const rightPrevLineEndCharRef = React.useRef(null);
const leftNextLineEndCharRef = React.useRef(null);
const rightNextLineEndCharRef = React.useRef(null);
const wordSkipLeftCharRef = React.useRef(null);
const wordSkipRightCharRef = React.useRef(null);
const prevLineCaretRef = React.useRef(null);
const nextLineCaretRef = React.useRef(null);
const anchorLeft = point.anchor === constants_1.Anchor.After;
React.useEffect(() => {
leftCharRef.current?.(ctx.events.ui?.getPointRect(point, false));
rightCharRef.current?.(ctx.events.ui?.getPointRect(point, true));
const lineInfo = ctx.events.ui?.getLineInfo(point);
leftLineEndCharRef.current?.(lineInfo?.[0][1]);
rightLineEndCharRef.current?.(lineInfo?.[1][1]);
if (lineInfo) {
const prevLineInfo = ctx.events.ui?.getNextLineInfo(lineInfo, -1);
const nextLineInfo = ctx.events.ui?.getNextLineInfo(lineInfo);
leftPrevLineEndCharRef.current?.(prevLineInfo?.[0][1]);
rightPrevLineEndCharRef.current?.(prevLineInfo?.[1][1]);
leftNextLineEndCharRef.current?.(nextLineInfo?.[0][1]);
rightNextLineEndCharRef.current?.(nextLineInfo?.[1][1]);
}
const wordJumpLeftPoint = ctx.peritext.editor.skip(point, -1, 'word');
if (wordJumpLeftPoint)
wordSkipLeftCharRef.current?.(ctx.events.ui?.getPointRect?.(wordJumpLeftPoint, true));
const wordJumpRightPoint = ctx.peritext.editor.skip(point, 1, 'word');
if (wordJumpRightPoint)
wordSkipRightCharRef.current?.(ctx.events.ui?.getPointRect?.(wordJumpRightPoint, false));
const pos = ctx.events.ui?.pointX(point);
const currLine = ctx.events.ui?.getLineInfo(point);
if (pos && currLine) {
const targetX = pos[0];
const prevLine = ctx.events.ui?.getNextLineInfo(currLine, -1);
const nextLine = ctx.events.ui?.getNextLineInfo(currLine);
if (prevLine) {
const prevLinePoint = ctx.events.ui?.findPointAtX(targetX, prevLine);
if (point.anchor === constants_1.Anchor.Before)
prevLinePoint?.refBefore();
else
prevLinePoint?.refAfter();
if (prevLinePoint) {
const rect = ctx.events.ui?.api.getCharRect?.(prevLinePoint.id);
if (rect)
prevLineCaretRef.current?.(rect);
}
}
if (nextLine) {
const prevLinePoint = ctx.events.ui?.findPointAtX(targetX, nextLine);
if (point.anchor === constants_1.Anchor.Before)
prevLinePoint?.refBefore();
else
prevLinePoint?.refAfter();
if (prevLinePoint) {
const rect = ctx.events.ui?.api.getCharRect?.(prevLinePoint.id);
if (rect)
nextLineCaretRef.current?.(rect);
}
}
}
});
if (!showCursorInfo)
return null;
return (React.createElement(React.Fragment, null,
React.createElement(CharOverlay_1.CharOverlay, { rectRef: leftCharRef, style: {
...characterOverlayStyles,
backgroundColor: anchorLeft ? 'rgba(0,0,255,.2)' : 'rgba(0,0,255,.1)',
outlineStyle: anchorLeft ? 'solid' : 'dashed',
} }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: rightCharRef, style: {
...characterOverlayStyles,
backgroundColor: !anchorLeft ? 'rgba(0,0,255,.2)' : 'rgba(0,0,255,.1)',
outlineStyle: !anchorLeft ? 'solid' : 'dashed',
} }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: leftLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid blue' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: rightLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid blue' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: leftPrevLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid rgba(127,127,127,.5)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: rightPrevLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid rgba(127,127,127,.5)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: leftNextLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid rgba(127,127,127,.5)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: rightNextLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid rgba(127,127,127,.5)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: wordSkipLeftCharRef, style: { ...eowCharacterOverlayStyles, borderLeft: '2px dotted rgba(127,127,127,.7)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: wordSkipRightCharRef, style: { ...eowCharacterOverlayStyles, borderRight: '2px dotted rgba(127,127,127,.7)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: prevLineCaretRef, style: { ...eowCharacterOverlayStyles, backgroundColor: 'rgba(127,127,127,.2)' } }),
React.createElement(CharOverlay_1.CharOverlay, { rectRef: nextLineCaretRef, style: { ...eowCharacterOverlayStyles, backgroundColor: 'rgba(127,127,127,.2)' } })));
};