diff --git a/README.md b/README.md
index b52ba79..a9768dc 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,8 @@
2. Наведите курсор — элемент подсвечивается, рядом метка с тегом.
3. **Клик** по элементу открывает форму — опишите правку, сохраните
(`Ctrl+Enter` или кнопка).
+ **`Ctrl+Shift+Enter`** — быстрый промпт: сразу копирует правку в буфер,
+ не добавляя её в общий список.
4. **Shift+клик** по следующему элементу добавляет его к текущей правке
(один текст → несколько элементов).
5. `Escape` — закрыть форму / выйти из режима.
diff --git a/src/content.js b/src/content.js
index aa8140b..ac87304 100644
--- a/src/content.js
+++ b/src/content.js
@@ -77,7 +77,14 @@
font-weight: 600;
}
button.save:hover { background: #4f46e5; }
+ button.quick:hover { background: #26334d; border-color: #475569; }
button.cancel:hover { background: #26334d; }
+ .toast {
+ position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
+ background: #6366f1; color: #fff; padding: 6px 14px;
+ border-radius: 20px; font: 12px/1.4 system-ui, sans-serif;
+ pointer-events: none; display: none; white-space: nowrap;
+ }
@@ -90,9 +97,11 @@
+
+
`;
(document.documentElement || document).appendChild(host);
@@ -103,7 +112,9 @@
const targetsList = root.querySelector('.targets');
const textarea = root.querySelector('textarea');
const saveBtn = root.querySelector('.save');
+ const quickBtn = root.querySelector('.quick');
const cancelBtn = root.querySelector('.cancel');
+ const toastEl = root.querySelector('.toast');
// ---------- Сообщения ----------
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
@@ -278,6 +289,10 @@
e.stopPropagation();
saveComment();
});
+ quickBtn.addEventListener('click', (e) => {
+ e.stopPropagation();
+ quickCopy();
+ });
cancelBtn.addEventListener('click', (e) => {
e.stopPropagation();
closeForm();
@@ -286,7 +301,8 @@
textarea.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
e.stopPropagation();
- saveComment();
+ if (e.shiftKey) quickCopy();
+ else saveComment();
}
});
@@ -338,6 +354,66 @@
return location.href.split('#')[0];
}
+ // Быстрый промпт: сразу в буфер, без сохранения в общий список.
+ function quickCopy() {
+ const prompt = textarea.value.trim();
+ if (!prompt || !selected.length) return;
+ const contexts = selected.map(elementContext);
+ closeForm();
+ clearSelection();
+ copyToClipboard(buildQuickText(prompt, contexts))
+ .then(() => showToast('Copied ✓'))
+ .catch(() => showToast('Copy failed'));
+ }
+
+ // Тот же формат, что у одного блока из «Copy all» в popup.
+ function buildQuickText(prompt, contexts) {
+ const lines = [];
+ contexts.forEach((el, j) => {
+ const label = contexts.length > 1 ? `Элемент ${j + 1}` : 'Элемент';
+ lines.push(`${label}: ${formatElement(el)}`);
+ });
+ lines.push(prompt);
+ return lines.join('\n') + '\n';
+ }
+
+ function formatElement(el) {
+ const parts = [`<${el.tag}`];
+ if (el.cls) parts.push(` class="${el.cls}"`);
+ if (el.text) parts.push(` «${el.text}»`);
+ return `\`${el.selector}\` ${parts.join('')}>`;
+ }
+
+ async function copyToClipboard(text) {
+ try {
+ await navigator.clipboard.writeText(text);
+ } catch {
+ fallbackCopy(text);
+ }
+ }
+
+ function fallbackCopy(text) {
+ const ta = document.createElement('textarea');
+ ta.value = text;
+ ta.style.cssText = 'position: fixed; opacity: 0; pointer-events: none;';
+ root.appendChild(ta);
+ ta.focus();
+ ta.select();
+ document.execCommand('copy');
+ ta.remove();
+ }
+
+ let toastTimer = null;
+
+ function showToast(msg) {
+ toastEl.textContent = msg;
+ toastEl.style.display = 'block';
+ clearTimeout(toastTimer);
+ toastTimer = setTimeout(() => {
+ toastEl.style.display = 'none';
+ }, 1400);
+ }
+
function saveComment() {
const prompt = textarea.value.trim();
if (!prompt || !selected.length) return;