-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Conversation
this is the only place it is now used
leave everything as XmlElement objects right till the end then make one final call to .render() which cascades aaall the way through the tree
now we've removed all the intermediate calls to render() we can just use an empty string
|
badge-maker/lib/xml.js
Outdated
class NullElement { | ||
// TODO: we can remove this later | ||
render() { | ||
return '' | ||
} | ||
} |
There was a problem hiding this comment.
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
## 4.0.0 [WIP] | ||
|
||
- Drop compatibility with Node 10 |
There was a problem hiding this comment.
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 }) { |
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this 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
badge-maker/lib/badge-renderers.js
Outdated
return this.getTextElement({ | ||
leftMargin: this.labelMargin, | ||
content: this.label, | ||
link: !shouldWrapBodyWithLink({ links: this.links }) && leftLink, |
There was a problem hiding this comment.
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
link: !shouldWrapBodyWithLink({ links: this.links }) && leftLink, | |
link: leftLink && !shouldWrapBodyWithLink({ links: this.links }), |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 😄
There was a problem hiding this comment.
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
badge-maker/lib/xml.js
Outdated
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), | ||
'' | ||
) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
shields/badge-maker/lib/badge-renderers.js
Lines 227 to 231 in b6c5a10
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.
There was a problem hiding this comment.
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>
This reverts commit b6c5a10.
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 🤞