mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
docs(docs-infra): preserve content before docs-card-container in adev
The tokenizer regex pattern `[^<]*` was consuming all non-`<` content before custom HTML tags, causing lost content. Changed to `\s*` which only allows leading whitespace, letting marked properly tokenize preceding content.
This commit is contained in:
committed by
Jessica Janiuk
parent
a1501bc90a
commit
bc473cf60f
+1
-1
@@ -21,7 +21,7 @@ interface DocsCardContainerToken extends Tokens.Generic {
|
||||
// Capture group 1: all attributes on the opening tag
|
||||
// Capture group 2: all content between the open and close tags
|
||||
const cardContainerRule =
|
||||
/^[^<]*<docs-card-container(?:\s([^>]*))?>((?:.(?!\/docs-card-container))*)<\/docs-card-container>/s;
|
||||
/^\s*<docs-card-container(?:\s([^>]*))?>((?:.(?!\/docs-card-container))*)<\/docs-card-container>/s;
|
||||
const headerTitleRule = /headerTitle="([^"]*)"/;
|
||||
const headerImgSrcRule = /headerImgSrc="([^"]*)"/;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ interface DocsCardToken extends Tokens.Generic {
|
||||
|
||||
// Capture group 1: all attributes on the opening tag
|
||||
// Capture group 2: all content between the open and close tags
|
||||
const cardRule = /^[^<]*<docs-card(?:\s([^>]*))?>((?:.(?!\/docs-card))*)<\/docs-card>/s;
|
||||
const cardRule = /^\s*<docs-card(?:\s([^>]*))?>((?:.(?!\/docs-card))*)<\/docs-card>/s;
|
||||
|
||||
const titleRule = /title="([^"]*)"/;
|
||||
const linkRule = /link="([^"]*)"/;
|
||||
|
||||
+37
-2
@@ -1,4 +1,39 @@
|
||||
Introductory paragraph that should be preserved before any card containers.
|
||||
|
||||
## First Section
|
||||
|
||||
This section contains important information about the feature status.
|
||||
|
||||
### Available features
|
||||
|
||||
- Feature one
|
||||
- Feature two
|
||||
- Feature three
|
||||
|
||||
### In progress
|
||||
|
||||
The following items are currently being developed:
|
||||
|
||||
1. Item A with description
|
||||
2. Item B with description
|
||||
|
||||
<docs-card-container>
|
||||
<docs-card></docs-card>
|
||||
<docs-card></docs-card>
|
||||
<docs-card title="Card One"></docs-card>
|
||||
<docs-card title="Card Two"></docs-card>
|
||||
</docs-card-container>
|
||||
|
||||
### Additional context
|
||||
|
||||
More text after the first card container that should also be preserved.
|
||||
|
||||
## Second Section
|
||||
|
||||
Another paragraph before the second card container.
|
||||
|
||||
<docs-card-container>
|
||||
<docs-card title="Card Three"></docs-card>
|
||||
</docs-card-container>
|
||||
|
||||
## Final Section
|
||||
|
||||
Concluding remarks at the end of the document.
|
||||
|
||||
+54
-4
@@ -20,10 +20,60 @@ describe('markdown to html', () => {
|
||||
markdownDocument = JSDOM.fragment(await parseMarkdown(markdownContent, rendererContext));
|
||||
});
|
||||
|
||||
it('creates card containers containing multiple cards', () => {
|
||||
const containerEl = markdownDocument.querySelector('.docs-card-grid');
|
||||
it('creates multiple card containers with correct card counts', () => {
|
||||
const containers = markdownDocument.querySelectorAll('.docs-card-grid');
|
||||
|
||||
expect(containerEl!.children.length).toBe(2);
|
||||
expect(containerEl!.classList.contains('docs-card-grid')).toBeTrue();
|
||||
expect(containers.length).toBe(2);
|
||||
expect(containers[0].children.length).toBe(2);
|
||||
expect(containers[1].children.length).toBe(1);
|
||||
});
|
||||
|
||||
it('preserves all h2 section headings', () => {
|
||||
const h2Elements = markdownDocument.querySelectorAll('h2');
|
||||
|
||||
expect(h2Elements.length).toBe(3);
|
||||
expect(h2Elements[0].textContent).toContain('First Section');
|
||||
expect(h2Elements[1].textContent).toContain('Second Section');
|
||||
expect(h2Elements[2].textContent).toContain('Final Section');
|
||||
});
|
||||
|
||||
it('preserves all h3 subsection headings outside card containers', () => {
|
||||
// Card titles also render as h3, so we filter to only h3s not inside card containers
|
||||
const allH3s = Array.from(markdownDocument.querySelectorAll('h3'));
|
||||
const sectionH3s = allH3s.filter((h3) => !h3.closest('.docs-card-grid'));
|
||||
|
||||
expect(sectionH3s.length).toBe(3);
|
||||
expect(sectionH3s[0].textContent).toContain('Available features');
|
||||
expect(sectionH3s[1].textContent).toContain('In progress');
|
||||
expect(sectionH3s[2].textContent).toContain('Additional context');
|
||||
});
|
||||
|
||||
it('preserves unordered lists before card containers', () => {
|
||||
const ulElements = markdownDocument.querySelectorAll('ul');
|
||||
|
||||
expect(ulElements.length).toBeGreaterThanOrEqual(1);
|
||||
expect(ulElements[0].children.length).toBe(3);
|
||||
expect(ulElements[0].textContent).toContain('Feature one');
|
||||
});
|
||||
|
||||
it('preserves ordered lists before card containers', () => {
|
||||
const olElements = markdownDocument.querySelectorAll('ol');
|
||||
|
||||
expect(olElements.length).toBe(1);
|
||||
expect(olElements[0].children.length).toBe(2);
|
||||
expect(olElements[0].textContent).toContain('Item A');
|
||||
});
|
||||
|
||||
it('preserves paragraphs throughout the document', () => {
|
||||
const paragraphs = markdownDocument.querySelectorAll('p');
|
||||
|
||||
expect(paragraphs.length).toBeGreaterThanOrEqual(5);
|
||||
|
||||
const paragraphTexts = Array.from(paragraphs).map((p) => p.textContent);
|
||||
expect(paragraphTexts.some((t) => t?.includes('Introductory paragraph'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('important information'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('More text after'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('Another paragraph'))).toBeTrue();
|
||||
expect(paragraphTexts.some((t) => t?.includes('Concluding remarks'))).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user