mirror of
https://github.com/027xiguapi/code-box.git
synced 2026-04-28 15:22:15 +00:00
优化自定义选择框代码
This commit is contained in:
67
component/customDomSelector/Tooltip.tsx
Normal file
67
component/customDomSelector/Tooltip.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
CheckOutlined,
|
||||
CloseOutlined,
|
||||
DownSquareOutlined,
|
||||
LeftSquareOutlined,
|
||||
RightSquareOutlined,
|
||||
UpSquareOutlined
|
||||
} from "@ant-design/icons"
|
||||
import { Button, Flex, message, Modal } from "antd"
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react"
|
||||
|
||||
export default function Tooltip(props: any) {
|
||||
const handleConfirm = () => {
|
||||
props.onConfirm()
|
||||
}
|
||||
|
||||
const navigateElement = (direction: "parent" | "child" | "prev" | "next") => {
|
||||
props.onNavigate(direction)
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
props.onCancel()
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex wrap gap="small">
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon={<CheckOutlined />}
|
||||
onClick={handleConfirm}>
|
||||
确定
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
icon={<UpSquareOutlined />}
|
||||
onClick={() => navigateElement("parent")}>
|
||||
父节点
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
icon={<DownSquareOutlined />}
|
||||
onClick={() => navigateElement("child")}>
|
||||
子节点
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
icon={<LeftSquareOutlined />}
|
||||
onClick={() => navigateElement("prev")}>
|
||||
上一个
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
icon={<RightSquareOutlined />}
|
||||
onClick={() => navigateElement("next")}>
|
||||
下一个
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
size="small"
|
||||
icon={<CloseOutlined />}
|
||||
onClick={handleCancel}>
|
||||
取消
|
||||
</Button>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
272
component/customDomSelector/index.tsx
Normal file
272
component/customDomSelector/index.tsx
Normal file
@@ -0,0 +1,272 @@
|
||||
import { Modal } from "antd"
|
||||
import React, { useEffect, useRef, useState } from "react"
|
||||
import { createRoot } from "react-dom/client"
|
||||
|
||||
import { useMessage } from "@plasmohq/messaging/hook"
|
||||
import { useStorage } from "@plasmohq/storage/hook"
|
||||
|
||||
import { addCss, saveHtml, saveMarkdown, scrollToTop, setIcon } from "~tools"
|
||||
import { savePdf } from "~utils/downloadPdf"
|
||||
import { useContent } from "~utils/editMarkdownHook"
|
||||
import Turndown from "~utils/turndown"
|
||||
|
||||
import Tooltip from "./Tooltip"
|
||||
|
||||
const turndownService = Turndown()
|
||||
|
||||
export default function CustomDomSelector() {
|
||||
const isReady = useRef(false)
|
||||
const isSelect = useRef(false)
|
||||
const downloadType = useRef("")
|
||||
const [content, setContent] = useContent()
|
||||
const [validTime] = useStorage("app-validTime", "1730390400")
|
||||
const [isModalOpen, setIsModalOpen] = useState(false)
|
||||
|
||||
const selectorRef = useRef<HTMLElement | null>(null)
|
||||
const tooltipRef = useRef<HTMLElement | null>(null)
|
||||
|
||||
const articleTitle = document
|
||||
.querySelector<HTMLElement>("head title")
|
||||
?.innerText.trim()
|
||||
|
||||
useEffect(() => {
|
||||
addEventListeners()
|
||||
setIcon(true)
|
||||
addCss(`.codebox-current { outline: 2px solid #42b88350 !important; }`)
|
||||
return () => {
|
||||
removeEventListeners()
|
||||
// removeSelector()
|
||||
removeTooltip()
|
||||
removeHighlight()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const createSelector = () => {
|
||||
const selector = document.createElement("div")
|
||||
selector.classList.add("codebox-selector")
|
||||
selector.style.position = "absolute"
|
||||
selector.style.pointerEvents = "none"
|
||||
selector.style.zIndex = "2147483640"
|
||||
selector.style.backgroundColor = "#42b88325"
|
||||
selector.style.border = "2px solid #42b88350"
|
||||
selector.style.borderRadius = "2px"
|
||||
selector.style.transition = "all 0.1s ease-in"
|
||||
selector.style.display = "none"
|
||||
document.body.appendChild(selector)
|
||||
selectorRef.current = selector
|
||||
}
|
||||
|
||||
const createTooltip = () => {
|
||||
const tooltip = document.createElement("div")
|
||||
tooltip.classList.add("codebox-tooltip")
|
||||
tooltip.style.position = "absolute"
|
||||
tooltip.style.zIndex = "2147483641"
|
||||
tooltip.style.backgroundColor = "#fff"
|
||||
tooltip.style.border = "1px solid #eee"
|
||||
tooltip.style.borderRadius = "5px"
|
||||
tooltip.style.padding = "8px"
|
||||
tooltip.style.boxShadow = "0 2px 8px rgba(0, 0, 0, 0.15)"
|
||||
// tooltip.style.display = "none"
|
||||
document.body.appendChild(tooltip)
|
||||
const root = createRoot(tooltip)
|
||||
root.render(
|
||||
<Tooltip
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={handleCancel}
|
||||
onNavigate={navigateElement}
|
||||
/>
|
||||
)
|
||||
tooltipRef.current = tooltip
|
||||
}
|
||||
|
||||
const removeSelector = () => {
|
||||
if (selectorRef.current) {
|
||||
document.body.removeChild(selectorRef.current)
|
||||
}
|
||||
}
|
||||
|
||||
const removeTooltip = () => {
|
||||
if (tooltipRef.current) {
|
||||
document.body.removeChild(tooltipRef.current)
|
||||
tooltipRef.current = null
|
||||
}
|
||||
}
|
||||
|
||||
const addEventListeners = () => {
|
||||
document.addEventListener("mousemove", handleMouseMove)
|
||||
document.addEventListener("click", handleClick)
|
||||
}
|
||||
|
||||
const removeEventListeners = () => {
|
||||
document.removeEventListener("mousemove", handleMouseMove)
|
||||
document.removeEventListener("click", handleClick)
|
||||
}
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
if (isReady.current && !isSelect.current) {
|
||||
const target = event.target as HTMLElement
|
||||
highlightElement(target)
|
||||
// updateSelectorPosition(target)
|
||||
}
|
||||
}
|
||||
|
||||
const handleClick = (event: MouseEvent) => {
|
||||
if (isReady.current) {
|
||||
const target = event.target as HTMLElement
|
||||
const tooltip = target.closest(".codebox-tooltip")
|
||||
const modal = target.closest(".codebox-modal")
|
||||
const submit = target.closest(".valid-submit")
|
||||
|
||||
if (!tooltip && !modal && !submit) {
|
||||
removeTooltip()
|
||||
createTooltip()
|
||||
isSelect.current = true
|
||||
highlightElement(target)
|
||||
// updateSelectorPosition(target)
|
||||
updateTooltipPosition(target)
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const highlightElement = (element: HTMLElement) => {
|
||||
removeHighlight()
|
||||
element.classList.add("codebox-current")
|
||||
selectorRef.current = element
|
||||
}
|
||||
|
||||
const removeHighlight = () => {
|
||||
const currentList = document.querySelectorAll(".codebox-current")
|
||||
currentList.forEach((el) => el.classList.remove("codebox-current"))
|
||||
selectorRef.current = null
|
||||
}
|
||||
|
||||
const updateSelectorPosition = (element: HTMLElement) => {
|
||||
if (selectorRef.current) {
|
||||
const rect = element.getBoundingClientRect()
|
||||
selectorRef.current.style.top = `${rect.top + window.scrollY}px`
|
||||
selectorRef.current.style.left = `${rect.left + window.scrollX}px`
|
||||
selectorRef.current.style.width = `${rect.width}px`
|
||||
selectorRef.current.style.height = `${rect.height}px`
|
||||
selectorRef.current.style.display = "block"
|
||||
}
|
||||
}
|
||||
|
||||
const updateTooltipPosition = (element: HTMLElement) => {
|
||||
const rect = element.getBoundingClientRect()
|
||||
const distanceTop = rect.top + window.scrollY
|
||||
const distanceLeft = rect.left + window.scrollX
|
||||
const top =
|
||||
distanceTop < 50 ? distanceTop + rect.height + 5 : distanceTop - 40
|
||||
tooltipRef.current.style.top = `${top}px`
|
||||
tooltipRef.current.style.left = `${distanceLeft + 5}px`
|
||||
scrollToTop(tooltipRef.current)
|
||||
}
|
||||
|
||||
useMessage(async (req: any, res: any) => {
|
||||
if (req.name == "custom-downloadHtml") {
|
||||
setCustom("html")
|
||||
}
|
||||
if (req.name == "custom-downloadMarkdown") {
|
||||
setCustom("downloadMarkdown")
|
||||
}
|
||||
if (req.name == "custom-editMarkdown") {
|
||||
setCustom("editMarkdown")
|
||||
}
|
||||
if (req.name == "custom-downloadPdf") {
|
||||
setCustom("pdf")
|
||||
}
|
||||
if (req.name == "custom-downloadImg") {
|
||||
setCustom("img")
|
||||
}
|
||||
})
|
||||
|
||||
const setCustom = (type: string) => {
|
||||
downloadType.current = type
|
||||
isReady.current = true
|
||||
isSelect.current = false
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (!selectorRef.current || !downloadType.current) return
|
||||
switch (downloadType.current) {
|
||||
case "html":
|
||||
saveHtml(selectorRef.current, articleTitle)
|
||||
break
|
||||
case "downloadMarkdown":
|
||||
const markdown = turndownService.turndown(selectorRef.current)
|
||||
saveMarkdown(markdown, articleTitle)
|
||||
break
|
||||
case "editMarkdown":
|
||||
setContent(".codebox-current")
|
||||
break
|
||||
case "pdf":
|
||||
savePdf(selectorRef.current, articleTitle)
|
||||
break
|
||||
}
|
||||
|
||||
resetState()
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
resetState()
|
||||
}
|
||||
|
||||
const resetState = () => {
|
||||
removeHighlight()
|
||||
// removeSelector()
|
||||
removeTooltip()
|
||||
isReady.current = false
|
||||
isSelect.current = false
|
||||
}
|
||||
|
||||
const navigateElement = (direction: "parent" | "child" | "prev" | "next") => {
|
||||
if (!selectorRef.current) return
|
||||
|
||||
let newElement: HTMLElement | null = null
|
||||
switch (direction) {
|
||||
case "parent":
|
||||
newElement = selectorRef.current.parentElement
|
||||
break
|
||||
case "child":
|
||||
newElement = selectorRef.current.firstElementChild as HTMLElement
|
||||
break
|
||||
case "prev":
|
||||
newElement = selectorRef.current.previousElementSibling as HTMLElement
|
||||
break
|
||||
case "next":
|
||||
newElement = selectorRef.current.nextElementSibling as HTMLElement
|
||||
break
|
||||
}
|
||||
|
||||
if (newElement) {
|
||||
highlightElement(newElement)
|
||||
// updateSelectorPosition(newElement)
|
||||
updateTooltipPosition(newElement)
|
||||
}
|
||||
}
|
||||
|
||||
const handleOkModal = () => {
|
||||
setIsModalOpen(false)
|
||||
}
|
||||
|
||||
const handleCancelModal = () => {
|
||||
setIsModalOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
className="codebox-modal"
|
||||
open={isModalOpen}
|
||||
onOk={handleOkModal}
|
||||
onCancel={handleCancelModal}>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,41 +1,13 @@
|
||||
import { StyleProvider } from "@ant-design/cssinjs"
|
||||
import {
|
||||
CheckOutlined,
|
||||
CloseOutlined,
|
||||
DownSquareOutlined,
|
||||
LeftSquareOutlined,
|
||||
RightSquareOutlined,
|
||||
UpSquareOutlined
|
||||
} from "@ant-design/icons"
|
||||
import { Button, Flex, message, Modal } from "antd"
|
||||
import antdResetCssText from "data-text:antd/dist/reset.css"
|
||||
import dayjs from "dayjs"
|
||||
import type {
|
||||
PlasmoCSConfig,
|
||||
PlasmoGetShadowHostId,
|
||||
PlasmoGetStyle
|
||||
} from "plasmo"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
|
||||
import { sendToBackground } from "@plasmohq/messaging"
|
||||
import { useMessage } from "@plasmohq/messaging/hook"
|
||||
import { useStorage } from "@plasmohq/storage/hook"
|
||||
|
||||
import ValidateContent from "~component/contents/validateContent"
|
||||
import CustomDomSelector from "~component/customDomSelector"
|
||||
import { ThemeProvider } from "~theme"
|
||||
import { addCss, saveHtml, saveMarkdown, scrollToTop, setIcon } from "~tools"
|
||||
import { getSummary } from "~utils/coze"
|
||||
import useCssCodeHook from "~utils/cssCodeHook"
|
||||
import { downloadAllImagesAsZip } from "~utils/downloadAllImg"
|
||||
import { savePdf } from "~utils/downloadPdf"
|
||||
import DrawImages from "~utils/drawImages"
|
||||
import { useContent } from "~utils/editMarkdownHook"
|
||||
import Turndown from "~utils/turndown"
|
||||
|
||||
const turndownService = Turndown()
|
||||
const articleTitle = document
|
||||
.querySelector<HTMLElement>("head title")
|
||||
?.innerText.trim()
|
||||
|
||||
const HOST_ID = "codebox-csui"
|
||||
|
||||
@@ -48,341 +20,11 @@ export const getStyle: PlasmoGetStyle = () => {
|
||||
return style
|
||||
}
|
||||
|
||||
let isDownloadType = "markdown"
|
||||
let isReady = false
|
||||
let isSelect = false
|
||||
let instance = null
|
||||
|
||||
export default function CustomOverlay() {
|
||||
const [cssCode, runCss] = useCssCodeHook("custom")
|
||||
const [content, setContent] = useContent()
|
||||
const [summary, setSummary] = useStorage("app-summary", "")
|
||||
const [validTime, setValidTime] = useStorage("app-validTime", "1730390400")
|
||||
const [isCurrentDom, setIsCurrentDom] = useState<boolean>(false)
|
||||
const [rect, setRect] = useState<any>(() => {
|
||||
return { top: 0, right: 0 }
|
||||
})
|
||||
const [messageApi, contextHolder] = message.useMessage()
|
||||
|
||||
useEffect(() => {
|
||||
getSelection()
|
||||
setIcon(true)
|
||||
}, [])
|
||||
|
||||
useMessage(async (req: any, res: any) => {
|
||||
if (req.name == "custom-isShow") {
|
||||
res.send({ isShow: true })
|
||||
}
|
||||
if (req.name == "custom-downloadHtml") {
|
||||
setCustom("html")
|
||||
}
|
||||
if (req.name == "custom-downloadMarkdown") {
|
||||
setCustom("downloadMarkdown")
|
||||
}
|
||||
if (req.name == "custom-downloadPdf") {
|
||||
setCustom("pdf")
|
||||
}
|
||||
if (req.name == "custom-downloadImg") {
|
||||
setCustom("img")
|
||||
}
|
||||
if (req.name == "custom-editMarkdown") {
|
||||
setCustom("editMarkdown")
|
||||
}
|
||||
if (req.name == "app-downloadImages") {
|
||||
await downloadImages(req.body?.onProgress)
|
||||
}
|
||||
if (req.name == "app-get-summary") {
|
||||
setSummary("")
|
||||
const res = await getSummary(location.href)
|
||||
if (res.code == 0) {
|
||||
const result = JSON.parse(res.data)
|
||||
setSummary(result)
|
||||
}
|
||||
}
|
||||
if (req.name == "app-full-page-screenshot") {
|
||||
if (confirm("确认下载?")) {
|
||||
const { scrollHeight, clientHeight } = document.documentElement
|
||||
const devicePixelRatio = window.devicePixelRatio || 1
|
||||
|
||||
let capturedHeight = 0
|
||||
let capturedImages = []
|
||||
|
||||
const captureAndScroll = async () => {
|
||||
const scrollAmount = clientHeight * devicePixelRatio
|
||||
const res = await sendToBackground({ name: "screenshot" })
|
||||
const dataUrl = res.dataUrl
|
||||
|
||||
capturedHeight += scrollAmount
|
||||
if (capturedHeight < scrollHeight * devicePixelRatio) {
|
||||
capturedImages.push(dataUrl)
|
||||
window.scrollTo(0, capturedHeight)
|
||||
setTimeout(captureAndScroll, 2000) // Adjust the delay as needed
|
||||
} else {
|
||||
DrawImages(capturedImages, articleTitle)
|
||||
}
|
||||
}
|
||||
|
||||
captureAndScroll()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
async function downloadImages(
|
||||
onProgress?: (current: number, total: number) => void
|
||||
) {
|
||||
const imageUrls = Array.from(document.images).map((img) => img.src)
|
||||
try {
|
||||
const res = await sendToBackground({
|
||||
name: "download",
|
||||
body: {
|
||||
action: "downloadAllImages",
|
||||
imageUrls: imageUrls,
|
||||
title: articleTitle,
|
||||
onProgress: onProgress
|
||||
}
|
||||
})
|
||||
if (res.code == 0) {
|
||||
alert("下载失败")
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to download images:`, error)
|
||||
}
|
||||
}
|
||||
|
||||
function setCustom(type) {
|
||||
isReady = true
|
||||
isSelect = false
|
||||
isDownloadType = type
|
||||
messageApi.info("请在页面选择要下载区域!")
|
||||
}
|
||||
|
||||
function getSelection() {
|
||||
addCss(`.codebox-current { border: 1px solid #7983ff!important; }`)
|
||||
document.addEventListener("mousemove", (event) => {
|
||||
const target = event.target as HTMLElement
|
||||
if (isReady && target && !isSelect) {
|
||||
removeCurrentDom()
|
||||
target.classList.add("codebox-current")
|
||||
}
|
||||
})
|
||||
document.addEventListener("click", (event) => {
|
||||
const target = event.target as HTMLElement
|
||||
const tooltip = target.closest("#codebox-csui")
|
||||
const modal = target.closest(".ant-modal")
|
||||
const submit = target.closest(".valid-submit")
|
||||
|
||||
if (isReady && target && !tooltip && !modal && !submit) {
|
||||
isSelect = true
|
||||
setIsCurrentDom(true)
|
||||
removeCurrentDom()
|
||||
target.classList.add("codebox-current")
|
||||
setTooltip()
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function setTooltip() {
|
||||
const currentDom = document.querySelector<HTMLElement>(".codebox-current")
|
||||
const rect = currentDom.getBoundingClientRect()
|
||||
const distanceTop = rect.top + window.scrollY
|
||||
const distanceLeft = rect.left + window.scrollX
|
||||
const top = distanceTop < 50 ? distanceTop + 15 : distanceTop - 40
|
||||
const left = distanceLeft + 5
|
||||
|
||||
setRect({ top, left })
|
||||
scrollToTop(currentDom)
|
||||
}
|
||||
|
||||
function removeCurrentDom() {
|
||||
const currentList = document.querySelectorAll(".codebox-current")
|
||||
currentList.forEach((el) => {
|
||||
el.classList.remove("codebox-current")
|
||||
})
|
||||
}
|
||||
|
||||
function downloadHtml(currentDom) {
|
||||
saveHtml(currentDom, articleTitle)
|
||||
}
|
||||
|
||||
function downloadMarkdown(currentDom) {
|
||||
const markdown = turndownService.turndown(currentDom)
|
||||
saveMarkdown(markdown, articleTitle)
|
||||
}
|
||||
|
||||
function handleOk() {
|
||||
const currentDom = document.querySelector(".codebox-current")
|
||||
|
||||
if (isDownloadType == "html") {
|
||||
removeCurrentDom()
|
||||
downloadHtml(currentDom)
|
||||
} else if (isDownloadType == "downloadMarkdown") {
|
||||
removeCurrentDom()
|
||||
downloadMarkdown(currentDom)
|
||||
} else if (isDownloadType == "editMarkdown") {
|
||||
setContent(".codebox-current")
|
||||
removeCurrentDom()
|
||||
} else if (isDownloadType == "pdf") {
|
||||
removeCurrentDom()
|
||||
savePdf(currentDom, articleTitle)
|
||||
}
|
||||
isReady = false
|
||||
isSelect = false
|
||||
setIsCurrentDom(false)
|
||||
instance.destroy()
|
||||
}
|
||||
|
||||
function handleConfirm() {
|
||||
instance = Modal.confirm({
|
||||
title: "提示",
|
||||
content: (
|
||||
<>
|
||||
<div style={{ fontSize: "18px" }}>是否保存?</div>
|
||||
{Number(validTime) > dayjs().unix() ? (
|
||||
<></>
|
||||
) : (
|
||||
<ValidateContent handleOk={handleOk}></ValidateContent>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
okText: "确认",
|
||||
okButtonProps: {
|
||||
disabled: Number(validTime) <= dayjs().unix()
|
||||
},
|
||||
onOk: () => {
|
||||
handleOk()
|
||||
},
|
||||
cancelText: "取消",
|
||||
onCancel: () => {
|
||||
handleCancel()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
removeCurrentDom()
|
||||
isReady = false
|
||||
isSelect = false
|
||||
setIsCurrentDom(false)
|
||||
instance.destroy()
|
||||
}
|
||||
|
||||
function handleSetParent(event) {
|
||||
const currentDom = document.querySelector(".codebox-current")
|
||||
const parent = currentDom.parentElement
|
||||
|
||||
if (parent) {
|
||||
removeCurrentDom()
|
||||
parent.classList.add("codebox-current")
|
||||
setTooltip()
|
||||
}
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
function handleSetChild(event) {
|
||||
const currentDom = document.querySelector(".codebox-current")
|
||||
const child = currentDom.firstElementChild
|
||||
if (child) {
|
||||
removeCurrentDom()
|
||||
child.classList.add("codebox-current")
|
||||
setTooltip()
|
||||
}
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
function handleSetPrev(event) {
|
||||
const currentDom = document.querySelector(".codebox-current")
|
||||
const previousSibling = currentDom.previousElementSibling
|
||||
if (previousSibling) {
|
||||
removeCurrentDom()
|
||||
previousSibling.classList.add("codebox-current")
|
||||
setTooltip()
|
||||
}
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
function handleSetNext(event) {
|
||||
const currentDom = document.querySelector(".codebox-current")
|
||||
const nextSibling = currentDom.nextElementSibling
|
||||
if (nextSibling) {
|
||||
removeCurrentDom()
|
||||
nextSibling.classList.add("codebox-current")
|
||||
setTooltip()
|
||||
}
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider>
|
||||
{contextHolder}
|
||||
<StyleProvider container={document.getElementById(HOST_ID).shadowRoot}>
|
||||
{isCurrentDom ? (
|
||||
<div
|
||||
className="codebox-tooltip"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: `${rect.top}px`,
|
||||
left: `${rect.left}px`,
|
||||
width: "520px",
|
||||
background: "#fff",
|
||||
border: "1px solid #eee",
|
||||
borderRadius: "5px"
|
||||
}}>
|
||||
<Flex wrap gap="small">
|
||||
<Button
|
||||
color="primary"
|
||||
variant="text"
|
||||
size="small"
|
||||
icon={<CheckOutlined />}
|
||||
onClick={handleConfirm}>
|
||||
确定
|
||||
</Button>
|
||||
<Button
|
||||
color="default"
|
||||
variant="text"
|
||||
size="small"
|
||||
icon={<UpSquareOutlined />}
|
||||
onClick={handleSetParent}>
|
||||
父节点
|
||||
</Button>
|
||||
<Button
|
||||
color="default"
|
||||
variant="text"
|
||||
size="small"
|
||||
icon={<DownSquareOutlined />}
|
||||
onClick={handleSetChild}>
|
||||
子节点
|
||||
</Button>
|
||||
<Button
|
||||
color="default"
|
||||
variant="text"
|
||||
size="small"
|
||||
icon={<LeftSquareOutlined />}
|
||||
onClick={handleSetPrev}>
|
||||
上一个
|
||||
</Button>
|
||||
<Button
|
||||
color="default"
|
||||
variant="text"
|
||||
size="small"
|
||||
icon={<RightSquareOutlined />}
|
||||
onClick={handleSetNext}>
|
||||
下一个
|
||||
</Button>
|
||||
<Button
|
||||
color="danger"
|
||||
variant="text"
|
||||
size="small"
|
||||
icon={<CloseOutlined />}
|
||||
onClick={handleCancel}>
|
||||
取消
|
||||
</Button>
|
||||
</Flex>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<CustomDomSelector />
|
||||
</StyleProvider>
|
||||
</ThemeProvider>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-box",
|
||||
"displayName": "__MSG_extensionName__",
|
||||
"version": "0.9.23",
|
||||
"version": "0.9.24",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"author": "027xiguapi. <458813868@qq.com>",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user