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

can not parse correctly html with nested ul and li tags. #1039

Closed
lovetingyuan opened this issue Sep 4, 2023 · 8 comments · Fixed by #1304
Closed

can not parse correctly html with nested ul and li tags. #1039

lovetingyuan opened this issue Sep 4, 2023 · 8 comments · Fixed by #1304
Assignees
Labels
bug Something isn't working

Comments

@lovetingyuan
Copy link

Describe the bug
can not parse correctly html with nested ul and li tags.

To Reproduce
Steps to reproduce the behavior:

  1. just run this code:
import { Window } from 'happy-dom'

const window = new Window({})
const document = window.document
document.write('<div id="app"></div>')
const container = document.querySelector('#app')
container.innerHTML = `
<ul>
  <li>
    <ul>
      <li>aaaaa</li>
      <li>bbbbb</li>
    </ul>
  </li>
</ul>
`
console.log(container.outerHTML)

/**
 * the output is wrong: 
 * <div id="app">
<ul>
  <li>
    <ul>
      </ul></li><li>aaaaa</li>
      <li>bbbbb</li>
    </ul>


</div>
 */
  1. check the output, it should be same as input html but in fact is wrong.

Expected behavior
the right answer is

<ul>
  <li>
    <ul>
      <li>aaaaa</li>
      <li>bbbbb</li>
    </ul>
  </li>
</ul>

Device:

  • happy-dom version: "10.11.2"
  • node version: 18.15.0
@lovetingyuan lovetingyuan added the bug Something isn't working label Sep 4, 2023
@danielbush
Copy link

I think I've got a similar issue. I thought I'd post it here rather than make a new issue - but I can do that if it's clearer.

  • happy-dom: 12.10.3
  • bun: 1.0.18
import { Window } from 'happy-dom';

const window = new Window({
  url: 'https://localhost:8080',
  width: 1024,
  height: 768,
});
const document = window.document;

document.body.innerHTML =
  '<ul id="ul"><li id="li1">item 1</li><li id="li2"><ul ><li >trap</li></ul></li><li id="li3">item 3</li></ul>';

console.log(document.body.outerHTML);

window.happyDOM.cancelAsync();

gives:

<body><ul id="ul"><li id="li1">item 1</li><li id="li2"><ul></ul></li><li>trap</li></ul><li id="li3">item 3</li></body>

#li2 should contain a nested list with item "trap", but the nested list is empty, "trap" becomes a sibling alongside it and the outer ul fails to enclose #li3.

@tq-xyy
Copy link

tq-xyy commented Feb 21, 2024

I also have this issue. Did the author have some questions for solving the issue?

@tq-xyy
Copy link

tq-xyy commented Feb 21, 2024

import { Window } from 'happy-dom'

const document = new Window().document

const ul = document.createElement('ul')

// There are two cases.
// Case 1: It will output `<ul><li><ul><li>From sub list</li></ul></li></ul>` (right)
const li = document.createElement('li')
li.innerHTML = '<ul><li>From sub list</li></ul>'
ul.appendChild(li)

// Case 2: It will output `<ul><li><ul></ul></li><li>From sub list</li></ul>` (error)
// ul.innerHTML = '<li><ul><li>From sub list</li></ul></li>'
// document.body.appendChild(ul)

console.log(document.body.innerHTML)

It seemed that the problem happened when putting the <ul> element in <li>. And it is the problem of XMLParser.

The best method is to rewrite XMLParser. Now you can try to write a parser yourself to avoid it.

@tq-xyy
Copy link

tq-xyy commented Feb 21, 2024

This is a patch.

import UnnestableElements from 'happy-dom/lib/config/UnnestableElements.js'
delete UnnestableElements.LI

jacobbuck added a commit to jacobbuck/dom-parse that referenced this issue Mar 4, 2024
@capricorn86 capricorn86 self-assigned this Mar 12, 2024
danbentley added a commit to danbentley/happy-dom that referenced this issue Mar 13, 2024
Update tests to reflect the change and also ensure that nesting is
removed from all non-nestable elements.
@danbentley
Copy link
Contributor

Thanks @lovetingyuan, we've encountered the same issue that left us scratching our heads when writing tests.

We also found that, as @tq-xyy suggests, removing LI from the Unnestable element config (happy-dom/src/config/UnnestableElements.ts) will allow nested <li> elements. Running your test snippet now correctly outputs the markup.

I've submitted a PR with this fix and updated the tests accordingly.

danbentley added a commit to danbentley/happy-dom that referenced this issue Mar 13, 2024
Update tests to reflect the change and also ensure that nesting is
removed from all non-nestable elements.
@capricorn86
Copy link
Owner

Thank you for contributing @danbentley! 🌟

I'm currently working on an implementation for this as well:
https://github.com/capricorn86/happy-dom/tree/1039-can-not-parse-correctly-html-with-nested-ul-and-li-tags

The problem is that <li> elements are not allowed to be nested when they are a direct child of another <li> element, but it seems like they are when they are not a direct child.

Example

var container = document.createElement('div');
container.innerHTML = '<li><li><span>Test</span></li></li>';

// Outputs "<li></li><li><span>Test</span></li>"
console.log(container.innerHTML);

Spec
https://html.spec.whatwg.org/multipage/grouping-content.html#the-li-element

@danbentley
Copy link
Contributor

danbentley commented Mar 13, 2024

Thanks @capricorn86 for the explanation, it makes sense and it's something that occurred to me.

I suppose some elements are more "unnestable" than others, with <li> being the least unnestable of them all!

Sounds like an interesting challenge. I'm looking forward to see how you solve it!

capricorn86 added a commit that referenced this issue Mar 13, 2024
…able>) doesn't allow itself as direct descendant when parsed, but should allow itself as descendant when it is not at first level
@capricorn86
Copy link
Owner

The problem should be fixed now 🙂

You can read more about the release here:
https://github.com/capricorn86/happy-dom/releases/tag/v13.8.3

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

Successfully merging a pull request may close this issue.

5 participants