Кнопка «Скопировать» над каждым блоком скрипта/кода (pre.copyable); копирование работает и по http (запасной путь через execCommand), в т.ч. в карточке заявки и отчёте QUIK

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-10-05 11:39:44 +03:00
parent 4498289198
commit a1379c9f27
3 changed files with 36 additions and 3 deletions
@@ -257,7 +257,7 @@
<script> <script>
function copyReq(btn){ function copyReq(btn){
var t=document.getElementById('raw-request').innerText; var t=document.getElementById('raw-request').innerText;
navigator.clipboard.writeText(t).then(function(){ window.bjCopy(t).then(function(){
var o=btn.textContent; btn.textContent='Скопировано ✓'; var o=btn.textContent; btn.textContent='Скопировано ✓';
setTimeout(function(){btn.textContent=o;},1500); setTimeout(function(){btn.textContent=o;},1500);
}); });
@@ -307,7 +307,7 @@
<script> <script>
function copyRaw(btn){ function copyRaw(btn){
var t=document.getElementById('raw-response').innerText; var t=document.getElementById('raw-response').innerText;
navigator.clipboard.writeText(t).then(function(){ window.bjCopy(t).then(function(){
var o=btn.textContent; btn.textContent='Скопировано ✓'; var o=btn.textContent; btn.textContent='Скопировано ✓';
setTimeout(function(){btn.textContent=o;},1500); setTimeout(function(){btn.textContent=o;},1500);
}); });
@@ -305,6 +305,9 @@ label { font-size:13px; font-weight:500; }
/* скрипты и код в карточках: не шире блока — длинные строки переносятся, а не уезжают за край */ /* скрипты и код в карточках: не шире блока — длинные строки переносятся, а не уезжают за край */
pre.copyable { max-width:100%; box-sizing:border-box; white-space:pre-wrap; overflow-wrap:anywhere; overflow:auto; } pre.copyable { max-width:100%; box-sizing:border-box; white-space:pre-wrap; overflow-wrap:anywhere; overflow:auto; }
details:has(> pre.copyable) { min-width:0; max-width:100%; } details:has(> pre.copyable) { min-width:0; max-width:100%; }
.copy-bar { display:flex; justify-content:flex-end; margin:6px 0 -2px; }
.copy-bar button { font-size:12px; padding:3px 10px; border:1px solid var(--border); border-radius:6px; background:var(--card); color:var(--text); cursor:pointer; }
.copy-bar button.done { color:var(--ok); border-color:var(--ok); }
@media (max-width:900px){ .doc { grid-template-columns:1fr; gap:0; } .doc-toc { position:static; max-height:none; margin-bottom:18px; border-bottom:1px solid var(--border); padding-bottom:12px; } } @media (max-width:900px){ .doc { grid-template-columns:1fr; gap:0; } .doc-toc { position:static; max-height:none; margin-bottom:18px; border-bottom:1px solid var(--border); padding-bottom:12px; } }
/* ---- Toast ---- */ /* ---- Toast ---- */
@@ -561,6 +564,36 @@ details:has(> pre.copyable) { min-width:0; max-width:100%; }
} }
poll(); poll();
setInterval(poll, 12000); // каждые 12 сек setInterval(poll, 12000); // каждые 12 сек
// Копирование текста: navigator.clipboard работает только по https/localhost, bj часто открыт по http —
// запасной путь через скрытое поле и execCommand. window.bjCopy — для кнопок на страницах.
window.bjCopy = function(text){
function fallback(){
var ta=document.createElement('textarea'); ta.value=text; ta.setAttribute('readonly','');
ta.style.position='fixed'; ta.style.top='-1000px'; document.body.appendChild(ta); ta.select();
var ok=false; try{ ok=document.execCommand('copy'); }catch(e){}
document.body.removeChild(ta); return ok;
}
if (navigator.clipboard && window.isSecureContext) {
return navigator.clipboard.writeText(text).then(function(){return true}, function(){return fallback()});
}
return Promise.resolve(fallback());
};
// Кнопка «Скопировать» над каждым блоком скрипта/кода (pre.copyable): копирует текст целиком.
(function(){
document.querySelectorAll('pre.copyable').forEach(function(pre){
if (pre.previousElementSibling && pre.previousElementSibling.classList.contains('copy-bar')) return;
var bar=document.createElement('div'); bar.className='copy-bar';
var b=document.createElement('button'); b.type='button'; b.textContent='Скопировать';
b.addEventListener('click', function(){
window.bjCopy(pre.textContent).then(function(ok){
b.textContent = ok ? 'Скопировано ✓' : 'Не удалось — выделите и скопируйте вручную';
b.classList.toggle('done', !!ok);
setTimeout(function(){ b.textContent='Скопировать'; b.classList.remove('done'); }, 2000);
});
});
bar.appendChild(b); pre.parentNode.insertBefore(bar, pre);
});
})();
// Цепочка связи с НРД в шапке: обновляется каждые 30 с, чтобы открытая страница не показывала старое. // Цепочка связи с НРД в шапке: обновляется каждые 30 с, чтобы открытая страница не показывала старое.
(function(){ (function(){
var el = document.getElementById('nsd-chain'); var el = document.getElementById('nsd-chain');
@@ -74,7 +74,7 @@
<p class="muted">Можно выделить и скопировать целиком — для отправки коллегам/аутсорсеру QUIK. <p class="muted">Можно выделить и скопировать целиком — для отправки коллегам/аутсорсеру QUIK.
{{if not .Settings.Quik.LastAt.IsZero}}Проверка от {{.Settings.Quik.LastAt.Format "02.01.2006 15:04:05"}} UTC.{{end}}</p> {{if not .Settings.Quik.LastAt.IsZero}}Проверка от {{.Settings.Quik.LastAt.Format "02.01.2006 15:04:05"}} UTC.{{end}}</p>
<div style="display:flex;gap:8px;margin:8px 0"> <div style="display:flex;gap:8px;margin:8px 0">
<button type="button" class="btn" onclick="var t=document.getElementById('quik-report').textContent;navigator.clipboard&&navigator.clipboard.writeText(t);this.textContent='Скопировано ✓';setTimeout(()=>this.textContent='Скопировать отчёт',1500)">Скопировать отчёт</button> <button type="button" class="btn" onclick="var t=document.getElementById('quik-report').textContent;window.bjCopy(t);this.textContent='Скопировано ✓';setTimeout(()=>this.textContent='Скопировать отчёт',1500)">Скопировать отчёт</button>
</div> </div>
<pre id="quik-report" style="white-space:pre-wrap;word-break:break-word;background:var(--surface-2,#0d1117);color:var(--code-fg,#c9d1d9);padding:14px;border-radius:8px;font-size:12.5px;line-height:1.5;overflow:auto;max-height:420px;user-select:all">{{.Settings.Quik.LastReport}}</pre> <pre id="quik-report" style="white-space:pre-wrap;word-break:break-word;background:var(--surface-2,#0d1117);color:var(--code-fg,#c9d1d9);padding:14px;border-radius:8px;font-size:12.5px;line-height:1.5;overflow:auto;max-height:420px;user-select:all">{{.Settings.Quik.LastReport}}</pre>
</div> </div>