Repository navigation
Find end tags in place instead of in a lowercased copy - #151
Merged
Merged
Conversation
Five places lowercased a whole page or text, searched the copy, and used
the offsets they found on the original. Unicode lowercasing can lengthen a
string ("İ" becomes two characters), so after such a character every
offset pointed past the text it named:
- preserved-targets (compiler and language server): the end of a <title>,
<style>, <script> or <textarea> landed past the next tag, so its classes
and ids were left out of the preserved/scoped split.
- generated-id-classes: an #id collision in a <style> was reported at the
wrong line and column.
- docs search: the result snippet could slide past the match.
- the skills' link checker and SEO audit: the end of a masked element
landed past the next tag, which skipped its links, headings and images.
Tag names are now compared in place, in ASCII case, as an HTML parser
compares them. The docs search keeps Unicode-aware matching for what a
reader types and maps the match back to the original text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Shop preview: https://bascik-shop-pr-151.collin-inbox.workers.dev Stripe sandbox payments are enabled. Paid orders create unconfirmed Printful drafts only. Production confirmation and customer email are blocked in test mode. No live domain changes. |
Site PreviewsBuilt from c1713a2 on
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For the 1.0.0 release. Found while fixing the flaky language-server linear-time test, which had the same pattern in its block scanner (that fix is on its own branch,
pre-release-20261112).The bug
Five places lowercased a whole page or text, searched the lowercased copy, and then used the positions they found on the original. That only works while both strings are the same length, and Unicode lowercasing can make a string longer:
"İ".toLowerCase()is two characters. After everyİ, the positions point one character further past what they name.pkg/src/lib/preserved-targets.tsand its identical copy inlsp/src/<title>,<style>,<script>or<textarea>lands too far, so classes and ids on the tags right after it can be skipped. This feeds the compiler's scoping split between preserved and scoped classes, and the editor's view of it. Twelveİin a component's<title>were enough to drop the<p class="kept">after it.pkg/src/lib/generated-id-classes.ts#idcollision found in a<style>element is reported at the wrong line and column.docs/src/components/docs-search/search-logic.tsskills/bascik/scripts/check-links.mjs,skills/bascik-seo/scripts/audit-seo.mjsİ(U+0130) is the only character whose lowercase is longer. Nothing in the repo uppercases whole documents, where many more characters change length (ßbecomesSS).The fix
Tag names are compared in place, in ASCII case, which is how an HTML parser compares them, and no copy of the page is made. The two
preserved-targets.tscopies stay byte-identical (a test checks that).The docs search still matches what a reader types without regard to case, Unicode included, and maps the match position back to the original text. It only does the extra work when lowercasing changed the length.
Not changed
component-props.tslowercases a template only for a yes/noincludespre-check and never uses positions from it, so it isn't affected..agents/skills/holds installed, hash-locked copies of the skills scripts. They pick up this fix with the next skills refresh.Tests
Each fix has a test with
İbefore the affected tag or text. I confirmed all five fail without the fix. Thepreserved-targetstest also covers mixed-case raw-text tags (<TITLE>…</Title >).Verification
🤖 Generated with Claude Code