diff --git a/twpkinfo-ad-blocker-sniper.user.js b/twpkinfo-ad-blocker-sniper.user.js index 4699f82..67435c5 100644 --- a/twpkinfo-ad-blocker-sniper.user.js +++ b/twpkinfo-ad-blocker-sniper.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name TWPKInfo 廣告清除器 // @namespace http://tampermonkey.net/ -// @version 1.1.7 +// @version 1.1.15 // @description 移除頂部導覽列、底部功能列與空白列,保留地圖工具 // @author AdBlocker // @match https://twpkinfo.com/* @@ -19,6 +19,21 @@ let cleanupStarted = false; let tooltipTimer = null; + // 判斷元素是否屬於 Leaflet 地圖/彈窗系統(清理時必須跳過) + function isLeafletDescendant(element) { + if (!element || !element.closest) { + return false; + } + return Boolean( + element.closest('#map') || + element.closest('.leaflet-container') || + element.closest('.leaflet-pane') || + element.closest('.leaflet-popup') || + element.closest('.leaflet-tooltip') || + element.closest('.leaflet-control') + ); + } + // 清理用 CSS function addCleanupCSS() { if (document.getElementById('twpk-ad-blocker-cleanup')) { @@ -131,6 +146,47 @@ visibility: visible !important; } + /* 保護 Leaflet 彈出視窗(popup)所有內容,避免被廣告清除規則誤殺 */ + html body .leaflet-pane, + html body .leaflet-pane *, + html body .leaflet-popup, + html body .leaflet-popup * { + visibility: visible !important; + opacity: 1 !important; + } + + /* 只強制 popup 內文(rows)的顯示,避免被 display:none 規則蓋掉; + 不再覆寫 .leaflet-popup / .leaflet-popup-content-wrapper / tip 容器尺寸, + 讓 TWPKInfo 與 Leaflet 自身的排版(含底部 tip 三角)正常運作 */ + html body .leaflet-popup-content > *, + html body .leaflet-popup-content > * > *, + html body .leaflet-popup-content > * > * > *, + html body .leaflet-popup-content > * > * > * > * { + display: revert !important; + height: auto !important; + min-height: 0 !important; + max-height: none !important; + overflow: visible !important; + } + + /* 把 Leaflet popup 預設的白色三角 tip 拿掉,並把 wrapper 改成自己控制留白 */ + html body .leaflet-popup-content-wrapper { + overflow: hidden !important; + border-radius: 12px !important; + padding: 14px 4px !important; + } + + /* 內層 content margin 歸零,全部交給 wrapper 的 padding 負責 */ + html body .leaflet-popup-content { + margin: 0 14px !important; + } + + html body .leaflet-popup-tip-container, + html body .leaflet-popup-tip, + html body [class*="leaflet-popup-tip"] { + display: none !important; + } + #map, .leaflet-container { top: 0 !important; @@ -339,8 +395,7 @@ if (div.id === 'map' || div.classList.contains('leaflet-container') || div.classList.contains('leaflet-control-attribution') || - div.closest('#map') || - div.closest('.leaflet-container')) { + isLeafletDescendant(div)) { return; } @@ -366,7 +421,10 @@ // 策略2:通過內容識別 document.querySelectorAll('div').forEach(div => { - const classList = div.className.toLowerCase(); + if (isLeafletDescendant(div)) { + return; + } + const classList = (typeof div.className === 'string' ? div.className : '').toLowerCase(); if (classList.includes('bottom') && (classList.includes('nav') || classList.includes('bar') || classList.includes('menu') || classList.includes('toolbar')) && !classList.includes('pokemon') && @@ -420,8 +478,7 @@ candidates.forEach(element => { if (element.id === 'map' || element.classList.contains('leaflet-container') || - element.closest('#map') || - element.closest('.leaflet-container')) { + isLeafletDescendant(element)) { return; } @@ -460,8 +517,18 @@ let hasElementChanges = false; mutations.forEach((mutation) => { + // 略過 Leaflet popup / pane 內部的變動,避免誤判清理 + if (mutation.target && mutation.target.nodeType === 1 && + isLeafletDescendant(mutation.target)) { + return; + } + mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { // 元素節點 + if (isLeafletDescendant(node)) { + return; + } + hasElementChanges = true; const rect = node.getBoundingClientRect(); const style = window.getComputedStyle(node); @@ -532,8 +599,7 @@ document.querySelectorAll('div').forEach(div => { if (div.id === 'map' || div.classList.contains('leaflet-container') || - div.closest('#map') || - div.closest('.leaflet-container')) { + isLeafletDescendant(div)) { return; } @@ -624,8 +690,7 @@ document.querySelectorAll('div').forEach(div => { if (div.id === 'map' || div.classList.contains('leaflet-container') || - div.closest('#map') || - div.closest('.leaflet-container')) { + isLeafletDescendant(div)) { return; }