Skip to content
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

Invalid tree due to optional tags #1126

Closed
itozyun opened this issue Oct 10, 2023 · 1 comment
Closed

Invalid tree due to optional tags #1126

itozyun opened this issue Oct 10, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@itozyun
Copy link

itozyun commented Oct 10, 2023

Describe the bug
Hi, I am developing a library to convert HTML to JSON with happy-dom.

I report an invalid tree result of the following test that omits the end tags.

To Reproduce

Add the following to /packages/happy-dom/test/xml-parser/XMLParser.test.ts.

it('Handles unclosed tags (e.g. <dl>, <table>).', () => {
	const root = XMLParser.parse(
		document,
		`
		<div class="test" disabled>
			<dl>
				<dt>Test
				<dd>Test</dt></dt></dt></dt>
				<dt>Test</dt>
				<dd>Test
			</dl>
			<select>
				<option>Test 1
				<optgroup>
					<option>Test 2
					<option>Test 3</option>
					<option>Test 4
				<optgroup>
					<option>Test 5
					<option>Test 6
			</select>
			<ruby>明日
				<rp>(
				<rt>Ashita
				<rp>)
			</ruby>
			<table>
				<caption>Test
				<colgroup>
					<col>
					<col>
					<col>
				<thead>
					<tr>
						<th>Test 1</th><td>Test 2<td>Test 3
					<tr>
						<th>Test 4<td>Test 5<td>Test 6</th></th></th>
				<tbody>
					<tr>
						<th>Test 7<td>Test 8<td>Test 9</td>
					</tr>
					<tr>
						<th></td></td></td></td></td></td>Test 10<td>Test 11<td>Test 12
				<tfoot>
					<tr>
						<th>Test 13<td>Test 14<td>Test 15
			</table>
		</div>
		`
	);

	expect(new XMLSerializer().serializeToString(root).replace(/\s/gm, '')).toBe(
		`
		<div class="test" disabled="">
			<dl>
				<dt>Test</dt>
				<dd>Test</dd>
				<dt>Test</dt>
				<dd>Test</dd>
			</dl>
			<select>
				<option>Test 1</option>
				<optgroup>
					<option>Test 2</option>
					<option>Test 3</option>
					<option>Test 4</option>
				</optgroup>
				<optgroup>
					<option>Test 5</option>
					<option>Test 6</option>
				</optgroup>
			</select>
			<ruby>明日
				<rp>(</rp>
				<rt>Ashita</rt>
				<rp>)</rp>
			</ruby>
			<table>
				<caption>Test</caption>
				<colgroup>
					<col>
					<col>
					<col>
				</colgroup>
				<thead>
					<tr>
						<th>Test 1</th><td>Test 2</td><td>Test 3</td>
					</tr>
					<tr>
						<th>Test 4</th><td>Test 5</td><td>Test 6</td>
					</tr>
				</thead>
				<tbody>
					<tr>
						<th>Test 7</th><td>Test 8</td><td>Test 9</td>
					</tr>
					<tr>
						<th>Test 10</th><td>Test 11</td><td>Test 12</td>
					</tr>
				</tbody>
				<tfoot>
					<tr>
						<th>Test 13</th><td>Test 14</td><td>Test 15</td>
					</tr>
				</tfoot>
			</table>
		</div>
		`.replace(/\s/gm, '')
	);
});

Result

<divclass="test"disabled="">
    <dl>
        <dt>Test
            <dd>Test</dd>
        </dt>
        <dt>Test</dt>
    </dl>
</div>
<dd>Test
    <select>
        <option>Test1
            <optgroup></optgroup>
        </option>
        <option>Test2</option>
        <option>Test3</option>
        <option>Test4
            <optgroup></optgroup>
        </option>
        <option>Test5</option>
        <option>Test6
            <ruby>明日
                <rp>(
                    <rt>Ashita
                        <rp>)
                            <table>
                                <caption>Test
                                    <colgroup>
                                        <col>
                                        <col>
                                        <col>
                                        <thead>
                                            <tr>
                                                <th>Test1</th>
                                                <td>Test2
                                                    <td>Test3
                                                        <tr>
                                                            <th>Test4
                                                                <td>Test5
                                                                    <td>Test6
                                                                        <tbody>
                                                                            <tr>
                                                                                <th>Test7
                                                                                    <td>Test8
                                                                                        <td>Test9</td>
                                                                                        <tr>
                                                                                            <th>Test10
                                                                                                <td>Test11
                                                                                                    <td>Test12
                                                                                                        <tfoot>
                                                                                                            <tr>
                                                                                                                <th>Test13
                                                                                                                    <td>Test14
                                                                                                                        <td>Test15</td>
                                                                                                                    </td>
                                                                                                                </th>
                                                                                                            </tr>
                                                                                                        </tfoot>
                                                                                                    </td>
                                                                                                </td>
                                                                                            </th>
                                                                                        </tr>
                                                                                    </td>
                                                                                </th>
                                                                            </tr>
                                                                        </tbody>
                                                                    </td>
                                                                </td>
                                                            </th>
                                                        </tr>
                                                    </td>
                                                </td>
                                            </tr>
                                        </thead>
                                    </colgroup>
                                </caption>
                            </table>
                        </rp>
                    </rt>
                </rp>
            </ruby>
        </option>
    </select>
</dd>

Expected behavior

<divclass="test"disabled="">
    <dl>
        <dt>Test</dt>
        <dd>Test</dd>
        <dt>Test</dt>
        <dd>Test</dd>
    </dl><select>
        <option>Test1</option>
        <optgroup>
            <option>Test2</option>
            <option>Test3</option>
            <option>Test4</option>
        </optgroup>
        <optgroup>
            <option>Test5</option>
            <option>Test6</option>
        </optgroup>
    </select><ruby>明日<rp>(</rp>
        <rt>Ashita</rt>
        <rp>)</rp>
    </ruby>
    <table>
        <caption>Test</caption>
        <colgroup>
            <col>
            <col>
            <col>
        </colgroup>
        <thead>
            <tr>
                <th>Test1</th>
                <td>Test2</td>
                <td>Test3</td>
            </tr>
            <tr>
                <th>Test4</th>
                <td>Test5</td>
                <td>Test6</td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th>Test7</th>
                <td>Test8</td>
                <td>Test9</td>
            </tr>
            <tr>
                <th>Test10</th>
                <td>Test11</td>
                <td>Test12</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <th>Test13</th>
                <td>Test14</td>
                <td>Test15</td>
            </tr>
        </tfoot>
    </table>
    </div>
@itozyun itozyun added the bug Something isn't working label Oct 10, 2023
itozyun added a commit to itozyun/happy-dom that referenced this issue Oct 10, 2023
jacobbuck added a commit to jacobbuck/dom-parse that referenced this issue Mar 4, 2024
@capricorn86
Copy link
Owner

Thank you for reporting @itozyun! 🙂

I believe this issue has been fixed now in v16.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants