Skip to content

Conversation

gastonyte
Copy link

@gastonyte gastonyte commented Jul 29, 2024

Summary

That PR is about adding ability for users to not add a / at the end of specific void elements (like <br>, <link> or <input> elements)

This change originally come from #51

What are the specific steps to test this change?

type SelfClosingOptions = Record<string, boolean | { voidElement: boolean }>

type MyIOptions = Omit<sanitizeHtml.IOptions, 'selfClosing'> & {
  selfClosing?: SelfClosingOptions | string[] | undefined
}

const sanitizationOptions: MyIOptions = {
  allowedTags: ['p', 'strong', 'em', 'u', 's', 'blockquote', 'ul', 'ol', 'li', 'br'],
  allowedAttributes: {},
  selfClosing: {
    br: {
      voidElement: true
    }
  },
}

const cleaned = sanitizeHtml(
  value,
  sanitizationOptions as sanitizeHtml.IOptions
)

What kind of change does this PR introduce?

(Check at least one)

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Build-related changes
  • Other

Make sure the PR fulfills these requirements:

  • It includes a) the existing issue ID being resolved, b) a convincing reason for adding this feature, or c) a clear description of the bug it resolves
  • The changelog is updated
  • Related documentation has been updated
  • Related tests have been updated

If adding a new feature without an already open issue, it's best to open a feature request issue first and wait for approval before working on it.

Other information:

@gastonyte
Copy link
Author

I didn't change the documentation because I don't know where to write about voidElement because the section explaining selfClosing does not exist yet.

Copy link
Member

@boutell boutell left a comment

Choose a reason for hiding this comment

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

This is great — just one request to avoid prototype pollution issues.

As for documentation, please introduce a new third-level heading.

index.js Outdated
const tagAllowed = function (name) {
const { selfClosing } = options;
if (Array.isArray(selfClosing)) {
options.selfClosing = selfClosing.reduce((before, tagName) => ({
Copy link
Member

Choose a reason for hiding this comment

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

It would be more performant to use a for loop here, avoiding the need to make a new object on every pass.

Copy link
Author

Choose a reason for hiding this comment

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

i replaced the reduce with a for-of loop

index.js Outdated
if (options.selfClosing.indexOf(name) !== -1) {
result += ' />';

if (options.selfClosing[name]) {
Copy link
Member

Choose a reason for hiding this comment

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

Use Object.hasOwn(options.selfClosing, name) to make sure it's a real property and not something sneaky like __prototype__. Or use a Map.

Copy link
Author

Choose a reason for hiding this comment

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

done

@BoDonkey BoDonkey requested a review from boutell February 1, 2025 10:58
options.parser = Object.assign({}, htmlParserDefaults, options.parser);

const tagAllowed = function (name) {
const { selfClosing } = options;
Copy link
Member

Choose a reason for hiding this comment

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

Localized and then never used in a localized away again because of the reassignment for the array case. So I think it would be clearer if we didn't do this at all and just referred to options.selfClosing throughout this bit.

Copy link
Member

Choose a reason for hiding this comment

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

The README must be updated to cover this new syntax.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the delay on this one!

Copy link

stale bot commented Apr 26, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Apr 26, 2025
@BoDonkey BoDonkey removed the stale label May 8, 2025
@BoDonkey
Copy link
Contributor

BoDonkey commented May 8, 2025

Bump to remove label.

@gastonyte gastonyte closed this May 9, 2025
@gastonyte gastonyte reopened this May 10, 2025
Copy link

stale bot commented Jul 19, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jul 19, 2025
@BoDonkey BoDonkey removed the stale label Jul 19, 2025
@BoDonkey
Copy link
Contributor

I know this has been a long back and forth, but do you know if you will be able to finish this @gastonyte?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants