mirror of
https://github.com/phantomptr/ps5upload.git
synced 2026-10-21 19:33:08 -05:00
- The build rewrote start/end corners and positions with :lang(ar,fa,…) language lists, which Chromium before 141 (Android's WebView) drops: split buttons were square and start/end-placed controls sat wrong. Each list is now split into one language per check (postcss/langLists.mjs, run on the built CSS). - Home's action tiles stack the icon above the label on a phone; the labels broke mid-word. - Payloads' search box takes its own row on a phone instead of shrinking to nothing. - After Resend helper, pairing keeps checking for a minute, not 16 s. - Reverts the Android blur change: the doubled title was the emulator's software rendering, gone with its GPU on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
55 lines
2.4 KiB
JavaScript
55 lines
2.4 KiB
JavaScript
// Split `:lang(a,b,c)` language lists in the built stylesheet.
|
|
//
|
|
// The build targets old WebKit (safari13), so the minifier rewrites logical properties
|
|
// (`rounded-s-full`, `start-3`, `border-s`…) into left/right pairs picked by language:
|
|
//
|
|
// .rounded-s-full:not(:lang(ae,ar,…,yi)) { border-top-left-radius: … }
|
|
// .rounded-s-full:lang(ae,ar,…,yi) { border-top-right-radius: … }
|
|
//
|
|
// A language LIST inside :lang() is newer than the rest of that output: Chromium before
|
|
// 141 (Android System WebView on most phones, older WebView2) drops both rules, which
|
|
// left every split button square-cornered and every start/end-positioned control
|
|
// misplaced on Android. One language per :lang() works everywhere:
|
|
//
|
|
// :not(:lang(ae,ar,fa)) -> :not(:lang(ar)):not(:lang(fa))
|
|
// .x:lang(ae,ar,fa) -> .x:lang(ar), .x:lang(fa) (only the right-to-left
|
|
// languages the app ships)
|
|
//
|
|
// Run on the final CSS (vite.config.ts, generateBundle), after the minifier wrote it.
|
|
import postcss from "postcss";
|
|
|
|
/** Right-to-left languages the app has a translation for (client/src/i18n/locales). */
|
|
export const SHIPPED_RTL = ["ar", "fa"];
|
|
|
|
const NOT_LIST = /:not\(:lang\(([a-z-]+(?:,[a-z-]+)+)\)\)/gi;
|
|
const LIST = /:lang\(([a-z-]+(?:,[a-z-]+)+)\)/i;
|
|
|
|
function splitSelector(sel) {
|
|
// Only the languages the app can be set to need excluding; the rest never occur, and
|
|
// each extra :not() would add to the rule's specificity.
|
|
const negated = sel.replace(NOT_LIST, (_, list) =>
|
|
list
|
|
.split(",")
|
|
.filter((l) => SHIPPED_RTL.includes(l))
|
|
.map((l) => `:not(:lang(${l}))`)
|
|
.join(""),
|
|
);
|
|
const m = LIST.exec(negated);
|
|
if (!m) return [negated];
|
|
const langs = m[1].split(",").filter((l) => SHIPPED_RTL.includes(l));
|
|
// Expand one list at a time; a selector with two lists is expanded again.
|
|
return langs.flatMap((l) => splitSelector(negated.replace(m[0], `:lang(${l})`)));
|
|
}
|
|
|
|
export function splitLangLists(css) {
|
|
if (!css.includes(":lang(") || !/:lang\([a-z-]+,/i.test(css)) return css;
|
|
const root = postcss.parse(css);
|
|
root.walkRules((rule) => {
|
|
if (!/:lang\([a-z-]+,/i.test(rule.selector)) return;
|
|
const selectors = rule.selectors.flatMap(splitSelector);
|
|
if (selectors.length === 0) rule.remove();
|
|
else rule.selectors = selectors;
|
|
});
|
|
return root.toResult({ map: false }).css.replace(/,\s*\n\s*/g, ",");
|
|
}
|