Skip to content

Commit

Permalink
✨ feat(ContentScript): 实现编辑单词
Browse files Browse the repository at this point in the history
  • Loading branch information
couriourc committed Apr 23, 2024
1 parent d8f9c90 commit fc95efa
Show file tree
Hide file tree
Showing 6 changed files with 6,469 additions and 7,968 deletions.
Binary file modified docs/snapshot/thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/snapshot/translating.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 51 additions & 35 deletions entrypoints/content.tsx → entrypoints/content/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {ReactNode, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react';
import React, {ReactNode, useEffect, useMemo, useRef, useState} from 'react';
import ReactDOM from 'react-dom/client';
import {cx} from "@emotion/css";
import 'uno.css';
Expand All @@ -15,7 +15,7 @@ import {
Select,
SelectItem,
} from "@nextui-org/react";
import {Mark, Menu, Text} from "@mantine/core";
import {Mark, Menu,} from "@mantine/core";
import {IoIosHeartEmpty, IoMdCopy} from "react-icons/io";
import {Logo, LogoWithName} from "@/shared/components/Logo.tsx";
import {
Expand Down Expand Up @@ -51,9 +51,9 @@ import Highlighter from "react-highlight-words";
import {segment} from "@/shared/lang/segment.ts";
import useSWR from "swr";
import {SiTrueup} from "react-icons/si";
import {notify} from "@/shared/notifications";

let $ui: JQuery;
let $mount: Element | null;
let selection: string;

function Preview() {
Expand Down Expand Up @@ -81,8 +81,6 @@ interface IOriginProps {

}

import {db} from "@/shared/store/db";

function HighlighterMarker({
children,
highlightIndex,
Expand All @@ -100,8 +98,10 @@ function HighlighterMarker({
});

const handleInput: React.KeyboardEventHandler<HTMLElement> = (e) => {
e.preventDefault();
e.stopPropagation();
if (e.key === "Enter") {
e.preventDefault();
e.stopPropagation();
}
};

const selectedValues = useMemo(
Expand All @@ -111,7 +111,7 @@ function HighlighterMarker({
]);

function handleOneWordPick(key: keyof IWordInfo) {
console.log(key);
notify();
setCurSelected((state) => {
return {
...state,
Expand All @@ -120,16 +120,32 @@ function HighlighterMarker({
});
}

const [editing, enterEditing] = useState<boolean>();

function handleEnterEditorMode() {
enterEditing(true);
}

function handleLeveEditorMode() {
enterEditing(false);
}

return <Menu withinPortal={false}
closeOnClickOutside={true}
closeOnItemClick={false}
shadow="md"
width={200}
>
<Menu.Target>
<Mark className={cx("cursor-pointer", className)} onKeyDownCapture={handleInput}>
{children}
</Mark>
<Mark
contentEditable={editing ? "true" : "false"}
spellCheck={false}
onDoubleClick={handleEnterEditorMode}
onBlurCapture={handleLeveEditorMode}
className={cx("cursor-pointer", className)}
onKeyDownCapture={handleInput}
dangerouslySetInnerHTML={{__html: children as string}}
/>
</Menu.Target>

<Menu.Dropdown>
Expand Down Expand Up @@ -177,6 +193,7 @@ function Origin({className, ...props}: IOriginProps) {

return <div
{...props}
className={cx(className, "border-box ")}
>
<Highlighter
highlightClassName={cx("cursor-pointer hover:bg-yellow rounded-lg bg-transparent px-2px")}
Expand All @@ -201,18 +218,11 @@ function EnginePanel({selection}: { selection: string }) {
const ref = useRef<HTMLDivElement>(null);
const [is_loaded, setIsLoaded] = useState(false);

useLayoutEffect(() => {
setIsLoaded(true);
return () => {
$mount = null;
};
}, []);
return <Card
className={cx('w-full h-full min-h-300px w-99% m-auto pointer-events-auto overflow-visible!')}
ref={element => {
//@ts-ignore
ref.current = element!;
$mount = element!;
}}
isFooterBlurred
>
Expand Down Expand Up @@ -363,24 +373,18 @@ function PanelHeader() {
</div>;
}

function ContentApp({wrapper}: { wrapper: HTMLElement }) {
function ContentApp() {
const [panel, setPanel] = usePanelStore();
const [selection, set_selection] = useState<string>("");
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const listen = (e: any) => {
$(ref.current as HTMLElement).css({
position: "absolute",
padding: "1em",
boxSizing: "border-box",
overflow: 'visible',
top: 0 + "px",
left: 0 + "px",
pointerEvents: 'none',

minHeight: (panel.isOpen ? popupCardMinWidth : 0) + "px",
minWidth: popupCardMinWidth + "px",
maxWidth: popupCardMaxWidth + "px",
zIndex: zIndex,
zIndex: 1,
});
};
const listen_hide_popup = () => {
Expand All @@ -400,6 +404,9 @@ function ContentApp({wrapper}: { wrapper: HTMLElement }) {
//@ts-ignore
ref.current = r!;
}}
className={
cx("absolute p-1em border-box overflow-visible pointer-events-none top-0 left-0")
}
>
{
Assert(!panel.isOpen as boolean, <PanelHeader/>, <EnginePanel selection={selection}></EnginePanel>)
Expand Down Expand Up @@ -440,25 +447,37 @@ export default defineContentScript({
matches: ['<all_urls>'],
runAt: "document_end",
cssInjectionMode: "ui",
world: "ISOLATED",
async main(e) {
const settings = await getSettings();
const app_container = await createShadowRootUi(e, {
name: injectedShadowName,
position: "overlay",
append: "after",
async onMount(wrapper: HTMLElement) {
const div = document.createElement("div");

div.style.pointerEvents = "auto";
$ui = $(wrapper);

wrapper.append(div);


const $container = $(app_container.shadowHost);
let lastMouseEvent: UserEventType;
let mousedownTarget: EventTarget;
$container.css({
position: "fixed",
zIndex: zIndex,
});
window.addEventListener("scroll", (event) => {
console.log(-window.scrollY + position.offset);
$container.css({
$(div).css({
transform: `translateY(${-window.scrollY + position.offset}px)`,
top: position.y + "px",
marginLeft: position.x + "px",
});

});

const mouseUpHandler = async (event: UserEventType) => {
Expand All @@ -467,7 +486,7 @@ export default defineContentScript({

if (
(mousedownTarget instanceof HTMLInputElement || mousedownTarget instanceof HTMLTextAreaElement)
&& settings.selectInputElementsText === false
&& !settings.selectInputElementsText
) {
return;
}
Expand Down Expand Up @@ -505,7 +524,7 @@ export default defineContentScript({
position.x = x;
position.y = y;
position.offset = window.scrollY;
$container.css({
$(div).css({
top: y + "px",
left: 0,
marginLeft: x + "px",
Expand Down Expand Up @@ -542,13 +561,10 @@ export default defineContentScript({
.then(({$ui}) => {
$ui.hide();
});
const div = document.createElement("div");
wrapper.append(div);
div.style.pointerEvents = "auto";
ReactDOM.createRoot(div).render(
<TranslatorAppWrapper>
<TranslatorAppWrapper wrapper={div}>
<DndProvider backend={HTML5Backend}>
<ContentApp wrapper={wrapper}/>
<ContentApp/>
</DndProvider>
</TranslatorAppWrapper>,
);
Expand Down
Loading

0 comments on commit fc95efa

Please sign in to comment.