-
Notifications
You must be signed in to change notification settings - Fork 140
Improve disabling checkbox for Picture Element on Media settings screen #1470
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
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
westonruter
left a comment
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.
LGTM
plugins/webp-uploads/settings.php
Outdated
| opacity: 0.7; | ||
| } | ||
| #webp_uploads_picture_element_fieldset.disabled #webp_uploads_use_picture_element_label { | ||
| pointer-events: none; |
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.
That works! However, it will still be toggled with the keyboard, right?
Anyway, it doesn't really matter if the disabled checkbox can or can't be changed.
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 don't understand this. Wouldn't toggling with the keyboard still be a problem as it would allow changing the value (since the checkbox is not technically disabled)?
I assume the reason we don't use the disabled attribute is that we still need to send the data with the form submission? If so, maybe we should conditionally add readonly, to ensure the value cannot be changed while it's "disabled"?
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.
Wouldn't toggling with the keyboard still be a problem as it would allow changing the value (since the checkbox is not technically disabled)?
Yes. IMO, this is just a UX enhancement though. Also accounting for keyboard toggling the checkbox seems overkill. It's not like it's a problem if someone successfully checks or unchecks this "disabled" checkbox, since the state is ignored. The visual disabled treatment is just to let them know it doesn't have an effect, which the associated admin notice also makes clear.
This being said, to improve a11y then perhaps setting the aria-disabled=true attribute should be done to make this crystal clear. I've done this in 25d2c02.
I assume the reason we don't use the
disabledattribute is that we still need to send the data with the form submission?
That is correct. I also noticed a bug where even though even though the webp_uploads_use_picture_element checkbox is checked, when the perflab_generate_webp_and_jpeg is not checked and the form is submitted, the resulting updated page will still show that the webp_uploads_use_picture_element checkbox is unchecked. This is in spite of the fact that the underlying DB option is still webp_uploads_use_picture_element. The reason for this is that the webp_uploads_is_picture_element_enabled() helper was being used instead of get_option( 'webp_uploads_use_picture_element' ), and the helper will always return false if the perflab_generate_webp_and_jpeg option is not true. I've fixed this in 8c8a294 (and 97dc627).
If so, maybe we should conditionally add
readonly, to ensure the value cannot be changed while it's "disabled"?
Unfortunately, readonly doesn't prevent a checkbox from being toggled: https://codepen.io/westonruter/pen/ExBbzPx
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's not like it's a problem if someone successfully checks or unchecks this "disabled" checkbox, since the state is ignored.
But I thought it isn't really ignored, since the checkbox isn't actually disabled, but only has the disabled class. So as far as I understand, it'll send the value to the backend, which then IMO makes it strange if you can change it (even though that probably won't have any real behavior implications).
Unfortunately,
readonlydoesn't prevent a checkbox from being toggled: https://codepen.io/westonruter/pen/ExBbzPx
Ah, didn't know that, that's too bad. The other alternative to solve this would be to actually disable, while temporarily injecting an input[type="hidden"] that's just there to continue sending the previous value back to the backend - since without sending it, WordPress would update the option to null.
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.
But I thought it isn't really ignored, since the checkbox isn't actually disabled, but only has the
disabledclass.
Sorry, by ignored I mean that webp_uploads_is_picture_element_enabled() will always return false when the perflab_generate_webp_and_jpeg option is false, regardless of whether the webp_uploads_use_picture_element option is true or false.
So as far as I understand, it'll send the value to the backend, which then IMO makes it strange if you can change it (even though that probably won't have any real behavior implications).
So yes, technically you could change it, but it won't have any behavioral effect.
The other alternative to solve this would be to actually disable, while temporarily injecting an
input[type="hidden"]that's just there to continue sending the previous value back to the backend - since without sending it, WordPress would update the option tonull.
That's right. But this seems like maybe overkill.
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.
Actually, thinking about it further: Why don't we simply add disabled to the checkbox than doing all these workarounds? If the checkbox is disabled, nothing will be sent to the backend. This will set the webp_uploads_use_picture_element option to null - which is the same as an unchecked checkbox - which is actually what we want: If the checkbox is disabled, you can't use picture element, so it makes sense for the option value to be false-y.
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.
Because let's say you had PICTURE element enabled, but then you temporarily turned off JPEG fallback. When you go back to turn on JPEG fallback, you'd then find that your PICTURE elements aren't automatically being served again. Keeping a non-disabled input for webp_uploads_use_picture_element ensures that the option isn't mutated unnecessarily. The webp_uploads_is_picture_element_enabled() helper function takes care of whether or not you can use PICTURE element based on the state of the two checkboxes.
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.
Okay, that makes sense. In that case though, I think my previous suggestion of using the disabled attribute on the checkbox and temporarily injecting input[type="hidden"] is a cleaner solution.
We'd only need to inject that additional element if the checkbox was previously checked anyway / the option was true. Otherwise the missing element will lead to the same behavior as the unchecked checkbox would.
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.
Implemented in 42b1129. I found it simpler to not have to inject/remove the hidden input, but to just leave it all the time.
Screen.recording.2024-08-14.10.44.47.webm
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, @westonruter, for updating the PR. The latest changes look good to me.
Clever way to exclude the checkbox in form submission.
felixarntz
left a comment
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.
@mukeshpanchal27 One point of feedback in relation to @westonruter's comment.
plugins/webp-uploads/settings.php
Outdated
| opacity: 0.7; | ||
| } | ||
| #webp_uploads_picture_element_fieldset.disabled #webp_uploads_use_picture_element_label { | ||
| pointer-events: none; |
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 don't understand this. Wouldn't toggling with the keyboard still be a problem as it would allow changing the value (since the checkbox is not technically disabled)?
I assume the reason we don't use the disabled attribute is that we still need to send the data with the form submission? If so, maybe we should conditionally add readonly, to ensure the value cannot be changed while it's "disabled"?
…cture_element_enabled() helper
… checkbox() input
plugins/webp-uploads/settings.php
Outdated
| <input | ||
| type="checkbox" | ||
| id="webp_uploads_use_picture_element" | ||
| aria-describedby="webp_uploads_use_picture_element_description" | ||
| <?php checked( get_option( 'webp_uploads_use_picture_element', false ) ); // Option intentionally used instead of webp_uploads_is_picture_element_enabled() to persist when perflab_generate_webp_and_jpeg is updated. ?> | ||
| <?php disabled( ! $jpeg_fallback_enabled ); ?> | ||
| onchange="document.getElementById('webp_uploads_use_picture_element_value').value = this.checked ? 1 : 0" | ||
| > |
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.
Does the lack of a name attribute on this have any unintended side effects? Makes sense we don't send it with the form submission in favor of the hidden input, but I wonder if this leads to other problems (is the name attribute used for anything else?).
Alternatively, we avoid tampering with this (user-facing) element completely and inject the hidden input only when needed (if the checkbox is disabled). This could then happen in the above event listener for #perflab_generate_webp_and_jpeg, which IMO is cleaner in terms of code organization too as it colocates all the dynamic logic in one place based on the condition (rather than the onchange attribute here that feels a bit out of place).
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.
Does the lack of a
nameattribute on this have any unintended side effects? Makes sense we don't send it with the form submission in favor of the hidden input, but I wonder if this leads to other problems (is thenameattribute used for anything else?).
No, AFAIK the name attribute is only relevant here in that it includes the value in the form submission.
Alternatively, we avoid tampering with this (user-facing) element completely and inject the hidden input only when needed (if the checkbox is disabled). This could then happen in the above event listener for
#perflab_generate_webp_and_jpeg, which IMO is cleaner in terms of code organization too as it colocates all the dynamic logic in one place based on the condition (rather than theonchangeattribute here that feels a bit out of place).
IMO, adding and removing a hidden input makes the code more complicated. But if you'd like to see that, feel free to amend the PR.
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.
IMO it only makes the code more, but not more complicated. Happy to add this.
Co-authored-by: Felix Arntz <[email protected]>
Co-authored-by: felixarntz <[email protected]>
Co-authored-by: felixarntz <[email protected]>
…into fix/disable-input
… exclusively concerns this part of the UI.
|
@westonruter I implemented the placing and removing of the hidden input in a039791. Please review that commit individually as it makes it easier. In 9e5d40f I moved the |
westonruter
left a comment
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.
@felixarntz LGTM, just a few minor suggestions
plugins/webp-uploads/settings.php
Outdated
| hiddenInput.setAttribute( 'type', 'hidden' ); | ||
| hiddenInput.setAttribute( 'id', 'webp_uploads_use_picture_element_hidden' ); | ||
| hiddenInput.setAttribute( 'name', checkbox.getAttribute( 'name' ) ); | ||
| hiddenInput.setAttribute( 'value', checkbox.getAttribute( 'value' ) ); |
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.
Less verbose if properties are used instead:
| hiddenInput.setAttribute( 'type', 'hidden' ); | |
| hiddenInput.setAttribute( 'id', 'webp_uploads_use_picture_element_hidden' ); | |
| hiddenInput.setAttribute( 'name', checkbox.getAttribute( 'name' ) ); | |
| hiddenInput.setAttribute( 'value', checkbox.getAttribute( 'value' ) ); | |
| hiddenInput.type = 'hidden'; | |
| hiddenInput.id = 'webp_uploads_use_picture_element_hidden'; | |
| hiddenInput.name = checkbox.name; | |
| hiddenInput.value = checkbox.value; |
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.
Does this do the same? I believe I had run into weird issues in the past, where one is not like the other, i.e. not in sync. But maybe that was a specific situation. Are you aware of any quirks with attributes vs properties in that sense?
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.
Yeah, although in this case they will be equivalent. We're using the properties elsewhere in this file (e.g. hidden), so I think also good for consistency.
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.
Done in ae2f0c7
plugins/webp-uploads/settings.php
Outdated
| // The hidden input is only needed if the value was originally set (i.e. the checkbox enabled). | ||
| var hiddenInput = document.createElement( 'input' ); | ||
| hiddenInput.setAttribute( 'type', 'hidden' ); | ||
| hiddenInput.setAttribute( 'id', 'webp_uploads_use_picture_element_hidden' ); |
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 string is duplicated three times. Should be added to a new constant that is reused?
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.
We could do that, although then it makes me think we should rather do it across PHP and JS (i.e. define variables in PHP and pass them even to JS), to share more code between server and client. Either way works.
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.
Yeah, defining it in PHP once and then reusing in PHP in JS sounds good 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.
Done in fa311f9
Co-authored-by: Weston Ruter <[email protected]>
|
@adamsilverstein This should be ready for merge. Please review and we'll get this out the door for the Monday release! |
disable is not working for Settings->Media controls
Summary
In #1273, we improved the Settings -> Media controls for Modern Image Formats, where the
Use <picture> Element (experimental)option is disabled if the fallback JPEG checkbox is not selected. However, the checkbox remains clickable even when disabled because we only added the disabled class without actually adding thedisabledattribute to the checkbox.This PR provides a quick workaround by disabling pointer events for the checkbox when the disabled class is present.
Screen.Recording.2024-08-14.at.9.55.36.AM.mov