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

Migrate flat, flat-square, plastic and social to use XmlElement #6883

Merged
merged 14 commits into from
Aug 21, 2021

Conversation

chris48s
Copy link
Member

Closes #6535

This PR applies the work we started in #5754 to the other 4 styles. This fully delegates the responsibility for XML escaping and formatting/minification to the XmlElement class making it easier to "fall into the pit of success" when it comes to escaping.

One thing to note in review is I've been careful to replicate the existing behaviour such that the outputs exactly match the existing outputs without changing the snapshots at all. This should give us a high level of confidence that these changes don't make any functional changes to the XML output. You can also use http://127.0.0.1:3000/dev/styles/ for a visual side-by-side visual comparison.

I've attempted to rebase the history into something vaguely sensible to try and make the review easier 🤞

@chris48s chris48s added the npm-package Badge generation and badge templates label Aug 11, 2021
@shields-ci
Copy link

shields-ci commented Aug 11, 2021

Messages
📖

Thanks for contributing to our documentation. We ❤️ our documentarians!

📖 ✨ Thanks for your contribution to Shields, @chris48s!

Generated by 🚫 dangerJS against 870af64

Comment on lines 76 to 81
class NullElement {
// TODO: we can remove this later
render() {
return ''
}
}
Copy link
Member Author

@chris48s chris48s Aug 11, 2021

Choose a reason for hiding this comment

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

This was helpful as an intermediate step in the refactoring but it gets deleted in f982039 You can basically ignore it in review

Comment on lines +3 to +5
## 4.0.0 [WIP]

- Drop compatibility with Node 10
Copy link
Member Author

Choose a reason for hiding this comment

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

Not strictly related to this PR but the next package release has to be v4 because we've dropped node10. I'm starting the changelog here so we don't lose sight of it.

}

static render(params) {
return new this(params).render()
}

getTextElement({ leftMargin, content, link, color, textWidth, linkWidth }) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I think there's actually scope to factor out getTextElement() into a shared helper (maybe getBackgroundGroupElement() and getForegroundGroupElement() too), DRY up and have FTB share more logic with flat/flat-square/plastic. At the moment FTB and flat/flat-square/plastic use different attribute order in the XML output though so I think doing this will require tweaking the snapshots. For this reason I think this should be done in a follow-on PR instead of here. The property that we know the code exactly matches the snapshots before and after this PR is probably a valuable property for reviewing plus there is already enough stuff changing at once here.

@shields-cd shields-cd temporarily deployed to shields-staging-pr-6883 August 14, 2021 20:38 Inactive
@calebcartwright
Copy link
Member

Haven't been able to carve out enough time yet to start going through this in detail but hoping to do so later this week

@shields-cd shields-cd temporarily deployed to shields-staging-pr-6883 August 21, 2021 02:46 Inactive
Copy link
Member

@calebcartwright calebcartwright left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this one! Everything LGTM. Have left one inline question for my own edification, and one minor (non-blocking) suggested change.

I also want to double check the raster side of the equation out of an abundance of caution (will do here shortly), but we're good to move ahead with this from my perspective

return this.getTextElement({
leftMargin: this.labelMargin,
content: this.label,
link: !shouldWrapBodyWithLink({ links: this.links }) && leftLink,
Copy link
Member

Choose a reason for hiding this comment

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

Realize this is identical to what was there before, but seems like we should change the ordering here to take advantage of short circuiting, given that links are more the exception than the norm

Suggested change
link: !shouldWrapBodyWithLink({ links: this.links }) && leftLink,
link: leftLink && !shouldWrapBodyWithLink({ links: this.links }),

Copy link
Member Author

Choose a reason for hiding this comment

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

I accepted this because it looked kinda sensible. Then fortunately a test failed :)
link here isn't a boolean - its the link URL. Order matters
so this is behaving more like link: !shouldWrapBodyWithLink({ links: this.links }) ? leftLink : undefined
Since we both looked at that and thought it was a bool, maybe writing it like that would be clearer?

Copy link
Member

Choose a reason for hiding this comment

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

It looks like this made the tests fail? It's not at all clear to me why that would be the case

Copy link
Member

Choose a reason for hiding this comment

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

oops, comments crossed

Since we both looked at that and thought it was a bool, maybe writing it like that would be clearer?

Yeah that makes sense, it's currently subtle/easy to miss clearly 😄

Copy link
Member

Choose a reason for hiding this comment

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

will go ahead and re-:+1: since this could certainly be deferred like some of other changes mentioned but happy to circle back and do so again if you want to tack that onto this pr

Comment on lines 89 to 92
return this.content.reduce((acc, el) => acc + el.render(), '')
return this.content.reduce(
(acc, el) =>
typeof el.render === 'function'
? acc + el.render()
: acc + escapeXml(el),
''
)
Copy link
Member

Choose a reason for hiding this comment

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

I can't convince myself that I understand this part of the diff 😆 Would you mind explaining it to me?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep so basically this.content is a list of things each of which might be:

  • an XmlElement object
  • another nested ElementList object
  • a string (tbh, this is mostly an empty string when we don't want to render a particular element e.g:
    const shadow = this.constructor.shadow ? shadowText : ''
    if (!link) {
    return new ElementList({ content: [shadow, text] })
    }
    )

so if I say

const list = new ElementList({content: [
  new XmlElement({name: 'foo'}),
  'bar',
  new XmlElement({name: 'baz'}),
]})

then I want render() to output

<foo />bar<baz />

this.content.reduce((acc, el) => acc + el, '')

does the same thing as

this.content.join('')

so I'm doing that, but then I'm saying in the reduce function:
If this object has a render() function (it quacks like an XmlElement or an ElementList), call render() and concat the result. Otherwise (assume it is just a string), escape the string and concat that.

Copy link
Member

Choose a reason for hiding this comment

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

tbh, this is mostly an empty string when we don't want to render a particular element e.g:

Ah okay, so even if it's not an element it's not strictly going to be an empty string which requires a more thorough check. makes sense, thanks

Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com>
@chris48s chris48s temporarily deployed to shields-staging-pr-6883 August 21, 2021 18:56 Inactive
@chris48s chris48s temporarily deployed to shields-staging-pr-6883 August 21, 2021 19:07 Inactive
@chris48s chris48s temporarily deployed to shields-staging-pr-6883 August 21, 2021 19:27 Inactive
@chris48s chris48s merged commit e8c78d5 into badges:master Aug 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
npm-package Badge generation and badge templates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate flat, flat-square, plastic and social to use XmlElement
4 participants