Skip to content

sync: dev to extern-contrib - #1037

Merged
PythonSmall-Q merged 21 commits into
extern-contribfrom
dev
Oct 4, 2026
Merged

PythonSmall-Q merged 21 commits into
extern-contribfrom
dev

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

sync-branches: New code has just landed in dev, so let's bring extern-contrib up to speed!

Summary by Sourcery

Improve monochrome navbar rendering and lifecycle handling across legacy and web interfaces.

Bug Fixes:

  • Fix monochrome navbar font rendering across legacy and web pages, including consistent Chinese glyph fallback.
  • Prevent fixed navbar layout issues when Bootstrap CSS is delayed or unavailable.
  • Preserve page-owned navbar styles and DOM elements while cleaning up replaced or disabled top bars.

Enhancements:

  • Unify navbar styling updates across both page types and safely manage refresh listeners and generated artifacts.
  • Centralize monochrome font loading and align project versioning at 3.8.2.

Tests:

  • Add coverage for shared font loading, navbar lifecycle and cleanup, fixed-navbar spacing, delayed Bootstrap loading, downloads placement, and language-independent glyph rendering.

@sourcery-ai

sourcery-ai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This sync updates the project to 3.8.1, unifies monochrome font loading across UI modes, hardens navbar styling against repeated refreshes and DOM replacement while preserving page-owned styles and elements, and adds focused browser/unit coverage for these behaviors and downloads layout.

Sequence diagram for resilient navbar styling refresh

sequenceDiagram
    participant UI as Contest or legacy UI
    participant Update as UpdateNavbarStyler
    participant Styler as NavbarStyler
    participant DOM as Navbar DOM

    UI->>Update: UpdateNavbarStyler()
    Update->>DOM: querySelector(.navbar.navbar-expand-lg.bg-body-tertiary)
    alt Navbar replaced or top bar disabled
        Update->>Styler: destroy()
        Styler->>DOM: restore preserved styles and classes
        Styler->>DOM: remove owned overlay and spacer
    end
    alt Navbar exists and NewTopBar enabled
        Update->>Styler: new NavbarStyler(navbar)
        Styler->>DOM: init()
        Styler->>DOM: createOverlay()
        Styler->>DOM: createSpacer()
        Styler->>DOM: updateBlurOverlay()
    end
Loading

Flow diagram for unified monochrome font loading

flowchart TD
    A[Monochrome UI enabled] --> B{Font link already exists?}
    B -->|Yes| C[Reuse existing link]
    B -->|No| D["LoadMonochromeFonts()"]
    D --> E[Create stylesheet link]
    E --> F[Append link to document head]
    C --> G[Apply monochrome UI]
    F --> G
Loading

File-Level Changes

Change Details Files
Centralize monochrome font loading across legacy and web UI initialization paths.
  • Add an idempotent font stylesheet loader with head/document fallback.
  • Invoke it during early initialization and both legacy and contest-web setup.
  • Add coverage for enabled/disabled settings, bootstrap cache states, and repeated calls.
XMOJ.user.js
tests/contest-web.test.cjs
Make navbar styling lifecycle-safe across repeated polling and Vue DOM replacements.
  • Reuse a single NavbarStyler instance and resize listener.
  • Destroy stale instances when the navbar changes or the feature is disabled.
  • Restore original inline styles/classes and remove only generated overlays and spacers.
  • Reuse page-owned overlay/spacer elements while preserving their styles.
  • Update spacer height in place and avoid interfering with page containers.
XMOJ.user.js
Update the downloads page integration to remain below the fixed navbar.
  • Exercise downloads rendering with the new navbar spacer and verify content stays in the page container.
  • Verify spacing tracks navbar height changes.
tests/navbar-styler.test.cjs
Bump the release version and expand the automated test command.
  • Update userscript and package versions from 3.8.0 to 3.8.1.
  • Include navbar lifecycle and downloads tests in npm test.
XMOJ.user.js
package.json
Add an update metadata file for the branch synchronization.
  • Introduce the new update manifest content.
Update.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Deploying xmoj-script-dev-channel with  Cloudflare Pages  Cloudflare Pages

Latest commit: 11dd0db
Status: ✅  Deploy successful!
Preview URL: https://c03be34c.xmoj-script-dev-channel.pages.dev

View logs

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="XMOJ.user.js" line_range="2941-2945" />
<code_context>
             `;
                 document.head.appendChild(style);
             }
+            const overlay = document.getElementById('blur-overlay');
+            if (overlay !== this.overlay && overlay !== this.borrowedOverlay) {
+                this.borrowedOverlay = overlay;
+                this.restoreOverlayStyles = this.preserveStyles(overlay, ['top', 'left', 'width', 'height']);
+            }
         } catch (e) {
             console.error(e);
</code_context>
<issue_to_address>
**issue (bug_risk):** When a page-owned `blur-overlay` or `navbar-spacer` is replaced before the next `UpdateNavbarStyler()` call, the new element overwrites `restoreOverlayStyles` or `restoreSpacerStyles` while the old modified element is no longer tracked. Teardown restores only the replacement, leaving the original page-owned element with XMOJ's dimensions.

**Triggers:** When Vue or another page handler replaces an existing page-owned overlay or spacer between navbar refreshes.

**Suggested fix:** Restore the previously borrowed element before replacing its restore callback, or track each borrowed element and its restoration callback independently.
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: XMOJ.user.js:2945


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread XMOJ.user.js
Comment on lines +2941 to +2945
const overlay = document.getElementById('blur-overlay');
if (overlay !== this.overlay && overlay !== this.borrowedOverlay) {
this.borrowedOverlay = overlay;
this.restoreOverlayStyles = this.preserveStyles(overlay, ['top', 'left', 'width', 'height']);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): When a page-owned blur-overlay or navbar-spacer is replaced before the next UpdateNavbarStyler() call, the new element overwrites restoreOverlayStyles or restoreSpacerStyles while the old modified element is no longer tracked. Teardown restores only the replacement, leaving the original page-owned element with XMOJ's dimensions.

Triggers: When Vue or another page handler replaces an existing page-owned overlay or spacer between navbar refreshes.

Suggested fix: Restore the previously borrowed element before replacing its restore callback, or track each borrowed element and its restoration callback independently.

@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Oct 4, 2026
@hendragon-bot hendragon-bot Bot added the user-script This issue or pull request is related to the main user script label Oct 4, 2026
@PythonSmall-Q
PythonSmall-Q merged commit f496164 into extern-contrib Oct 4, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL user-script This issue or pull request is related to the main user script

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants