Skip to content

WEBDEV-8840: Put the ia-reviews network calls behind an injectable service - #122

Open
jbuckner wants to merge 27 commits into
mainfrom
WEBDEV-8840-review-service
Open

jbuckner wants to merge 27 commits into
mainfrom
WEBDEV-8840-review-service

Conversation

@jbuckner

Copy link
Copy Markdown
Collaborator

Stacked on #110. Ports internetarchive/iaux-reviews#59 onto ia-reviews now that reviews live here.

ia-review-form and ia-review stop building URLs and calling fetch. They hand a typed object to a ReviewService and render what comes back.

  • The token goes out as an X-CSRF-Token header from the fetch handler, so it's out of the hidden field_reviewtoken input and the delete query string.
  • Delete sends credentials and reports the server's error.
  • ia-reviews takes a reviewService. Without one it builds a default from baseHost, which renders fine but can't write since it has no token.
  • token, endpointPath and fetchHandler are gone from ia-reviews, and token / baseHost / endpointPath / csrfToken from the two inner elements. Offshoot and petabox are the only consumers and both move in WEBDEV-8840.

Consumers: offshoot !1268 and petabox !6435.

https://webarchive.jira.com/browse/WEBDEV-8840

🤖 Generated with Claude Code

https://claude.ai/code/session_015pmQ4SrFjLJ9gdGh4SZCkz

jbuckner and others added 12 commits September 21, 2026 12:33
Brings @internetarchive/reviews 1.0.8 across as ia-reviews, ia-review and
ia-review-form, with a demo story and the utils and icons they need.

Adapted to this repo: tests moved to vitest and co-located, customElement
from @src/util/custom-element like the other 28 components, classes on the
IA prefix, and fetch-handler in place of the deprecated
fetch-handler-service. The a11y assertions run on axe-core directly, since
vitest-axe is node-only and the suite runs in real Chromium.

Fixes carried in the move:

- A review body could inject attributes onto the rendered link. The URL
  pattern allowed a quote, the match is interpolated into an anchor and
  rendered with unsafeHTML, and DOMPurify runs before that, so
  `archive.org/x"onmouseover="alert(1)` became a live handler. Quotes and
  angle brackets now end a match, and the href is escaped.
- Delete reported success on any response, because fetch resolves on a 500.
- Delete parameters went unencoded into a query string, so a screenname
  with a space or an ampersand corrupted the request.
- sanitizeReviewBody registered a DOMPurify hook per call on the shared
  singleton, stacking up one per review and reaching other callers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
Matches the newer components here, which keep glyphs as standalone assets
rather than inline lit templates. The class each svg carried moves onto the
img that renders it, so the existing CSS and test selectors still find them.

Drops add-icon and reviews-icon, which nothing imported, and fixes
star-basic's fill, which was "2C2C2C" with no leading hash and so rendered
black rather than grey.

An svg with no intrinsic size renders 300x150 inside an img, so the two
sizes that were previously implicit are pinned by tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
The component only offers its own "write a review" link when an item has
no reviews yet, so with the demo's three reviews the form was unreachable.
A host page supplies its own button and sets displayReviewForm on the
element; the story now does the same and the usage notes say so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
ia-review truncates a body past 150 characters and offers More/Less, but
every body in the story sat under that, so the demo never showed it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
The demo submitted new reviews as "Ada Fielding", who already has one in
the list, so a review you just wrote looked like it had been attributed to
someone else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
Both whitespace patterns were character classes with a pipe inside, so a
pipe in a review body counted as whitespace: "Rated 8|10 overall" came out
as "Rated 8 10 overall". The classes now list only real whitespace, and
the newline pattern groups \r\n instead of spreading it across a class.

Reported by GitHub code quality on #110, which flagged the duplicate \n in
the second class. The stray pipe was the part that showed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
The submit button's spinner came from @internetarchive/ia-activity-indicator.
ia-status-indicator covers it in loading mode, so the form uses that and the
external dependency goes. hideDots gives the bare ring the button wants, and
the colour and size come through the theme variables rather than the old
component's own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
The four buttons were native elements wearing ia-styles' .ia-button
classes. They're ia-button now: mode="link" for the two in the messages,
secondary for Cancel, primary for Submit.

ia-button renders its own loading state, so the submit spinner and the
ia-status-indicator wiring behind it go away, and @internetarchive/ia-styles
is no longer a dependency. That was the last package here built against
lit 2, so the CSSResult casts go with it.

