// ==UserScript==
// @name wnacg 優化
// @name:zh-TW wnacg 優化
// @name:zh-CN wnacg 优化
// @name:ja wnacg 最適化
// @name:en wnacg Optimization
// @version 0.0.14
// @author Canaan HS
// @description 電腦版頁面支持切換自動翻頁或手動按鍵翻頁,並可自定背景顏色及圖像大小。電腦開啟的手機頁面 (移動端不適用),則可自定背景顏色及圖像大小。
// @description:zh-TW 電腦版頁面支持切換自動翻頁或手動按鍵翻頁,並可自定背景顏色及圖像大小。電腦開啟的手機頁面 (移動端不適用),則可自定背景顏色及圖像大小。
// @description:zh-CN 电脑版页面支持切换自动翻页或手动按键翻页,并可自定背景颜色及图像大小。电脑开启的手机页面(移动端不适用),则可自定背景颜色及图像大小。
// @description:ja デスクトップ版ページでは、自動ページ送りと手動キー操作によるページ送りの切り替えができ、背景色と画像サイズをカスタマイズできます。デスクトップで開いたモバイルページ(モバイル端末では適用されません)では、背景色と画像サイズをカスタマイズできます。
// @description:en The desktop version supports switching between automatic page turning and manual key press page turning, with customizable background color and image size. The mobile version opened on a desktop (not applicable on mobile devices) allows for customizing the background color and image size.
// @match *://*.wnacg.com/photos-view-id-*.html
// @match *://*.wnacg01.ru/photos-view-id-*.html
// @match *://*.wnacg02.ru/photos-view-id-*.html
// @match *://*.wnacg03.ru/photos-view-id-*.html
// @match *://*.wnacg.com/photos-slist-aid-*.html
// @match *://*.wnacg01.ru/photos-slist-aid-*.html
// @match *://*.wnacg02.ru/photos-slist-aid-*.html
// @match *://*.wnacg03.ru/photos-slist-aid-*.html
// @icon https://www.wnacg.com/favicon.ico
// @license MIT
// @namespace https://greasyfork.org/users/989635
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_registerMenuCommand
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.14.0/jquery-ui.min.js
// @require https://update.greasyfork.org/scripts/495339/1456526/ObjectSyntax_min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js
// ==/UserScript==
(async () => {
async function w(b, e) {
document.title = document.title.split(" - ")[1];
const f = Syn.$$("a", { root: b }).href,
q = Syn.$$("img", { root: b }).src;
if (h.SwitchStatus) {
let p = Syn.$$("select option", { all: !0 }).length - e;
const n = new IntersectionObserver(
(c) => {
c.forEach((a) => {
a.isIntersecting &&
(history.pushState(null, null, a.target.alt),
n.unobserve(a.target));
});
},
{ threshold: 0.3 }
);
function l({ OLink: c, src: a }) {
return React.createElement("img", {
src: a,
alt: c,
loading: "lazy",
className: "ImageOptimization",
ref: function (d) {
d && n.observe(d);
},
});
}
async function m(c) {
0 < p &&
fetch(c)
.then((a) => a.text())
.then((a) => {
a = Syn.$$("#photo_body", { root: Syn.DomParse(a) });
const d = Syn.$$("a", { root: a }).href;
a = Syn.$$("img", { root: a }).src;
ReactDOM.render(
React.createElement(l, { OLink: c, src: a }),
b.appendChild(document.createElement("div"))
);
setTimeout(() => {
p--;
m(d);
}, 500);
})
.catch((a) => {
m(c);
});
}
ReactDOM.render(
React.createElement(l, { OLink: Syn.Device.Url, src: q }),
b
);
Syn.$$("#header").scrollIntoView();
m(f);
} else {
function p({ number: c, src: a }) {
return React.createElement("img", {
src: a,
"data-number": c,
className: "ImageOptimization",
});
}
async function n(c) {
fetch(c)
.then((a) => a.text())
.then((a) => {
a = Syn.DomParse(a);
var d = Syn.$$("#photo_body", { root: a });
d = Syn.$$("img", { root: d }).src;
ReactDOM.render(React.createElement(p, { number: l, src: d }), b);
a = Syn.$$(".newpage .btntuzao", { all: !0, root: a });
m.set(l, { PrevLink: a[0].href, NextLink: a[1].href });
history.pushState(null, null, c);
window.scrollTo(0, 0);
});
}
let l = e;
const m = new Map();
e = Syn.$$(".newpage .btntuzao", { all: !0 });
m.set(l, { PrevLink: e[0].href, NextLink: e[1].href });
ReactDOM.render(
React.createElement(p, { number: l, NLink: f, src: q }),
b
);
document.onkeydown = void 0;
u(window, "keydown", (c) => {
var a = c.key;
if ("ArrowLeft" == a || "4" == a)
c.stopImmediatePropagation(),
--l,
(c = +Syn.$$("img", { root: b }).getAttribute("data-number")),
(a = m.get(c - 1)) ? n(a.PrevLink) : n(m.get(c).PrevLink);
else if ("ArrowRight" == a || "6" == a)
c.stopImmediatePropagation(),
++l,
(c = +Syn.$$("img", { root: b }).getAttribute("data-number")),
(c = m.get(c).NextLink),
n(c);
});
}
}
async function u(b, e, f) {
$(b).on(e, f);
}
async function v(b = !1) {
if (Syn.$$(".modal-background")) b && Syn.$$(".modal-background").remove();
else {
var {
SwitchStatus: e,
ImageBasicWidth: f,
ImageMaxWidth: q,
ImageBasicHight: p,
ImageMaxHight: n,
ImageSpacing: l,
BackgroundColor: m,
} = h.LoadingConfig();
b = [];
for (var c of [l, f, q, p, n, m]) b.push(h.ConfigAnalyze(c));
c = h.IsMobile
? ""
: `
<div class="DMS">
<input type="checkbox" class="DMS-checkbox" id="SwitchMode" ${
e ? "checked" : ""
}>
<label class="DMS-label" for="SwitchMode">
<span class="DMS-inner"></span>
<span class="DMS-switch"></span>
</label>
</div>
`;
b = `
<div class="modal-background">
<div class="modal-interface">
<div style="display: flex; justify-content: space-between;">
<h1 style="margin-bottom: 1rem; font-size: 1.3rem;">${h.Transl(
"\u5716\u50cf\u8a2d\u7f6e"
)}</h1>${c}
</div>
<p>
<Cins>${h.Transl(
"\u5716\u50cf\u9593\u8ddd"
)}</Cins><input type="range" id="ImageSpacing" class="slider" min="0" max="100" step="1" value="${
b[0].RangeValue
}">
<span class="Cshow">${b[0].DisplayText}</span>
</p>
<br>
<p>
<Cins>${h.Transl(
"\u57fa\u672c\u5bec\u5ea6"
)}</Cins><input type="range" id="ImageBasicWidth" class="slider" min="9" max="100" step="1" value="${
b[1].RangeValue
}">
<span class="Cshow">${b[1].DisplayText}</span>
</p>
<br>
<p>
<Cins>${h.Transl(
"\u6700\u5927\u5bec\u5ea6"
)}</Cins><input type="range" id="ImageMaxWidth" class="slider" min="9" max="100" step="1" value="${
b[2].RangeValue
}">
<span class="Cshow">${b[2].DisplayText}</span>
</p>
<br>
<p>
<Cins>${h.Transl(
"\u57fa\u672c\u9ad8\u5ea6"
)}</Cins><input type="range" id="ImageBasicHight" class="slider" min="9" max="100" step="1" value="${
b[3].RangeValue
}">
<span class="Cshow">${b[3].DisplayText}</span>
</p>
<br>
<p>
<Cins>${h.Transl(
"\u6700\u5927\u9ad8\u5ea6"
)}</Cins><input type="range" id="ImageMaxHight" class="slider" min="9" max="100" step="1" value="${
b[4].RangeValue
}">
<span class="Cshow">${b[4].DisplayText}</span>
</p>
<br>
<p>
<Cins>${h.Transl(
"\u80cc\u666f\u984f\u8272"
)}</Cins><input type="color" id="BackgroundColor" class="color" value="${
b[5].RangeValue
}">
<span style="margin-right: 17.9rem;"></span><button id="SaveConfig" class="button-sty">${h.Transl(
"\u4fdd\u5b58\u8a2d\u7f6e"
)}</button>
</p>
</div>
</div>
`;
$(document.body).append(b);
$(".modal-interface").draggable({
scroll: !0,
opacity: 0.8,
cursor: "grabbing",
});
var a, d, r;
u("#BackgroundColor", "input", (k) => {
a = k.target.id;
d = $(k.target).val();
h.StylePointer[a](d);
});
u("#ImageSpacing", "input", (k) => {
r = $(k.target).next(".Cshow");
a = k.target.id;
d = $(k.target).val();
h.StylePointer[a](`${d}rem`);
r.text(`${d}rem`);
});
u("#ImageBasicWidth, #ImageMaxWidth", "input", (k) => {
r = $(k.target).next(".Cshow");
a = k.target.id;
d = $(k.target).val();
"9" === d
? (h.StylePointer[a]("auto"), r.text("auto"))
: (h.StylePointer[a](`${d}%`), r.text(`${d}%`));
});
u("#ImageBasicHight, #ImageMaxHight", "input", (k) => {
r = $(k.target).next(".Cshow");
a = k.target.id;
d = $(k.target).val();
"9" === d
? (h.StylePointer[a]("auto"), r.text("auto"))
: (h.StylePointer[a](`${d}rem`), r.text(`${d}rem`));
});
u("#SaveConfig", "click", function () {
const k = {};
k.SwitchStatus = $("#SwitchMode").prop("checked") ? !0 : !1;
var t = $(".modal-interface");
const g = t.css("top");
t = t.css("left");
k.MenuTop = g;
k.MenuLeft = t;
h.StylePointer.MenuTop(g);
h.StylePointer.MenuLeft(t);
$(".modal-interface")
.find("input")
.not("#SwitchMode")
.each(function () {
a = $(this).attr("id");
d = $(this).val();
k[a] =
"ImageSpacing" === a
? `${d}rem`
: "ImageBasicWidth" === a || "ImageMaxWidth" === a
? "9" === d
? "auto"
: `${d}%`
: "ImageBasicHight" === a || "ImageMaxHight" === a
? "9" === d
? "auto"
: `${d}rem`
: d;
});
Syn.Store("s", "Config", k);
$(".modal-background").remove();
});
}
}
(async () => {
Syn.Store("g", "Mode_V2", !1) && Syn.Store("d", "Mode_V2");
const b = Syn.Store("g", "Settings");
if (b) {
Syn.Store("d", "Settings");
const { ULS: e, BW: f, MW: q, BH: p, MH: n, BC: l, MT: m, ML: c } = b[0];
Syn.Store("s", "Config", {
SwitchStatus: !0,
MenuTop: m,
MenuLeft: c,
ImageBasicWidth: f,
ImageMaxWidth: q,
ImageBasicHight: p,
ImageMaxHight: n,
ImageSpacing: e,
BackgroundColor: l,
});
}
})();
const h = (() => {
const b = () =>
Syn.Store("g", "Config", null) ?? {
SwitchStatus: !0,
MenuTop: "auto",
MenuLeft: "auto",
ImageSpacing: "0rem",
ImageBasicWidth: "100%",
ImageMaxWidth: "60%",
ImageBasicHight: "auto",
ImageMaxHight: "auto",
BackgroundColor: "#000",
};
let e;
var f = {},
q = {
"\u5716\u50cf\u8a2d\u7f6e": "\u56fe\u50cf\u8bbe\u7f6e",
"\u5716\u50cf\u9593\u8ddd": "\u56fe\u50cf\u95f4\u8ddd",
"\u57fa\u672c\u5bec\u5ea6": "\u57fa\u672c\u5bbd\u5ea6",
"\u6700\u5927\u5bec\u5ea6": "\u6700\u5927\u5bbd\u5ea6",
"\u57fa\u672c\u9ad8\u5ea6": "\u57fa\u672c\u9ad8\u5ea6",
"\u6700\u5927\u9ad8\u5ea6": "\u6700\u5927\u9ad8\u5ea6",
"\u80cc\u666f\u984f\u8272": "\u80cc\u666f\u989c\u8272",
"\u4fdd\u5b58\u8a2d\u7f6e": "\u4fdd\u5b58\u8bbe\u7f6e",
"\u6efe\u52d5\u95b1\u8b80": "\u6eda\u52a8\u9605\u8bfb",
"\u7ffb\u9801\u95b1\u8b80": "\u7ffb\u9875\u9605\u8bfb",
"\ud83d\udd32 \u958b\u95dc\u83dc\u55ae": "\u5f00\u5173\u83dc\u5355",
};
f = {
"zh-TW": f,
"zh-HK": f,
"zh-MO": f,
"zh-CN": q,
"zh-SG": q,
"en-US": {
"\u5716\u50cf\u8a2d\u7f6e": "Image Settings",
"\u5716\u50cf\u9593\u8ddd": "Image ImageSpacing",
"\u57fa\u672c\u5bec\u5ea6": "Base Width",
"\u6700\u5927\u5bec\u5ea6": "Max Width",
"\u57fa\u672c\u9ad8\u5ea6": "Base Height",
"\u6700\u5927\u9ad8\u5ea6": "Max Height",
"\u80cc\u666f\u984f\u8272": "BackgroundColor Color",
"\u4fdd\u5b58\u8a2d\u7f6e": "Save Settings",
"\u6efe\u52d5\u95b1\u8b80": "Scroll Read",
"\u7ffb\u9801\u95b1\u8b80": "TurnPage Read",
"\ud83d\udd32 \u958b\u95dc\u83dc\u55ae": "Toggle Menu",
},
ja: {
"\u5716\u50cf\u8a2d\u7f6e": "\u753b\u50cf\u8a2d\u5b9a",
"\u5716\u50cf\u9593\u8ddd": "\u753b\u50cf\u9593\u9694",
"\u57fa\u672c\u5bec\u5ea6": "\u57fa\u672c\u5e45",
"\u6700\u5927\u5bec\u5ea6": "\u6700\u5927\u5e45",
"\u57fa\u672c\u9ad8\u5ea6": "\u57fa\u672c\u9ad8\u3055",
"\u6700\u5927\u9ad8\u5ea6": "\u6700\u5927\u9ad8\u3055",
"\u80cc\u666f\u984f\u8272": "\u80cc\u666f\u8272",
"\u4fdd\u5b58\u8a2d\u7f6e": "\u8a2d\u5b9a\u306e\u4fdd\u5b58",
"\u6efe\u52d5\u95b1\u8b80":
"\u30b9\u30af\u30ed\u30fc\u30eb\u8aad\u307f\u53d6\u308a",
"\u7ffb\u9801\u95b1\u8b80":
"\u30da\u30fc\u30b8\u8aad\u307f\u53d6\u308a",
"\ud83d\udd32 \u958b\u95dc\u83dc\u55ae":
"\u30e1\u30cb\u30e5\u30fc\u306e\u5207\u308a\u66ff\u3048",
},
};
const p = f[Syn.Device.Lang] ?? f["en-US"];
f = (g) => p[g] ?? g;
const {
SwitchStatus: n,
MenuTop: l,
MenuLeft: m,
ImageBasicWidth: c,
ImageMaxWidth: a,
ImageBasicHight: d,
ImageMaxHight: r,
ImageSpacing: k,
BackgroundColor: t,
} = b();
Syn.AddStyle(`
.ImageOptimization {
display: block;
margin: ${k} auto;
width: ${c};
height: ${d};
max-width: ${a};
max-height: ${r};
}
body {
overflow-x: visible !important;
background-color: ${t};
}
.tocaowrap {
width: 100%;
margin: 0 auto;
padding: 0.1rem;
max-width: ${a};
}
.btntuzao {
margin: 0 5px;
background-color: #5F5F5F;
}
a, em {
color: #fff;
}
#header {
background: #5F5F5F;
border-bottom: 1px solid #dfe1e1;
transform: translateY(-1.6rem);
opacity: 0;
transition: 0.8s;
}
#header:hover {
opacity: 1;
transform: translateY(0rem);
}
.nav li a {
float: left;
line-height: 40px;
height: 40px;
width: 85px;
font-size: 14px;
color: #fff;
text-decoration: none;
text-align: center;
font-weight: bold;
text-align: center;
background: #5F5F5F;
}
.modal-background {
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
z-index: 9999;
position: fixed;
overflow: auto;
pointer-events: none;
}
.modal-interface {
top: ${l};
left: ${m};
margin: auto;
color: #3d8fe7;
padding: 1% 2%;
border-radius: 5px;
background-color: #f3f3f3;
border: 2px solid #c0d8fc;
pointer-events: auto;
}
.slider {
width: 21rem;
cursor: pointer;
}
.color {
width: 4rem;
cursor: pointer;
}
.Cshow {
font-size: 1.25rem;
margin: auto 1rem;
font-weight: bold;
}
.button-sty {
color: #ffffff;
font-size: 1rem;
padding: 0.3rem;
font-weight: bold;
border-radius: 5px;
background-color: #3d8fe7;
border: 2px solid #f3f3f3;
}
.button-sty:hover,
.button-sty:focus {
color: #c0d8fc;
cursor: pointer;
text-decoration: none;
}
p {
display: flex;
align-items: center;
white-space: nowrap;
}
Cins {
font-size: 1.2rem;
font-weight: bold;
padding: 1rem;
margin-right: 1rem;
}
/*--------------------*/
.DMS {
position: absolute;
width: 8.2rem;
margin-left: 27rem;
}
.DMS-checkbox {
display: none;
}
.DMS-label {
display: block;
overflow: hidden;
cursor: pointer;
border: 2px solid #c0d8fc;
border-radius: 20px;
}
.DMS-inner {
display: block;
width: 200%;
margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.DMS-inner:before,
.DMS-inner:after {
display: block;
float: left;
width: 50%;
height: 30px;
padding: 0;
line-height: 30px;
font-size: 14px;
font-family: Trebuchet, Arial, sans-serif;
font-weight: bold;
box-sizing: border-box;
}
.DMS-inner:before {
content: "${f("\u6efe\u52d5\u95b1\u8b80")}";
padding-left: 1.7rem;
background-color: #3d8fe7;
color: #FFFFFF;
}
.DMS-inner:after {
content: "${f("\u7ffb\u9801\u95b1\u8b80")}";
padding-right: 1.5rem;
background-color: #FFFFFF;
color: #3d8fe7;
text-align: right;
}
.DMS-switch {
display: block;
width: 18px;
margin: 6px;
background: #FFFFFF;
position: absolute;
top: 0;
bottom: 0;
right: 96px;
border: 2px solid #999999;
border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.DMS-checkbox:checked+.DMS-label .DMS-inner {
margin-left: 0;
}
.DMS-checkbox:checked+.DMS-label .DMS-switch {
right: 0px;
}
`);
setTimeout(() => {
e = Syn.$$("#New-Style").sheet.cssRules;
}, 1300);
return {
IsMobile: Syn.Device.Url.includes("photos-slist-aid"),
LoadingConfig: b,
SwitchStatus: n,
ConfigAnalyze: (g) =>
"auto" === g
? { RangeValue: 9, DisplayText: "auto" }
: g.endsWith("rem") || g.endsWith("%")
? { RangeValue: parseInt(g), DisplayText: g }
: { RangeValue: g, DisplayText: "color" },
StylePointer: {
MenuTop: (g) => (e[9].style.top = g),
MenuLeft: (g) => (e[9].style.left = g),
ImageSpacing: (g) => (e[0].style.margin = `${g} auto`),
ImageBasicWidth: (g) => (e[0].style.width = g),
ImageMaxWidth: (g) => {
e[0].style.maxWidth = g;
e[2].style.maxWidth = g;
},
ImageBasicHight: (g) => (e[0].style.height = g),
ImageMaxHight: (g) => (e[0].style.maxHeight = g),
BackgroundColor: (g) => (e[1].style.background = g),
},
Transl: f,
};
})();
(async () => {
if ("Mobile" != Syn.Device.Type())
if (
(GM_registerMenuCommand(
h.Transl("\ud83d\udd32 \u958b\u95dc\u83dc\u55ae"),
() => v(!0)
),
Syn.AddListener(
window,
"keydown",
(b) => {
const e = b.key;
"Shift" === e
? (b.preventDefault(), v())
: "Escape" === e &&
(b.preventDefault(), Syn.$$(".modal-background")?.remove());
},
{ capture: !0 }
),
h.IsMobile)
) {
const b = new Map();
Syn.WaitElem(
"#img_list",
(e) => {
Syn.Observer(
e,
() => {
Syn.$$("div", { root: e, all: !0 }).forEach((f) => {
b.has(f) ||
(b.set(f, !0),
(f.style.cssText = "text-align: center"),
(f = Syn.$$("img", { root: f })),
f.removeAttribute("width"),
f.classList.add("ImageOptimization"));
});
},
{ throttle: 1500 }
);
},
{ raf: !0, timeout: 10 }
);
} else
Syn.WaitMap(
".png.bread;#bread;#photo_body;span.newpagelabel b;#bodywrap;.newpagewrap;.footer.wrap".split(
";"
),
(b) => {
const [e, f, q, p, n, l, m] = b;
ReactDOM.render(
React.createElement("div", {
dangerouslySetInnerHTML: { __html: e.innerHTML },
}),
f
);
q.classList.remove("photo_body");
[n, l, m].forEach((c) => {
c.style.display = "none";
});
w(q, +p.textContent);
},
{ raf: !0, timeout: 10 }
);
})();
})();