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

feat: new private node property "_withoutClosingTag" #48

Closed
wants to merge 1 commit into from

Conversation

SukkaW
Copy link
Contributor

@SukkaW SukkaW commented Nov 24, 2020

Notable Changes

The PR adds support for a private property _withoutClosingTag:

// fixture
{
  tag: 'div',
  _withoutClosingTag: true // By default the property won't exist
}

will result in

<div>

Commit Message Summary (CHANGELOG)

feat: new private node property "_withoutClosingTag"

Type

  • Feature

SemVer

  • Fix (:label: Patch)
  • Feature (:label: Minor)
  • Breaking Change (:label: Major)

Issues

The PR is primarily used to implement posthtml/htmlnano#29, to omit those optional closing tags (without producing invalid HTML). It might also help to handle the case I mentioned in posthtml/posthtml-parser#9 (comment).

So far _withoutClosingTag should be considered as a private property of node (with _ prefixed) and shouldn't be documented, but we could make it public in the future.

Checklist

  • Lint and unit tests pass with my changes
  • I have added tests that prove my fix is effective/works
  • I have added necessary documentation (if appropriate)
  • Any dependent changes are merged and published in downstream modules

Copy link
Member

@Scrum Scrum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation should be done here because this block is responsible for the type of render

if (isSingleTag(tag)) {
switch (closingSingleTag) {
case 'tag':
result += '></' + tag + '>';
break;
case 'slash':
result += ' />';
break;
default:
result += '>';
}
result += html(node.content);

I think that it is necessary to introduce another type, for example, byProperty.

  1. You are adding an element that must be single options.singleTags = ['html']
  2. Refactor isSingleTag
const asTag = '></' + tag + '>';
const asSlash = ' />';
const asDefault = '>';
switch (closingSingleTag) {
  case 'tag':
    result += asTag;

    break;
  case 'slash':
    result += asSlash;

    break;
  case 'byProperty':
    result += node._closingElement ? asTag : asDefault;
    break;
  default:
    result += asDefault;
}

Don't forget to add this to the documentation.

thanks

@@ -204,6 +204,8 @@ function render(tree, options) {
}

result += html(node.content);
} else if (node._withoutClosingTag) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_withoutClosingTag The name is not very suitable because tag means that there is an opening and closing element.

It seems more appropriate to me that the _closingElement

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding semantics, element in HTML refers to the whole thing - an element has start/opening and end/closing tags.

I agree double negation through the use of without in the name is unnecessary, but if a name such as _closingTag creates confusion, maybe we could use something like _needsClosing or _shouldClose or something similar?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding semantics, element in HTML refers to the whole thing - an element has start/opening and end/closing tags.

It is considered that if the element is single such as <hr> or <img> then it is the element if the element has a closing element then the tag is used

@Scrum Scrum requested review from anikethsaha and cossssmin and removed request for michael-ciniawsky and mrmlnc November 24, 2020 06:36
@cossssmin
Copy link
Member

@Scrum I understand this could be a solution to posthtml/posthtml-mso#1 ?

@Scrum
Copy link
Member

Scrum commented Nov 24, 2020

@Scrum I understand this could be a solution to posthtml/posthtml-mso#1 ?

Yes, you can bypass all child elements by the found match and set them a parameter

@SukkaW
Copy link
Contributor Author

SukkaW commented Nov 24, 2020

I think that it is necessary to introduce another type, for example, byProperty.

@Scrum

withoutClosingTag should be considered as when it is not a single tag (like hr, img) while the closing tag could be omitted safely (without introducing invalid HTML). See WHATWG spec: https://html.spec.whatwg.org/multipage/syntax.html#optional-tags

It seems more appropriate to me that the _closingElement

Actually, WHATWG HTML spec uses the word start tag and end tag. I use closing because it feels more consistent with the posthtml options' name.

I agree double negation through the use of without in the name is unnecessary

@cossssmin

By default posthtml-parser will not add _withoutClosingTag to node, thus Boolean(node._withoutClosingTag) will be false, unless a posthtml plugin specify it to be true when travase through tree.

@Scrum
Copy link
Member

Scrum commented Nov 25, 2020

withoutClosingTag should be considered as when it is not a single tag (like hr, img) while the closing tag could be omitted safely (without introducing invalid HTML). See WHATWG spec: https://html.spec.whatwg.org/multipage/syntax.html#optional-tags

The fact is that we go beyond recommendations by manipulating the html tag as a single tag in conjunction with conditional comments. Therefore we have no right to look in the recommendation because we break them using this construction.

After a little reflection, I realized that we can do even better if we pass the type used for closingSingleTag

result += typeof node._closingElement === string ? as[node._closingElement] : node._closingElement ? asTag : asDefault;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants