-
-
Notifications
You must be signed in to change notification settings - Fork 382
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
Make Emoji img attributes configurable #258
Conversation
@@ -71,7 +71,42 @@ def asset_path(name) | |||
|
|||
# Build an emoji image tag | |||
def emoji_image_tag(name) | |||
"<img class='emoji' title=':#{name}:' alt=':#{name}:' src='#{emoji_url(name)}' height='20' width='20' align='absmiddle' />" | |||
"<img #{img_html_attrs(name)}>" |
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'm wary of this change because unsafe user input could be injected here. Could you look whitelisting only attributes that make sense for a img
element?
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'm wary of this change because unsafe user input could be injected here.
This is not from user input. It is context option used by developer.
Could you look whitelisting only attributes that make sense for a img element?
ditto, let's leave this to developer?
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.
Good point. I missed that.
- Could you update the documentation at the top of the class explaining this new context option?
- What do you think about simplifying the methods? The new methods are not part of the public interface, and I feel they add more layers than necessary. What about doing this new work in the existing
emoji_image_tag
method?
edit noticed the new methods are private, but still feel they add too many layers.
context[:img_attrs].each do |key, value| | ||
context[:img_attrs][key] = value.call(name) if value.respond_to?(:call) | ||
end | ||
end |
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 method can be inlined as well. Similar reasoning as before. Here, we're mutating the context
hash by adding more elements to it. While that's doable, it makes it difficult to debug pipelines because it's unclear which filter modified a context. Instead, we can leave the context as passed in options and use it's values. I haven't tested this, but I imagine something like:
default_attrs = default_img_attrs(name)
# This avoids creating an extra empty hash for each invocation and only merges if user passed something in
merged_attrs = context[:img_attrs] ? default_attrs.merge(context[:img_attrs]) : default_attrs
# This builds the attributes and handles procs. In your implementation, you remove nils, but I think that should be the responsibility of the caller. Nils would print as an empty value, which would still be valid.
html_attrs = merged_attrs.map do |k, v|
"#{k}='#{v.try(:call) || v}'"
end
"<img #{html_attrs.join(' '}>"
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 method can be inlined as well. Similar reasoning as before. Here, we're mutating the context hash by adding more elements to it. While that's doable, it makes it difficult to debug pipelines because it's unclear which filter modified a context
👍 Awesome!
Instead, we can leave the context as passed in options and use it's values. I haven't tested this, but I imagine something like:
I adapt your imagination as f1c1618.
In your implementation, you remove nils, but I think that should be the responsibility of the caller. Nils would print as an empty value, which would still be valid.
This is because #234, user of HTML::Pipeline
need to clear some unwanted default attributes to pass the W3C validations.
Another change I added is indifferent access to context[:img_attrs]
hash .
Why? Because a user may be tempted to use { height: nil, width: nil }
to clear height
and width
attributes. Without indifferent access, the keys of Hash must be String
. Better developer experience in my opinion.
1. User can specify a hash `context[:img_attrs]` to change the `img` tag attributes, e.g. `{ "draggable" => false }` 2. The hash key can be either `String` / `Symbol` (indifferent access) `{ "draggable" => false }` / `{ draggable: false }` => `<img draggable="false">` 3. The hash value can be either anything / proc-like object Proc-like object with default argument `name`: Given name is `:shipit:` `{ title: ->(name) { |n| n.gsub(":", "") } }` => `<img title="shipit">` So you can do any customisations with the attribute. 4. The hash value nil means clear the attribute of img tag For example, to clear the default `height`, `width`, and `align` attributes, pass `{ height: nil, width: nil, align: nil }` to `context[:img_attrs]`. 5. Refine tests with consistent styles
If you think this is mergable, I will squash commits, merge into master. Add an changelog item and release a patch version :) |
Sounds good! Thanks for tackling this. |
Merged as 3518bbb. |
1. User can specify a hash `context[:img_attrs]` to change the `img` tag attributes, e.g. `{ "draggable" => false }` 2. The hash key can be either `String` / `Symbol` (indifferent access) `{ "draggable" => false }` / `{ draggable: false }` => `<img draggable="false">` 3. The hash value can be either anything / proc-like object Proc-like object with default argument `name`: Given name is `:shipit:` `{ title: ->(name) { |n| n.gsub(":", "") } }` => `<img title="shipit">` So you can do any customisations with the attribute. 4. The hash value nil means clear the attribute of img tag For example, to clear the default `height`, `width`, and `align` attributes, pass `{ height: nil, width: nil, align: nil }` to `context[:img_attrs]`. 5. Refine tests with consistent styles
Thank you @JuanitoFatas - this was a much needed feature and looks great |
Resolves #234
This Pull Request makes
img
tag attributes configuarable:nil
("height" => nil, "width" => nil, "align" => nil
)img
tag attributes"draggable"=> false
name
argumentimg
attributes (height='20' width='20' align='absmiddle'
) can be removed when there is a next major / minor version bump@jch What do you think?