-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
7083187: Class CSS.CssValue is missing implementations of equals() and hashCode() #13405
Conversation
👋 Welcome back psadhukhan! A progress list of the required criteria for merging this PR into |
Webrevs
|
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.
The change looks good but it doesn't address the whole problem raised in the JDK-7083187: CSS.CssValue
does not implement equals
. This fix addresses only one particular case: CSS.FontSize
for font-size
property.
I do not think it resolves the problem entirely: CssValue
and all its subclasses must implement equals
method, otherwise adding another CSS attribute to AttributeSet
will lead to this same issue described in the bug report.
Yes, since CSS Attributes are quite extensive, I have only addressed part of it in this PR mainly CSS.Font properties.. |
It sounds reasonable but you have to update the bug summary to make it clear that this bug resolves the issue for Then, I think you should create a new bug for |
test/jdk/javax/swing/text/html/CSS/CSSAttributeEqualityBug.java
Outdated
Show resolved
Hide resolved
test/jdk/javax/swing/text/html/CSS/CSSAttributeEqualityBug.java
Outdated
Show resolved
Hide resolved
@prrace @aivanov-jdk Any other comments for this 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.
Can all the subclasses of CssValue
be compared with correct result?
May I suggest a simplified version of the CSSAttributeEqualityBug.java test which contains a list of CSS declarations which produce equal attribute sets and another list of declarations which produce non-equal attribute sets. The updated test covers all the existing cases as well as a few more cases for which I raised my concerns above. To add a new test case, just add a new entry into either |
To be more specific, it produces the following output:
The new test does not provide direct references to |
@prrace @aivanov-jdk Any further comments on this PR? I would like to get it in by RDP1 if it is possible and I guess contentious issues are sorted |
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.
Please confirm this test (and all other relevant tests) still pass.
Approving in anticipation of confirmation of the above.
@prsadhuk This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 1016 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
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.
Overall, it covers most of the values now. There are a couple of omissions though: BackgroundImage
, BorderWidthValue
(it could be handled automatically by its superclass, LengthValue
).
I assume CssValue
is never used directly, is it?
public boolean equals(Object val) { | ||
if (percentage) { | ||
return val instanceof CSS.LengthValue lu | ||
&& Objects.equals(svalue, lu.svalue); |
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.
Doesn't comparing span
work for percentage values? The comment for span
field implies it should contain the parsed value.
This comparison could fail for the case where there's a space before the %
in the string.
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 comparison could fail for the case where there's a space before the
%
in the string.
FontSize
does handle {"font-size: 100%", "font-size: 100 %"}
pair, but LengthValue
doesn't.
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.
No, it doesn't. For some reason, both 100%
and 200%
are parsed so that span = 1.0
.
Let's leave it as is then. It handles the most common case.
Handling a space before the percent sign can be postponed to a later fix.
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.
Aha, the value is capped at 100%:
jdk/src/java.desktop/share/classes/javax/swing/text/html/CSS.java
Lines 2627 to 2628 in 4683844
lv.span = Math.max(0, Math.min(1, lu.value)); | |
lv.percentage = true; |
This is why 200% is parsed as if it were 100%.
The following code
public boolean equals(Object val) {
return val instanceof CSS.LengthValue lu
&& percentage == lu.percentage
&& span == lu.span
&& Objects.equals(units, lu.units);
}
works correctly if you modify this line in the test
{"margin-top: 100%", "margin-top: 200%"}, |
to
{"margin-top: 100%", "margin-top: 50%"},
The above code also handles the case "margin-top: 50 %"
correctly.
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 had already made that observation in this comment few days back in case you overlooked
Also, I kept the percentage check for string even though it fails for "space" within string because it seems "space" is not valid in between % value but we can go beyond 100% ie 50 %
is not valid but 200%
is,
as per https://developer.mozilla.org/en-US/docs/Web/CSS/margin-top
where if you specify margin-top: 50 %
and then go to other block and come back, you will get a "X"
but
margin-top: 200%
is ok
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 had already made that observation in this #13405 (comment) days back in case you overlooked
I did miss this comment. Sorry about that.
Even though space between the value and the percent sign or the units is invalid (I couldn't find it quickly in the W3C spec for CSS), you should compare the parsed values. We pass 100%
and 200%
but the parsed value is 100%
in both cases — the attribute sets are indeed equal. If you apply either attribute set to a document, you'll get the same result. Does it make sense?
There could be other cases where the computed/parsed values are the same even though the input is different, for example "font-size: medium"
has a numeric value in points or pixels, so the attribute set with the same value should be equal, don't you agree?
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 am not sure on 100%, 200% ie >= 100% should be considered equal or not..I could not find in spec...also the URL I gave has 200% as valid value...so as of now I have considered what is normal and made equals
return false for different percentages irrespective of < or > 100%..
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 also think that capping at 100% is wrong but it's another bug.
Currently, both 100% and 200% result in attribute sets which behave as if both were 100%, therefore they should be equal. I strongly believe we should compare the parsed values not the input string.
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.
OK. Fair enough..guess CSS implementation and equality should match...Modified...
Upper capping and equality can be looked at later if needed
@prsadhuk, could you add me as the contributor for the test and |
Yep, it's handled correctly |
So, there are no show-stoppers except for my minor comments. |
Yes, all "clientlibs" test passed along with this test |
/contributor add @aivanov-jdk |
@prsadhuk |
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.
Thank you for updating the code.
return val instanceof CSS.LengthValue lu | ||
&& span == lu.span | ||
&& Objects.equals(units, lu.units); |
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.
The percentage
field must also be part of equals
:
return val instanceof CSS.LengthValue lu | |
&& span == lu.span | |
&& Objects.equals(units, lu.units); | |
return val instanceof CSS.LengthValue lu | |
&& percentage == lu.percentage | |
&& span == lu.span | |
&& Objects.equals(units, lu.units); |
You have included it in hashCode
.
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.
If percentage
isn't taken into account, the pair {"margin-top: 100%", "margin-top: 1"}
is considered equal. (And it essentially is; however, I think we should include the percentage
field, it is part of the object and the behaviour will be different.)
By the way, this is another quirk of Swing's CSS implementation: in the CSS spec, values without units are considered an error except for a few cases where such usage is specifically allowed.
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.
Updated..
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.
Perfect! Looks to me now.
/integrate |
Going to push as commit d2a858e.
Your commit was automatically rebased without conflicts. |
Two CSS AttributeSet-s can be compared using the AttributeSet.isEqual() method which can fail due to missing implementation of equals method in CSS subclasses.
In this issue, even when two CSS AttributeSet has same 42 font size string value, Object equality fails.
Fixed by implementing the equality and hashCode method for CSS.FontSize class.
All jtreg/jck tests are ok
Progress
Issue
Reviewers
Contributors
<aivanov@openjdk.org>
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/13405/head:pull/13405
$ git checkout pull/13405
Update a local copy of the PR:
$ git checkout pull/13405
$ git pull https://git.openjdk.org/jdk.git pull/13405/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 13405
View PR using the GUI difftool:
$ git pr show -t 13405
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/13405.diff
Webrev
Link to Webrev Comment