@@ -388,12 +388,144 @@ class ScriptInjector {
388388 const newScripts = matchingScripts . filter (
389389 ( script ) => ! tabScripts . has ( script . id )
390390 ) ;
391- for ( const script of newScripts ) {
392- tabScripts . add ( script . id ) ;
393- await this . injectScript ( tabId , script , settings ) ;
391+
392+ if ( settings . confirmFirstRun ) {
393+ const { scriptPermissions = { } } = await chrome . storage . local . get (
394+ "scriptPermissions"
395+ ) ;
396+ const domain = new URL ( url ) . hostname ;
397+
398+ for ( const script of newScripts ) {
399+ const allowedDomains = scriptPermissions [ script . id ] || [ ] ;
400+ if ( allowedDomains . includes ( domain ) ) {
401+ tabScripts . add ( script . id ) ;
402+ await this . injectScript ( tabId , script , settings ) ;
403+ } else {
404+ const confirmed = await this . askForConfirmation (
405+ tabId ,
406+ script . name ,
407+ domain
408+ ) ;
409+ if ( confirmed ) {
410+ allowedDomains . push ( domain ) ;
411+ scriptPermissions [ script . id ] = allowedDomains ;
412+ await chrome . storage . local . set ( { scriptPermissions } ) ;
413+ tabScripts . add ( script . id ) ;
414+ await this . injectScript ( tabId , script , settings ) ;
415+ }
416+ }
417+ }
418+ } else {
419+ for ( const script of newScripts ) {
420+ tabScripts . add ( script . id ) ;
421+ await this . injectScript ( tabId , script , settings ) ;
422+ }
394423 }
395424 }
396425
426+ async askForConfirmation ( tabId , scriptName , domain ) {
427+ const results = await chrome . scripting . executeScript ( {
428+ target : { tabId } ,
429+ world : "MAIN" ,
430+ func : ( scriptName , domain ) => {
431+ return new Promise ( ( resolve ) => {
432+ const container = document . createElement ( "div" ) ;
433+ container . id = "codetweak-confirm-container" ;
434+
435+ const shadow = container . attachShadow ( { mode : "open" } ) ;
436+
437+ const style = document . createElement ( "style" ) ;
438+ style . textContent = `
439+ :host {
440+ position: fixed;
441+ top: 0;
442+ left: 0;
443+ width: 100%;
444+ height: 100%;
445+ background-color: rgba(0, 0, 0, 0.5);
446+ z-index: 2147483647;
447+ display: flex;
448+ justify-content: center;
449+ align-items: center;
450+ font-family: sans-serif;
451+ }
452+ .modal {
453+ background: white;
454+ padding: 20px;
455+ border-radius: 8px;
456+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
457+ width: 400px;
458+ max-width: 90%;
459+ }
460+ h3 {
461+ margin-top: 0;
462+ color: #333;
463+ }
464+ p {
465+ color: #555;
466+ }
467+ .buttons {
468+ text-align: right;
469+ margin-top: 20px;
470+ }
471+ button {
472+ padding: 10px 20px;
473+ border: none;
474+ border-radius: 5px;
475+ cursor: pointer;
476+ margin-left: 10px;
477+ }
478+ #allow-btn {
479+ background-color: #28a745;
480+ color: white;
481+ }
482+ #deny-btn {
483+ background-color: #dc3545;
484+ color: white;
485+ }
486+ ` ;
487+
488+ const modal = document . createElement ( "div" ) ;
489+ modal . className = "modal" ;
490+ modal . innerHTML = `
491+ <h3>CodeTweak Script Confirmation</h3>
492+ <p>Allow "<strong></strong>" to run on <strong></strong>?</p>
493+ <div class="buttons">
494+ <button id="deny-btn">Deny</button>
495+ <button id="allow-btn">Allow</button>
496+ </div>
497+ ` ;
498+ const strongs = modal . querySelectorAll ( "strong" ) ;
499+ strongs [ 0 ] . textContent = scriptName ;
500+ strongs [ 1 ] . textContent = domain ;
501+
502+ shadow . appendChild ( style ) ;
503+ shadow . appendChild ( modal ) ;
504+
505+ document . body . appendChild ( container ) ;
506+
507+ const cleanup = ( ) => {
508+ if ( container . parentNode ) {
509+ container . parentNode . removeChild ( container ) ;
510+ }
511+ } ;
512+
513+ shadow . getElementById ( "allow-btn" ) . addEventListener ( "click" , ( ) => {
514+ cleanup ( ) ;
515+ resolve ( true ) ;
516+ } ) ;
517+
518+ shadow . getElementById ( "deny-btn" ) . addEventListener ( "click" , ( ) => {
519+ cleanup ( ) ;
520+ resolve ( false ) ;
521+ } ) ;
522+ } ) ;
523+ } ,
524+ args : [ scriptName , domain ] ,
525+ } ) ;
526+ return results [ 0 ] . result ;
527+ }
528+
397529 showNotification ( tabId , scriptName ) {
398530 chrome . scripting
399531 . executeScript ( {
0 commit comments