diff --git a/publicpaste/web.py b/publicpaste/web.py index a13ba57..ffbadfb 100644 --- a/publicpaste/web.py +++ b/publicpaste/web.py @@ -286,6 +286,13 @@ INDEX_HTML = f""" async function copyUrl({{ automatic = false }} = {{}}) {{ if (!currentUrl) return false; + // execCommand works in many HTTP/IP scenarios, but it usually must run + // directly inside a click event. Try it first. + if (legacyCopy()) {{ + setStatus('链接已复制到剪贴板'); + return true; + }} + // Async Clipboard only works in secure contexts in most browsers. if (navigator.clipboard && window.isSecureContext) {{ try {{ @@ -293,27 +300,38 @@ INDEX_HTML = f""" setStatus('链接已复制到剪贴板'); return true; }} catch (err) {{ - // Fall through to execCommand. + // Keep the selected input visible for manual copy below. }} }} - // execCommand works in many HTTP/IP scenarios when called from a click. - if (legacyCopy()) {{ - setStatus('链接已复制到剪贴板'); - return true; - }} - selectUrl(); setStatus( automatic - ? '浏览器拦截了自动复制,链接已选中,请按 Ctrl+C / ⌘+C 复制' - : '浏览器拦截了复制,链接已选中,请按 Ctrl+C / ⌘+C 复制', + ? '浏览器限制了自动复制,链接已选中,请按 Ctrl+C / ⌘+C 复制' + : '浏览器限制了复制,链接已选中,请按 Ctrl+C / ⌘+C 复制', true, ); return false; }} - submit.addEventListener('click', async () => {{ + function requestPasteSynchronously(value) {{ + const xhr = new XMLHttpRequest(); + xhr.open('POST', '/api/paste', false); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.send(JSON.stringify({{ text: value }})); + let data = {{}}; + try {{ + data = JSON.parse(xhr.responseText || '{{}}'); + }} catch (err) {{ + data = {{ error: 'invalid response' }}; + }} + if (xhr.status < 200 || xhr.status >= 300) {{ + throw new Error(data.error || 'request failed'); + }} + return data; + }} + + submit.addEventListener('click', () => {{ const value = text.value; if (!value.trim()) {{ setStatus('请输入文本', true); @@ -324,13 +342,7 @@ INDEX_HTML = f""" resultEl.style.display = 'none'; setStatus('正在提交...'); try {{ - const response = await fetch('/api/paste', {{ - method: 'POST', - headers: {{ 'Content-Type': 'application/json' }}, - body: JSON.stringify({{ text: value }}), - }}); - const data = await response.json().catch(() => ({{ error: 'invalid response' }})); - if (!response.ok) throw new Error(data.error || 'request failed'); + const data = requestPasteSynchronously(value); currentUrl = data.url; providerEl.textContent = data.provider || ''; urlEl.textContent = currentUrl; @@ -339,7 +351,7 @@ INDEX_HTML = f""" resultEl.style.display = 'block'; copy.style.display = 'inline-block'; setStatus('提交成功,正在复制链接...'); - await copyUrl({{ automatic: true }}); + void copyUrl({{ automatic: true }}); }} catch (err) {{ setStatus(err instanceof Error ? err.message : '提交失败', true); }} finally {{ @@ -347,7 +359,7 @@ INDEX_HTML = f""" }} }}); - copy.addEventListener('click', copyUrl); + copy.addEventListener('click', () => {{ void copyUrl(); }});