The link buttons sit inside a sentence, so they reach through
::part(button) to undo the flex display that would otherwise break the
line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CyEq51DigmsmwGsa7fEqWS
…eviews

* origin/main:
  1.1.1 (#118)
  WEBDEV-9132: Fix Safari image-viewer wide-layout breakpoint (#115)
  1.1.0 (#116)
  WEBDEV-9129: Exclude story files from coverage reporting (#113)
  WEBDEV-9121: Migrate histogram-date-range into elements (#112)
  WEBDEV-9130: Exclude nested dist and worktree tests from local runs (#114)
  v1.0.0 (#111)

# Conflicts:
#	package.json
#	pnpm-lock.yaml
…rvice

The form and the review no longer build URLs or call fetch themselves. Both hand a
typed object to a ReviewService and render what comes back. The CSRF token goes out
as an X-CSRF-Token header from the fetch handler, so it's out of the hidden form
field and the delete query string, and delete now sends credentials.

Ported from internetarchive/iaux-reviews#59.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015pmQ4SrFjLJ9gdGh4SZCkz
@jbuckner
jbuckner added this pull request to stack #123 September 30, 2026 18:25
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

🚀 View preview at
https://internetarchive.github.io/elements/pr/pr-122/

Built to branch ghpages at 2026-10-14 18:33 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

…eviews

* origin/main:
  WEBDEV-9160: Update to pnpm 12 (#119)
  1.1.2 (#121)
  WEBDEV-9192: Make the radio player's waveform music zones opt-in (#120)
…o WEBDEV-8840-review-service

* origin/WEBDEV-9107-migrate-reviews:
  1.1.3-webdev-9107.0
  WEBDEV-9160: Update to pnpm 12 (#119)
  1.1.2 (#121)
  WEBDEV-9192: Make the radio player's waveform music zones opt-in (#120)

# Conflicts:
#	package.json
@codecov-commenter

codecov-commenter commented Sep 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.20290% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.58%. Comparing base (b13a6e7) to head (40107e4).

Files with missing lines Patch % Lines
src/elements/ia-reviews/ia-review.ts 75.00% 0 Missing and 2 partials ⚠️
...rc/elements/ia-reviews/mocks/mock-fetch-handler.ts 75.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #122      +/-   ##
==========================================
+ Coverage   90.38%   90.58%   +0.19%     
==========================================
  Files         126      128       +2     
  Lines        4451     4491      +40     
  Branches     1023     1038      +15     
==========================================
+ Hits         4023     4068      +45     
+ Misses        192      187       -5     
  Partials      236      236              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

jbuckner and others added 8 commits October 6, 2026 14:54
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RgyoVnVd6Wt6HHbGy3Vuvh
Delete calls the global fetch, so the demo's stub fetchHandler never saw it
and a click posted to archive.org and failed on CORS.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RgyoVnVd6Wt6HHbGy3Vuvh
Keeps this branch's story: delete goes through the review service here, so
the demo needs no global fetch stub.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RgyoVnVd6Wt6HHbGy3Vuvh
* origin/main:
  1.1.6 (#145)
  WEBDEV-9329: Update the Firefox add-on link in ia-topnav (#143)
  WEBDEV-9241: Add ia-wayback-search-form for the home page Wayback block (#134)
  WEBDEV-9219: Localize the topnav strings (#125)
  WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98)
  WEBDEV-9038: Migrate the topnav into elements (#95)
* origin/WEBDEV-9107-migrate-reviews:
  1.1.6 (#145)
  WEBDEV-9329: Update the Firefox add-on link in ia-topnav (#143)
  WEBDEV-9241: Add ia-wayback-search-form for the home page Wayback block (#134)
  WEBDEV-9219: Localize the topnav strings (#125)
  WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98)
  WEBDEV-9038: Migrate the topnav into elements (#95)
* origin/main:
  WEBDEV-9052: Migrate edit-donation into elements (#100)
* origin/WEBDEV-9107-migrate-reviews:
  WEBDEV-9052: Migrate edit-donation into elements (#100)
Base automatically changed from WEBDEV-9107-migrate-reviews to main October 14, 2026 18:30
* commit 'bf2e1a16':
  WEBDEV-9221: Localize the topnav menu labels (#132)
  WEBDEV-9250: Fix the topnav font size (#146)
  WEBDEV-9599: Close the media menu on subnav click (#184)
  WEBDEV-9445: Move the other elements icons into the icons folder (#167)
  WEBDEV-9439: Add the icons folder, build step and export map (#153)
  WEBDEV-9053: Migrate the donation form payment layer into elements (#103)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants