mirror of
https://github.com/searxng/searxng.git
synced 2025-11-24 07:23:09 -05:00
[fix] client/simple: insecure ctx clipboard copy
Uses the deprecated [`execCommand()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) to copy content to clipboard if accessing the instance through HTTP, this method isn't going away soon. Closes https://github.com/searxng/searxng/issues/5359
This commit is contained in:
parent
b770a46e1f
commit
8dacbbbb15
@ -407,12 +407,31 @@ const toggleHelp = (keyBindings: typeof baseKeyBinding): void => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const copyURLToClipboard = async (): Promise<void> => {
|
const copyURLToClipboard = async (): Promise<void> => {
|
||||||
const currentUrlElement = document.querySelector<HTMLAnchorElement>(".result[data-vim-selected] h3 a");
|
const selectedResult = document.querySelector<HTMLElement>(".result[data-vim-selected]");
|
||||||
assertElement(currentUrlElement);
|
if (!selectedResult) return;
|
||||||
|
|
||||||
const url = currentUrlElement.getAttribute("href");
|
const resultAnchor = selectedResult.querySelector<HTMLAnchorElement>("a");
|
||||||
|
assertElement(resultAnchor);
|
||||||
|
|
||||||
|
const url = resultAnchor.getAttribute("href");
|
||||||
if (url) {
|
if (url) {
|
||||||
await navigator.clipboard.writeText(url);
|
if (window.isSecureContext) {
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
} else {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
if (selection) {
|
||||||
|
const node = document.createElement("span");
|
||||||
|
node.textContent = url;
|
||||||
|
resultAnchor.appendChild(node);
|
||||||
|
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(node);
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
document.execCommand("copy");
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
import { http, listen, settings } from "../core/toolkit.ts";
|
import { assertElement, http, listen, settings } from "../core/toolkit.ts";
|
||||||
|
|
||||||
let engineDescriptions: Record<string, [string, string]> | undefined;
|
let engineDescriptions: Record<string, [string, string]> | undefined;
|
||||||
|
|
||||||
@ -52,19 +52,25 @@ for (const engine of disableAllEngines) {
|
|||||||
listen("click", engine, () => toggleEngines(false, engineToggles));
|
listen("click", engine, () => toggleEngines(false, engineToggles));
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyHashButton: HTMLElement | null = document.querySelector<HTMLElement>("#copy-hash");
|
listen("click", "#copy-hash", async function (this: HTMLElement) {
|
||||||
if (copyHashButton) {
|
const target = this.parentElement?.querySelector<HTMLPreElement>("pre");
|
||||||
listen("click", copyHashButton, async (event: Event) => {
|
assertElement(target);
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const { copiedText, hash } = copyHashButton.dataset;
|
if (window.isSecureContext) {
|
||||||
if (!(copiedText && hash)) return;
|
await navigator.clipboard.writeText(target.innerText);
|
||||||
|
} else {
|
||||||
try {
|
const selection = window.getSelection();
|
||||||
await navigator.clipboard.writeText(hash);
|
if (selection) {
|
||||||
copyHashButton.innerText = copiedText;
|
const range = document.createRange();
|
||||||
} catch (error) {
|
range.selectNodeContents(target);
|
||||||
console.error("Failed to copy hash:", error);
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
document.execCommand("copy");
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
const copiedText = this.dataset.copiedText;
|
||||||
|
if (copiedText) {
|
||||||
|
this.innerText = copiedText;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@ -121,7 +121,19 @@ listen("click", "#copy_url", async function (this: HTMLElement) {
|
|||||||
const target = this.parentElement?.querySelector<HTMLPreElement>("pre");
|
const target = this.parentElement?.querySelector<HTMLPreElement>("pre");
|
||||||
assertElement(target);
|
assertElement(target);
|
||||||
|
|
||||||
await navigator.clipboard.writeText(target.innerText);
|
if (window.isSecureContext) {
|
||||||
|
await navigator.clipboard.writeText(target.innerText);
|
||||||
|
} else {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
if (selection) {
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(target);
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
document.execCommand("copy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const copiedText = this.dataset.copiedText;
|
const copiedText = this.dataset.copiedText;
|
||||||
if (copiedText) {
|
if (copiedText) {
|
||||||
this.innerText = copiedText;
|
this.innerText = copiedText;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<div id="search_url" role="complementary" aria-labelledby="search_url-title">
|
<div id="search_url" role="complementary" aria-labelledby="search_url-title">
|
||||||
<details class="sidebar-collapsible">
|
<details class="sidebar-collapsible">
|
||||||
<summary class="title" id="search_url-title">{{ _('Search URL') }}</summary>
|
<summary class="title" id="search_url-title">{{ _('Search URL') }}</summary>
|
||||||
<button id="copy_url" type="submit" data-copied-text="{{ _('Copied') }}">{{ _('Copy') }}</button>
|
<button id="copy_url" type="button" class="button" data-copied-text="{{ _('Copied') }}">{{ _('Copy') }}</button>
|
||||||
<div class="selectable_url">
|
<div class="selectable_url">
|
||||||
<pre>{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&language={{ current_language }}&time_range={{ time_range }}&safesearch={{ safesearch }}
|
<pre>{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&language={{ current_language }}&time_range={{ time_range }}&safesearch={{ safesearch }}
|
||||||
{%- if pageno > 1 -%}
|
{%- if pageno > 1 -%}
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
{{- preferences_url_params|e }}
|
{{- preferences_url_params|e }}
|
||||||
</pre>{{- '' -}}
|
</pre>{{- '' -}}
|
||||||
</div>
|
</div>
|
||||||
<button id="copy-hash" class="button" data-hash="{{- preferences_url_params|e -}}" data-copied-text="{{- _('Copied') -}}">{{- _('Copy') -}}</button>
|
<button id="copy-hash" type="button" class="button" data-hash="{{- preferences_url_params|e -}}" data-copied-text="{{- _('Copied') -}}">{{- _('Copy') -}}</button>
|
||||||
</div>
|
</div>
|
||||||
<h4>
|
<h4>
|
||||||
{{- _('Insert copied preferences hash (without URL) to restore') -}}:{{- '' -}}
|
{{- _('Insert copied preferences hash (without URL) to restore') -}}:{{- '' -}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user