Skip to content

Recognize import and image-set strings as CSS URLs - #316

Merged
adamziel merged 14 commits into
trunkfrom
codex/css-url-contexts
Sep 9, 2026
Merged

Recognize import and image-set strings as CSS URLs#316
adamziel merged 14 commits into
trunkfrom
codex/css-url-contexts

Conversation

@adamziel

@adamziel adamziel commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Finds CSS resource URLs written as quoted strings in @import, image-set(), and -webkit-image-set(), so existing callers can rewrite them through next_url() and set_raw_url().

For this CSS:

@import "theme.css";
.hero {
  background-image: image-set(
    "hero.avif" type("image/avif") 1x,
    url("hero@2x.png") 2x
  );
  content: "not-a-url.png";
}

Before this PR, next_url() returned only hero@2x.png, because it was wrapped in url(). It now returns all three resource URLs, in source order:

theme.css
hero.avif
hero@2x.png

image/avif is a MIME type and not-a-url.png is displayed text; neither is returned as a URL. -webkit-image-set() gets the same treatment as image-set().

Review order: #315 (merged) → #316#317#314.

URL context is tracked directly in next_url(), without a separate helper or lookahead loop. Comments and malformed string or URL tokens are not returned. The nesting limit counts image-set() functions open at the same time: the 129th is rejected. It does not limit the number of images in one set or separate image sets in the stylesheet.

This is layer 2 of the CSS stack. #315 is merged; this PR now targets trunk. It changes URL recognition only. Streamed input and saved cursors come in the next layer; URL mappings and rewrite_chunk() remain in #314.

Testing

A separate PHP process rewrites a real file containing imports, image sets, and non-URL text. Another file exceeds the nesting limit and must leave the previous output untouched. All three new tests fail against the preceding layer. The full DataLiberation run completed with 2,426 tests and 16 skips. PHPCS passes. The example above was also run against both trunk and this branch to check the before-and-after URL lists.

Base automatically changed from codex/css-prefix-edits to trunk September 8, 2026 18:32
@adamziel
adamziel merged commit e60cab9 into trunk Sep 9, 2026
29 checks passed
@adamziel
adamziel deleted the codex/css-url-contexts branch September 9, 2026 16:03
adamziel added a commit that referenced this pull request Sep 9, 2026
Lets a CSS token span input chunks and continue in a new PHP process
without restarting the file.

Review order: #315 (merged) → #316#317#314.

The processor keeps unfinished input and parses it again after another
read. Whole strings and streamed input use the same `next_token()`,
getters, and value setter. `flush_processed_css()` returns edited,
completed input and releases its source bytes. The cursor contains the
remaining bytes and whether more input is expected; the caller saves it
with the source and output offsets after writing the output.

This is layer 3 of the CSS stack, based on #316. It adds input,
flushing, and the token cursor together. It contains no URL mappings or
`rewrite_chunk()`; those remain in #314. ASCII spans are scanned
together so reparsing long identifiers and URLs does not walk every byte
in PHP.

A large token increases memory use, cursor size, and repeated parsing
work. Token size is not capped. The README spells out that cost and
links the real-file caller.

## Testing

The streamed tokens match the whole-string corpus, including one-byte
reads, escapes, and invalid UTF-8. Separate PHP processes edit a
multi-chunk file, stop before or after a saved checkpoint, and resume
with the unfinished token. The written file must match whole-string
edits without missing or duplicated bytes. The full DataLiberation run
completed with 2,618 tests and 16 skips. PHPCS passes.
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.

1 participant