-
Notifications
You must be signed in to change notification settings - Fork 0
Precursor to YPE-641: transform html for highlights #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Precursor to YPE-641: transform html for highlights #103
Conversation
🦋 Changeset detectedLatest commit: dc3f52d The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Greptile SummaryRefactored Bible verse HTML transformation to wrap verse content in
This is a precursor to YPE-641 (highlights feature), establishing the DOM structure needed for CSS-based verse highlighting like Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant Verse.Html
participant yvDomTransformer
participant wrapVerseContent
participant extractNotesFromWrappedHtml
participant HtmlWithNotes
User->>Verse.Html: Render HTML with verse markers
Verse.Html->>yvDomTransformer: Parse and transform HTML
yvDomTransformer->>DOMParser: Parse HTML string
yvDomTransformer->>DOMPurify: Sanitize HTML
yvDomTransformer->>wrapVerseContent: Wrap verses in yv-v elements
Note over wrapVerseContent: Find all .yv-v[v] markers
wrapVerseContent->>wrapVerseContent: Transform empty markers into wrappers
wrapVerseContent->>wrapVerseContent: Handle multi-paragraph verses
wrapVerseContent->>wrapVerseContent: Skip headers (.yv-h)
yvDomTransformer->>extractNotesFromWrappedHtml: Extract footnotes (if enabled)
Note over extractNotesFromWrappedHtml: Use .closest('.yv-v[v]') to find verse
extractNotesFromWrappedHtml->>extractNotesFromWrappedHtml: Group footnotes by verse
extractNotesFromWrappedHtml->>extractNotesFromWrappedHtml: Build verse HTML with A/B/C markers
extractNotesFromWrappedHtml->>extractNotesFromWrappedHtml: Insert placeholders
extractNotesFromWrappedHtml->>extractNotesFromWrappedHtml: Remove footnote elements
yvDomTransformer->>yvDomTransformer: Add non-breaking space to verse labels
yvDomTransformer->>yvDomTransformer: Fix irregular tables
yvDomTransformer-->>Verse.Html: Return transformed HTML + notes
Verse.Html->>HtmlWithNotes: Render with footnote buttons
HtmlWithNotes->>HtmlWithNotes: Find placeholders in DOM
HtmlWithNotes->>HtmlWithNotes: Portal VerseFootnoteButton to placeholders
HtmlWithNotes-->>User: Display verse with interactive footnotes
|
|
@greptileai, what improvements would you suggest? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this PR that transforms HTML for highlights by wrapping verse content, I can see several areas for improvement:
Performance & Efficiency
-
DOM Traversal Optimization: The current implementation does multiple passes through the DOM. You could combine
wrapVerseContentandextractNotesFromWrappedHtmlinto a single traversal for better performance. -
TreeWalker Reuse: In
extractNotesFromWrappedHtml, you're creating a new TreeWalker for each verse wrapper. Consider reusing a single walker or using more efficient DOM traversal methods.
Code Quality & Maintainability
- Extract Constants: Magic selectors like
.p, p, div.pand.s1, .s2, .s3, .s4, .msappear multiple times. Extract these to constants:
const PARAGRAPH_SELECTORS = '.p, p, div.p';
const HEADER_SELECTORS = '.s1, .s2, .s3, .s4, .ms';
const VERSE_MARKER_SELECTOR = '.yv-v[v]';
- Simplify Paragraph Detection: Create a helper function instead of repeating the same logic:
function isParagraphElement(element: Element): boolean {
return element.classList.contains('p') ||
element.tagName === 'P' ||
(element.tagName === 'DIV' && element.classList.contains('p'));
}
- Error Boundary: Add null checks and error handling for edge cases where DOM structure might be unexpected.
Test Coverage Improvements
- Edge Case Testing: Your tests are good, but consider adding:
- Empty verse content handling
- Malformed HTML scenarios
- Verses with only headers (no text content)
- Performance tests with large HTML documents
Algorithm Clarity
-
Document Processing Flow: The current approach processes verses sequentially, but the paragraph-spanning logic is complex. Consider a different approach:
- First pass: identify all verse boundaries
- Second pass: wrap content within those boundaries
- Third pass: handle footnotes
-
Memory Efficiency: The
nodesToWraparray could be large for verses with lots of content. Consider processing nodes as you iterate rather than collecting them all first.
CSS Integration
- Style Coordination: Since this change affects how highlights work, ensure the CSS changes in
bible-reader.css(removingwhite-space: nowrap) are sufficient. You might need additional styles for the new wrapping structure.
Would you like me to elaborate on any of these suggestions or help implement specific improvements?
|
Alright... My buddy Amp Code said,
Brenden and I were processing overhead of TreeWalker for each verse, so I asked my buddy OpenCode and it said:
|
bmanquen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! This is going to be such an upgrade from the previous version and help us interact with the DOM much easier, this is amazing!
Just a few comments to work through.
|
@davidfedor @bbelyeu here is the approach I've taken to prep the HTML returned from YVDOM so that highlights can be easily styled. If you want to provide feedback, it's important that you have read through this Notion doc. |
This directory is used by the OpenCode tool and should not be committed to the repository.
This commit introduces logic to wrap verse content within `yv-v` elements. This change facilitates easier CSS targeting for verse-specific styling, such as highlighting. The implementation handles cases where verses span multiple paragraphs by duplicating the `yv-v` wrapper as per the Bible.com pattern. It also ensures that verse labels are preserved within these new wrappers and that header elements are not erroneously included.
The extractNotesFromHtml function has been refactored into extractNotesFromWrappedHtml. This new function assumes that verse content has already been wrapped in .yv-v[v] elements by wrapVerseContent. This change simplifies the footnote extraction process by leveraging the existing verse wrapping and making the logic more straightforward. It also ensures footnotes are correctly associated with their respective verses, even when verses span multiple paragraphs.
Combine `wrapIntermediateParagraphs` and `wrapRemainingParagraphs` into a single `wrapParagraphsUntilBoundary` function to reduce code duplication. The unified function handles both scenarios via an optional `endParagraph` parameter.
extractNotesFromWrappedHtml
extractNotesFromWrappedHtml
Moves wrapVerseContent, extractNotesFromWrappedHtml, and related helpers from the Verse component to verse-html-utils.ts. This improves code organization and reduces component file size.
These functions lack meaningful context when isolated, so consolidating them improves code clarity and maintainability.
The paragraph wrapping logic was failing because
`handleParagraphWrapping`
attempted to find the paragraph context after `wrapNodesInVerse` had
removed the marker from the DOM. This caused `marker.closest('.p')` to
return null, breaking verse wrapping for multi-paragraph verses.
9b15534 to
798894e
Compare
davidfedor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonderful readability improvements, Cam!
If you want to understand the hardship as to why this change was needed, check out this Notion doc.
Play Video Overview