@@ -3246,4 +3246,68 @@ Object.assign(CodemanApp.prototype, {
32463246 }
32473247 }
32483248 } ,
3249+
3250+ // ─── Clipboard ──────────────────────────────────────────────────────────────
3251+
3252+ async _onClipboardWrite ( data ) {
3253+ const text = data ?. text ;
3254+ if ( typeof text !== 'string' ) return ;
3255+ try {
3256+ await navigator . clipboard . writeText ( text ) ;
3257+ this . showToast ( `Copied to clipboard (${ text . length } chars)` , 'success' ) ;
3258+ } catch {
3259+ this . _showClipboardFallback ( text ) ;
3260+ }
3261+ } ,
3262+
3263+ _showClipboardFallback ( text ) {
3264+ const overlay = document . createElement ( 'div' ) ;
3265+ overlay . style . cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.6);z-index:10000;display:flex;align-items:center;justify-content:center' ;
3266+
3267+ const modal = document . createElement ( 'div' ) ;
3268+ modal . style . cssText = 'background:#1e1e2e;border:1px solid #444;border-radius:8px;padding:16px;max-width:600px;width:90%;max-height:60vh;display:flex;flex-direction:column;gap:12px' ;
3269+
3270+ const header = document . createElement ( 'div' ) ;
3271+ header . style . cssText = 'display:flex;justify-content:space-between;align-items:center' ;
3272+ const title = document . createElement ( 'span' ) ;
3273+ title . style . cssText = 'color:#cdd6f4;font-weight:600' ;
3274+ title . textContent = 'Clipboard (browser blocked auto-copy)' ;
3275+ const closeBtn = document . createElement ( 'button' ) ;
3276+ closeBtn . style . cssText = 'background:none;border:none;color:#cdd6f4;font-size:18px;cursor:pointer' ;
3277+ closeBtn . textContent = '\u00d7' ;
3278+ header . appendChild ( title ) ;
3279+ header . appendChild ( closeBtn ) ;
3280+
3281+ const textarea = document . createElement ( 'textarea' ) ;
3282+ textarea . readOnly = true ;
3283+ textarea . style . cssText = 'background:#181825;color:#cdd6f4;border:1px solid #555;border-radius:4px;padding:8px;font-family:monospace;font-size:13px;resize:none;height:200px;width:100%' ;
3284+ textarea . value = text ;
3285+
3286+ const copyBtn = document . createElement ( 'button' ) ;
3287+ copyBtn . style . cssText = 'background:#89b4fa;color:#1e1e2e;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-weight:600' ;
3288+ copyBtn . textContent = 'Copy to Clipboard' ;
3289+
3290+ modal . appendChild ( header ) ;
3291+ modal . appendChild ( textarea ) ;
3292+ modal . appendChild ( copyBtn ) ;
3293+ overlay . appendChild ( modal ) ;
3294+ document . body . appendChild ( overlay ) ;
3295+
3296+ copyBtn . onclick = async ( ) => {
3297+ try {
3298+ await navigator . clipboard . writeText ( text ) ;
3299+ this . showToast ( 'Copied to clipboard' , 'success' ) ;
3300+ overlay . remove ( ) ;
3301+ } catch {
3302+ textarea . select ( ) ;
3303+ document . execCommand ( 'copy' ) ;
3304+ this . showToast ( 'Copied (fallback)' , 'success' ) ;
3305+ overlay . remove ( ) ;
3306+ }
3307+ } ;
3308+
3309+ const close = ( ) => overlay . remove ( ) ;
3310+ closeBtn . onclick = close ;
3311+ overlay . onclick = ( e ) => { if ( e . target === overlay ) close ( ) ; } ;
3312+ } ,
32493313} ) ;
0 commit comments