Skip to content

fragment node type #23

Closed
Closed
@viktor-yakubiv

Description

@viktor-yakubiv

Initial checklist

Problem

It could be useful to have a special type for fragments.

A fragment node type could help some plugins which need to preserve some isolated data for itself or replace a node with an array of nodes. Imagine a component for this case, that results in multiple nodes and has no single 'root' element. The idea is similar to JSX's fragment.

The plugins I bear in mind:

  • include — another file is imported but it has multiple nodes. It can be done with a splice() like below:

    parent.children.splice(index, 1, ...loadedRoot.children)

    but having a fragment node enables storing additional information (original properties, actual file location etc) in the node for possible future use.

  • components

    There is no limitation for number of children for the <template> element, i.e. a web component could yield multiple children instead itself. If a component gets replaced (like in rehype-componets plugin), it might be useful to preserve old data for other plugins that work on data based on that plugin.

Solution

Having a following interface could be useful.

interface Fragment <: Parent {
  type: "fragment"
}

Alternatives

With rehype, nested root nodes effectively work as fragments. This was tested running the following example:

const tree = {
  type: 'root',
  children: [
    { type: 'text', value: 'outside nested root\n' },
    {
      type: 'element',
      tagName: 'div',
      children: [
        {
          type: 'root',
          children: [{
          type: 'element',
          tagName: 'span',
          children: [{ type: 'text', value: 'inside nested root' }],
        }]}
      ]
    }
  ],
}

const file = await rehype()
  .data('settings', { fragment: true })
  .stringify(tree)

console.log(String(file))

This code does not throw and yields the following HTML:

outside nested root
<div><span>inside nested root</span></div>

The proposal is actually made for a sanity in specific cases. I understand that this is not a part of HTML and is rather a common practice in frameworks like React, Vue etc. and could be rejected as well as #20. However, as it could be useful for some plugins and does not require a lot of effort in the implementation, I am bringing this to your consideration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    👎 phase/noPost cannot or will not be acted on🙅 no/wontfixThis is not (enough of) an issue for this project

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions