Skip to content

Commit

Permalink
Fix head opening tag omission w/o title
Browse files Browse the repository at this point in the history
While typically a `title` is needed,
there are cases where `<head>` can be empty,
in which case,
the start tag can be omitted.

Closes GH-43.
  • Loading branch information
wooorm committed Sep 16, 2024
1 parent a556b7d commit 1c938b9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 17 deletions.
22 changes: 12 additions & 10 deletions lib/omission/opening.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,25 @@ function html(node) {
* Whether the opening tag can be omitted.
*/
function head(node) {
const children = node.children
/** @type {Array<string>} */
const seen = []
let index = -1
/** @type {Set<string>} */
const seen = new Set()

while (++index < children.length) {
const child = children[index]
// Whether `srcdoc` or not,
// make sure the content model at least doesn’t have too many `base`s/`title`s.
for (const child of node.children) {
if (
child.type === 'element' &&
(child.tagName === 'title' || child.tagName === 'base')
(child.tagName === 'base' || child.tagName === 'title')
) {
if (seen.includes(child.tagName)) return false
seen.push(child.tagName)
if (seen.has(child.tagName)) return false
seen.add(child.tagName)
}
}

return children.length > 0
// “May be omitted if the element is empty,
// or if the first thing inside the head element is an element.”
const child = node.children[0]
return !child || child.type === 'element'
}

/**
Expand Down
8 changes: 4 additions & 4 deletions test/omission-closing-head.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {u} from 'unist-builder'

test('`head` (closing)', async function (t) {
await t.test('should omit tag without following', async function () {
assert.deepEqual(toHtml(h('head'), {omitOptionalTags: true}), '<head>')
assert.deepEqual(toHtml(h('head'), {omitOptionalTags: true}), '')
})

await t.test(
Expand All @@ -16,7 +16,7 @@ test('`head` (closing)', async function (t) {
toHtml(h('html', [h('head'), u('comment', 'alpha')]), {
omitOptionalTags: true
}),
'<head></head><!--alpha-->'
'</head><!--alpha-->'
)
}
)
Expand All @@ -26,7 +26,7 @@ test('`head` (closing)', async function (t) {
async function () {
assert.deepEqual(
toHtml(h('html', [h('head'), ' alpha']), {omitOptionalTags: true}),
'<head></head> alpha'
'</head> alpha'
)
}
)
Expand All @@ -38,7 +38,7 @@ test('`head` (closing)', async function (t) {
toHtml(h('html', [h('head'), u('text', 'alpha')]), {
omitOptionalTags: true
}),
'<head>alpha'
'alpha'
)
}
)
Expand Down
9 changes: 6 additions & 3 deletions test/omission-opening-head.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ test('`head` (opening)', async function (t) {
)
})

await t.test('should not omit tag without children', async function () {
assert.deepEqual(toHtml(h('head'), {omitOptionalTags: true}), '<head>')
})
await t.test(
'should omit tag without children (could be fine in `srcdoc`)',
async function () {
assert.deepEqual(toHtml(h('head'), {omitOptionalTags: true}), '')
}
)

await t.test('should omit tag with `title`', async function () {
assert.deepEqual(
Expand Down

0 comments on commit 1c938b9

Please sign in to comment.