From 75a005c6784b9b0a9258156f6c72b08baee257e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E5=AE=87=E5=AE=81?= Date: Thu, 29 Oct 2026 19:46:50 +0700 Subject: [PATCH] =?UTF-8?q?=E5=85=B3=E9=97=AD=E6=8C=89=E9=92=AE=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/site/SiteDialogs.tsx | 4 ++-- src/lib/client/startup.ts | 4 +++- tests/startup.test.mjs | 10 +++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/site/SiteDialogs.tsx b/src/components/site/SiteDialogs.tsx index 9e6d5b0..27b7464 100644 --- a/src/components/site/SiteDialogs.tsx +++ b/src/components/site/SiteDialogs.tsx @@ -49,8 +49,8 @@ export function SiteDialogs() { - diff --git a/src/lib/client/startup.ts b/src/lib/client/startup.ts index e571421..7cdd177 100644 --- a/src/lib/client/startup.ts +++ b/src/lib/client/startup.ts @@ -276,7 +276,9 @@ export function startStartupDialogs(): StartupDialogs { const startup = new StartupDialogs(storage, view, document.documentElement.classList.contains('eighteen-ok')); age.addEventListener('cancel', event => event.preventDefault()); age.querySelector('.startup-age-confirm')!.addEventListener('click', () => startup.confirmAge()); - age.querySelectorAll('.startup-age-leave,.startup-close').forEach(button => button.addEventListener('click', () => location.assign('https://www.google.com'))); + age.querySelectorAll('.startup-age-leave').forEach(button => button.addEventListener('click', () => location.assign('https://www.google.com'))); + // The close button (X) under the age dialog enters the site, like the confirm button. + age.querySelector('.startup-close')?.addEventListener('click', () => startup.confirmAge()); function nextAdvertisement() {startup.nextAdvertisement();} close.addEventListener('click', nextAdvertisement); ad.addEventListener('cancel', event => {event.preventDefault(); nextAdvertisement();}); diff --git a/tests/startup.test.mjs b/tests/startup.test.mjs index 6fbe6d1..7e6478a 100644 --- a/tests/startup.test.mjs +++ b/tests/startup.test.mjs @@ -218,17 +218,17 @@ test('image loading supports cached images, errors, timeouts and cancellation',a }finally{if(previous===undefined)delete globalThis.window;else globalThis.window=previous;} }); -test('dialog controls enforce age confirmation, advance ads on Escape, emit no tracking events, and use the reference exit',async()=>{ +test('dialog controls enforce age confirmation (the X also enters the site), advance ads on Escape, emit no tracking events, and keep the explicit exit',async()=>{ class Dialog extends FakeElement { open=false;nodes=new Map(); showModal(){this.open=true;} close(){this.open=false;} querySelector(selector){return this.nodes.get(selector);} - querySelectorAll(){return [exit,ageClose];} + querySelectorAll(){return [exit];} } const age=new Dialog(),popup=new Dialog(),grid=new Dialog(); const enter=new FakeElement(),exit=new FakeElement(),ageClose=new FakeElement(),close=new FakeElement(),media=new FakeElement(),loading=new FakeElement(),image=new FakeImage(),promotions=new FakeElement(),gridClose=new FakeElement(); - age.nodes.set('.startup-age-confirm',enter); + age.nodes.set('.startup-age-confirm',enter);age.nodes.set('.startup-close',ageClose); popup.nodes.set('.startup-ad-image',image);popup.nodes.set('.startup-ad-media',media);popup.nodes.set('.startup-ad-loading',loading);popup.nodes.set('.startup-close',close); grid.nodes.set('.startup-promotions',promotions);grid.nodes.set('.startup-close',gridClose); const doc=new EventTarget(),classes=new Set();const store=session(),exits=[],tracks=[]; @@ -243,7 +243,7 @@ test('dialog controls enforce age confirmation, advance ads on Escape, emit no t const controller=startStartupDialogs();controller.setAdvertisements(ads,[ad('app')]);await flush(); assert.equal(age.open,true);assert.equal(popup.open,false); const cancelAge=new Event('cancel',{cancelable:true});age.dispatchEvent(cancelAge);assert.equal(cancelAge.defaultPrevented,true);assert.equal(age.open,true); - enter.click();assert.equal(age.open,false);assert.equal(popup.open,true);assert.equal(media.href,'https://example.com/first');assert.equal(store.getItem('hg_age_ok'),'1'); + ageClose.click();assert.equal(age.open,false);assert.deepEqual(exits,[],'the X never leaves the site');assert.equal(popup.open,true);assert.equal(media.href,'https://example.com/first');assert.equal(store.getItem('hg_age_ok'),'1'); media.click();assert.equal(popup.open,true); const cancelAd=new Event('cancel',{cancelable:true});popup.dispatchEvent(cancelAd);await flush(); assert.equal(cancelAd.defaultPrevented,true);assert.equal(media.href,'https://example.com/second');assert.equal(popup.open,true); @@ -273,6 +273,6 @@ test('dialog controls enforce age confirmation, advance ads on Escape, emit no t assert.equal(promotions.children[1].href,'https://example.com/last'); const inertClick=new Event('click');Object.defineProperty(inertClick,'target',{value:noLink.children[0]});promotions.dispatchEvent(inertClick);assert.equal(grid.open,true); gridClose.click(); - exit.click();ageClose.click();assert.deepEqual(exits,['https://www.google.com','https://www.google.com']); + exit.click();assert.deepEqual(exits,['https://www.google.com']); }finally{for(const [key,value] of Object.entries(originals)){if(value===undefined)delete globalThis[key];else globalThis[key]=value;}} });