Skip to content

Commit 221b58d

Browse files
committed
can hide painting plugins
1 parent 040df4c commit 221b58d

File tree

1 file changed

+238
-1
lines changed

1 file changed

+238
-1
lines changed

src/content_ui.js

Lines changed: 238 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4247,7 +4247,7 @@ try { installShareAndFavHandlers(); } catch (e) { console.warn('installShareAndF
42474247

42484248
/* Right-button long-press acts like pressing Q (with smoother tuning) */
42494249
(function installRightHoldAsQ() {
4250-
const HOLD_MS = Number(state.cfg.rightHoldMs || 500);
4250+
const HOLD_MS = Number(state.cfg.rightHoldMs);
42514251
const MOVE_THRESHOLD = Number(state.cfg.rightHoldMoveThreshold || 10);
42524252
let rightState = { pressed: false, timer: null, active: false, startX: 0, startY: 0, moved: false, suppressHandler: null };
42534253

@@ -4435,3 +4435,240 @@ try {
44354435
}
44364436
} catch (e){}
44374437
})();
4438+
// 隐藏blue marble或是skirk marble
4439+
(function installZToggleForBmDashDash() {
4440+
try {
4441+
if (window.__wplace_z_bm_dashdash_installed) return;
4442+
window.__wplace_z_bm_dashdash_installed = true;
4443+
4444+
let state = {
4445+
isHidden: false,
4446+
originalNode: null,
4447+
parent: null,
4448+
nextSibling: null,
4449+
oldInlineStyle: null,
4450+
oldAriaHidden: null,
4451+
dataMarked: false,
4452+
cloneFallback: null
4453+
};
4454+
4455+
function findBmCandidate() {
4456+
try {
4457+
// 1) 精确优先匹配你提到的 id(bm-- -> bm-A -> bm-z)
4458+
const preferIds = ['bm--', 'bm-A', 'bm-A'.toLowerCase()]; // bm-A is case-sensitive in DOM; we will try exact and then fallbacks
4459+
for (const id of ['bm--', 'bm-A', 'bm-a']) {
4460+
try {
4461+
const el = document.getElementById(id);
4462+
if (el) return el;
4463+
} catch (e) {}
4464+
}
4465+
4466+
// 2) 如果存在 bm-z(内部控件),向上寻找最近包含 bm- 前缀的祖先容器
4467+
const elBmZ = document.getElementById('bm-z');
4468+
if (elBmZ) {
4469+
let node = elBmZ;
4470+
while (node && node !== document.body) {
4471+
if (node.id && /^bm[-_]/i.test(node.id)) return node;
4472+
if (node.className && typeof node.className === 'string' && /(^|\s)bm(-|_)?/i.test(node.className)) return node;
4473+
node = node.parentElement;
4474+
}
4475+
return elBmZ;
4476+
}
4477+
} catch (e) {}
4478+
4479+
try {
4480+
// 3) 回退:寻找 id 以 bm- 开头且 DOM 结构看起来像面板(含输入、按钮或图片)
4481+
const bmPref = Array.from(document.querySelectorAll('[id]')).find(el => {
4482+
try {
4483+
if (!el.id) return false;
4484+
if (!/^bm[-_]/i.test(el.id)) return false;
4485+
// 简单检查:包含输入、按钮或图片之一
4486+
return !!(el.querySelector && (el.querySelector('input, button, img, textarea') || el.querySelector('[id^="bm-"]')));
4487+
} catch (e) { return false; }
4488+
});
4489+
if (bmPref) return bmPref;
4490+
} catch (e) {}
4491+
4492+
try {
4493+
// 4) 最后回退:查找包含明显文本或图片特征的容器
4494+
const nodes = Array.from(document.querySelectorAll('div')).slice(0, 800);
4495+
for (const n of nodes) {
4496+
try {
4497+
const text = (n.innerText || '').toLowerCase();
4498+
if (text.includes('skirk marble') || text.includes('blue marble')) return n;
4499+
if (n.querySelector && n.querySelector('img[alt*="Blue Marble"], img[alt*="Skirk"], img[alt*="Blue Marble Icon"]')) return n;
4500+
} catch (e) {}
4501+
}
4502+
} catch (e) {}
4503+
4504+
return null;
4505+
}
4506+
4507+
function preserve(node) {
4508+
try {
4509+
state.originalNode = node;
4510+
state.parent = node.parentElement || null;
4511+
state.nextSibling = node.nextSibling || null;
4512+
state.oldInlineStyle = node.getAttribute && node.getAttribute('style');
4513+
state.oldAriaHidden = node.getAttribute && node.getAttribute('aria-hidden');
4514+
state.dataMarked = !!(node.getAttribute && node.getAttribute('data-wplace-hidden-bm'));
4515+
try { state.cloneFallback = node.cloneNode(true); } catch (e) { state.cloneFallback = null; }
4516+
} catch (e) {
4517+
state.originalNode = node;
4518+
}
4519+
}
4520+
4521+
function clearState() {
4522+
state.originalNode = null;
4523+
state.parent = null;
4524+
state.nextSibling = null;
4525+
state.oldInlineStyle = null;
4526+
state.oldAriaHidden = null;
4527+
state.dataMarked = false;
4528+
state.cloneFallback = null;
4529+
state.isHidden = false;
4530+
}
4531+
4532+
function doHide(node) {
4533+
if (!node) return false;
4534+
preserve(node);
4535+
try { node.setAttribute && node.setAttribute('data-wplace-hidden-bm', '1'); } catch (e) {}
4536+
try { node.setAttribute && node.setAttribute('aria-hidden', 'true'); } catch (e) {}
4537+
try { node.setAttribute && node.setAttribute('data-wplace-old-style', node.getAttribute('style') || ''); } catch (e) {}
4538+
4539+
try {
4540+
// 使 top/right 生效:若 computed position 为 static 则设置 position:fixed
4541+
const comp = window.getComputedStyle(node);
4542+
if (!node.style.position && (!comp || comp.position === 'static' || comp.position === '')) {
4543+
node.style.position = 'fixed';
4544+
}
4545+
// 设置目标坐标并彻底隐藏
4546+
node.style.top = '-100px';
4547+
node.style.right = '75px';
4548+
node.style.transition = 'opacity 120ms linear';
4549+
node.style.opacity = '0';
4550+
node.style.pointerEvents = 'none';
4551+
node.style.display = 'none';
4552+
} catch (e) {}
4553+
4554+
state.isHidden = true;
4555+
return true;
4556+
}
4557+
4558+
function insertNodeAtParent(nodeToInsert) {
4559+
try {
4560+
if (!state.parent) {
4561+
document.body.appendChild(nodeToInsert);
4562+
return true;
4563+
}
4564+
if (state.nextSibling && state.parent.contains(state.nextSibling)) {
4565+
state.parent.insertBefore(nodeToInsert, state.nextSibling);
4566+
} else {
4567+
state.parent.appendChild(nodeToInsert);
4568+
}
4569+
return true;
4570+
} catch (e) {
4571+
try { state.parent.appendChild(nodeToInsert); return true; } catch (e2) { return false; }
4572+
}
4573+
}
4574+
4575+
function doRestore() {
4576+
try {
4577+
// 优先恢复原始节点(如果仍在 DOM 中)
4578+
if (state.originalNode && document.body.contains(state.originalNode)) {
4579+
const n = state.originalNode;
4580+
const oldStyle = n.getAttribute && n.getAttribute('data-wplace-old-style');
4581+
if (typeof oldStyle !== 'undefined' && oldStyle !== null) {
4582+
if (oldStyle.length) n.setAttribute('style', oldStyle);
4583+
else n.removeAttribute && n.removeAttribute('style');
4584+
try { n.removeAttribute('data-wplace-old-style'); } catch (e) {}
4585+
} else if (state.oldInlineStyle) {
4586+
n.setAttribute('style', state.oldInlineStyle || '');
4587+
} else {
4588+
n.removeAttribute && n.removeAttribute('style');
4589+
}
4590+
if (typeof state.oldAriaHidden === 'undefined' || state.oldAriaHidden === null) n.removeAttribute && n.removeAttribute('aria-hidden');
4591+
else n.setAttribute && n.setAttribute('aria-hidden', state.oldAriaHidden);
4592+
if (!state.dataMarked) n.removeAttribute && n.removeAttribute('data-wplace-hidden-bm');
4593+
try { n.style.display = ''; n.style.opacity = ''; n.style.pointerEvents = ''; } catch (e) {}
4594+
clearState();
4595+
showToast && showToast('已恢复 bm 面板');
4596+
return true;
4597+
}
4598+
4599+
// 原始节点不在 DOM,尝试用 cloneFallback 恢复
4600+
if (state.cloneFallback) {
4601+
let newNode;
4602+
try { newNode = state.cloneFallback.cloneNode(true); } catch (e) { try { newNode = state.cloneFallback; } catch (e2) { newNode = null; } }
4603+
if (newNode) {
4604+
const ok = insertNodeAtParent(newNode);
4605+
if (ok) {
4606+
newNode.removeAttribute && newNode.removeAttribute('data-wplace-hidden-bm');
4607+
newNode.removeAttribute && newNode.removeAttribute('aria-hidden');
4608+
try { newNode.style.display = ''; newNode.style.opacity = ''; newNode.style.pointerEvents = ''; } catch (e) {}
4609+
state.originalNode = newNode;
4610+
clearState();
4611+
showToast && showToast('已用备份恢复(原始元素被移除)');
4612+
return true;
4613+
}
4614+
}
4615+
}
4616+
4617+
clearState();
4618+
showToast && showToast('无法恢复 bm 面板(原始节点丢失)');
4619+
return false;
4620+
} catch (e) {
4621+
clearState();
4622+
showToast && showToast('恢复失败');
4623+
return false;
4624+
}
4625+
}
4626+
4627+
function toggle() {
4628+
try {
4629+
if (state.isHidden) {
4630+
doRestore();
4631+
return;
4632+
}
4633+
const cand = findBmCandidate();
4634+
if (!cand) {
4635+
showToast && showToast('未找到 bm 面板');
4636+
return;
4637+
}
4638+
doHide(cand);
4639+
showToast && showToast('已隐藏 bm 面板,按 Z 可复原');
4640+
} catch (e) {}
4641+
}
4642+
4643+
function onKeyDown(e) {
4644+
try {
4645+
if (e && e.repeat) return;
4646+
const active = document.activeElement;
4647+
const tag = (active && active.tagName || '').toLowerCase();
4648+
if (active && (active.isContentEditable || tag === 'input' || tag === 'textarea' || tag === 'select')) return;
4649+
if (e.key === 'z' || e.key === 'Z') {
4650+
e.preventDefault && e.preventDefault();
4651+
e.stopPropagation && e.stopPropagation();
4652+
toggle();
4653+
}
4654+
} catch (e) {}
4655+
}
4656+
4657+
window.addEventListener('keydown', onKeyDown, true);
4658+
4659+
window.__wplace_z_bm_dashdash = {
4660+
toggle: toggle,
4661+
hide: function() { const c = findBmCandidate(); return c ? doHide(c) : false; },
4662+
restore: doRestore,
4663+
find: findBmCandidate,
4664+
status: function() { return { isHidden: !!state.isHidden, hasOriginal: !!state.originalNode, parent: state.parent || null }; },
4665+
uninstall: function() {
4666+
try { window.removeEventListener('keydown', onKeyDown, true); } catch (e) {}
4667+
window.__wplace_z_bm_dashdash_installed = false;
4668+
}
4669+
};
4670+
4671+
} catch (e) {
4672+
console.warn('installZToggleForBmDashDash failed', e);
4673+
}
4674+
})();

0 commit comments

Comments
 (0)