()
| 335 | } |
| 336 | |
| 337 | function ScriptEditor() { |
| 338 | const [visible, setVisible] = useState<{ [key: string]: boolean }>({}); |
| 339 | const [searchKeyword, setSearchKeyword] = useState<string>(""); |
| 340 | const [showSearchInput, setShowSearchInput] = useState<boolean>(false); |
| 341 | const [modal, contextHolder] = Modal.useModal(); |
| 342 | const { |
| 343 | scriptList, |
| 344 | setScriptList, |
| 345 | canLoadScript, |
| 346 | setCanLoadScript, |
| 347 | editors, |
| 348 | setEditors, |
| 349 | selectedScript, |
| 350 | setSelectSciptButtonAndTab, |
| 351 | } = useScriptList(); |
| 352 | const editorsRef = useRef<EditorState[]>(editors); // 取出资料用 |
| 353 | // Sync during render (no useEffect needed) |
| 354 | editorsRef.current = editors; |
| 355 | // The function identity is now permanent (empty dependency array) |
| 356 | const getScript = useCallback((uuid: string) => { |
| 357 | return editorsRef.current.find((e) => e.script.uuid === uuid)?.script; |
| 358 | }, []); |
| 359 | const editorFindIndex = (uuid: string) => { |
| 360 | return editorsRef.current.findIndex((e) => e.script.uuid === uuid); |
| 361 | }; |
| 362 | const editorFindItem = (uuid: string) => { |
| 363 | return editorsRef.current.find((e) => e.script.uuid === uuid); |
| 364 | }; |
| 365 | const delayedEditorFocus = (editor: editor.ICodeEditor | null | undefined, delayMs: number = 100) => { |
| 366 | editor = !editor ? editorsRef.current.find((e) => e.active && e.script.uuid === selectedScript)?.editor : editor; |
| 367 | if (editor) { |
| 368 | setTimeout(editor.focus.bind(editor), delayMs); |
| 369 | } |
| 370 | }; |
| 371 | const getSelectedText = (editor: editor.ICodeEditor) => { |
| 372 | const model = editor.getModel(); |
| 373 | if (!model) return ""; |
| 374 | |
| 375 | const selections = editor.getSelections()?.filter((selection) => !selection.isEmpty()) || []; |
| 376 | return selections.map((selection) => model.getValueInRange(selection)).join(model.getEOL()); |
| 377 | }; |
| 378 | const writeClipboardText = async (text: string) => { |
| 379 | if (navigator.clipboard?.writeText) { |
| 380 | try { |
| 381 | await navigator.clipboard.writeText(text); |
| 382 | return; |
| 383 | } catch { |
| 384 | // 失败时回落到下方的 execCommand 分支 |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | const textarea = document.createElement("textarea"); |
| 389 | textarea.value = text; |
| 390 | textarea.style.position = "fixed"; |
| 391 | textarea.style.left = "-9999px"; |
| 392 | textarea.style.top = "-9999px"; |
| 393 | document.body.appendChild(textarea); |
| 394 | textarea.focus(); |
nothing calls this directly
no test coverage detected