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

Fix ignoreFlag not works bug #2751

Merged
merged 8 commits into from
Aug 22, 2022
Merged

Fix ignoreFlag not works bug #2751

merged 8 commits into from
Aug 22, 2022

Conversation

kyoncy
Copy link
Contributor

@kyoncy kyoncy commented May 17, 2022

What:
Fix #2478

When using the ignoreFlag for nth-child being potentially unsafe with server rendering, the first instance of the flag works while the second does not (workaround provided).

Why:
To ignore unsafe selector warning.

How:
The current implementation only compared the previous element, so all elements are now compared.

Checklist:

  • Documentation N/A
  • Tests
  • Code complete
  • Changeset

@changeset-bot
Copy link

changeset-bot bot commented May 17, 2022

🦋 Changeset detected

Latest commit: b82bcee

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@emotion/cache Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

@srmagura srmagura left a comment

Choose a reason for hiding this comment

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

Nice work! This looks good to me, but let's wait for @Andarist's approval.

Can you add a changeset to record this patch-level change to @emotion/cache?

Edit: I noticed that CI is failing with

@emotion/cache "@babel/runtime/helpers/createForOfIteratorHelperLoose" is imported by "src/stylis-plugins.js" but the package is not specified in dependencies or peerDependencies

This is caused by the for..of loop you added. We still technically support IE 11, so we have to stick to old-school JS in some places. Can you refactor the for..of to a classic for loop or a .forEach()?

@srmagura srmagura requested a review from Andarist May 17, 2022 13:59
@codesandbox-ci
Copy link

codesandbox-ci bot commented May 17, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit b82bcee:

Sandbox Source
Emotion Configuration

@codecov
Copy link

codecov bot commented May 17, 2022

Codecov Report

Merging #2751 (b82bcee) into main (d39379c) will decrease coverage by 1.08%.
The diff coverage is 81.25%.

Impacted Files Coverage Δ
packages/cache/src/stylis-plugins.js 86.08% <81.25%> (-13.92%) ⬇️
packages/serialize/src/index.js 93.98% <0.00%> (-6.02%) ⬇️
packages/react/src/global.js 94.73% <0.00%> (-3.51%) ⬇️
packages/react/src/class-names.js 97.10% <0.00%> (-2.90%) ⬇️

@kyoncy
Copy link
Contributor Author

kyoncy commented May 17, 2022

@srmagura
Thanks for reviewing!

Can you add a changeset to record this patch-level change to @emotion/cache?

Add a changeset commit!

Can you refactor the for..of to a classic for loop or a .forEach()?

I used classic for loop because it is returnable!

Copy link
Contributor

@srmagura srmagura left a comment

Choose a reason for hiding this comment

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

Apart from making the changeset more descriptive, this looks good to me. The changesets end up in our release notes so they need to clearly explain what was changed.

.changeset/witty-frogs-hear.md Outdated Show resolved Hide resolved
@kyoncy
Copy link
Contributor Author

kyoncy commented May 24, 2022

@Andarist How is this going?

@@ -52,6 +66,20 @@ exports[`unsafe pseudo classes does not warn when using with flag: /* emotion-di
/>
`;

exports[`unsafe pseudo classes does not warn when using with flag: /* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */ ":first-child :nth-child(3) /* [flag] */" in a style multiple selectors 1`] = `
Copy link
Member

Choose a reason for hiding this comment

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

Based on the [flag] here it seems that the original intention was to replace that long string in test titles to aid the readability. There is .replace call somewhere that perhaps doesn't replace all occurrences of that flag in the input string - could you check if this assumption is correct and if we could fix this?

Copy link
Member

Choose a reason for hiding this comment

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

ah, actually the full flag is part of the describe's title and is literally passed in there:

describe(`does not warn when using with flag: ${ignoreSsrFlag}`, () => {

So we don't need to change anything here and that was the original intention (perhaps we could change it separately, but it doesn't matter)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is .replace call somewhere that perhaps doesn't replace all occurrences of that flag in the input string

Replaced by /* [flag] */ here.

it(`"${pseudoClass.replace(
/\/\* \S+ \*\//g,
'/* [flag] */'
)}" in a style ${type}`, () => {

Do you need to modify or add test cases?

Comment on lines 170 to 175
for (let i = 0; i < children.length; i++) {
const element = children[i]
if (element && isIgnoringComment(last(element.children))) {
return
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Could you describe the change? What was the assumption of the previous code? How the fixed case is different and why it didn't work with the previous logic? What was the thought process behind the introduced change? I would appreciate if you could show the AST layouts of different cases so it would be easier to reason about this fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the previous logic, only the first ignoreFlag in a style worked.
Therefore, CI passed, but if there were multiple styles and the second or later style used unsafe pseudo classes (ex. :first-child), an error would be displayed even if the ignoreFlag was given.

@Andarist
Copy link
Member

Could you check if this would fix the recently reported issue: #2763 ?

@kyoncy
Copy link
Contributor Author

kyoncy commented Aug 18, 2022

Could you check if this would fix the recently reported issue: #2763 ?

@Andarist
Sorry for the late reply.
I applied the modifications and deployed the same code as in the codesandbox example!

deployed site: https://kyoncy.github.io/emotion-test/
repository: https://github.com/kyoncy/emotion-test/tree/main

@Andarist Andarist requested a review from emmatown August 18, 2022 22:43
@Andarist
Copy link
Member

@kyoncy thanks for taking a look. I've pushed out some commits to make this comment detection more strict - we should be able to land this soon. I will just wait a couple of days to give a chance to other maintainers to review this

@Andarist Andarist requested a review from srmagura August 18, 2022 22:45
@Andarist Andarist merged commit 0ffd606 into emotion-js:main Aug 22, 2022
@github-actions github-actions bot mentioned this pull request Aug 22, 2022
@swernerx
Copy link

Hi! I know this is not a fully valid bug report. Still it seems that updating from v11.10.1 to v11.10.2 breaks in our application. I receive the error: Cannot read properties of undefined (reading 'type') at isIgnoringComment2. Possibly element can be null/undefined?

@swernerx
Copy link

swernerx commented Aug 23, 2022

Seems to be related to:

var isIgnoringComment = function isIgnoringComment(element) {
  return element.type === 'comm' && element.children.indexOf(ignoreFlag) > -1;
};

which can be fixed using:

var isIgnoringComment = function isIgnoringComment(element) {
  return element && element.type === 'comm' && element.children.indexOf(ignoreFlag) > -1;
};

@swernerx
Copy link

The code involved producing the issue is:

  terminatedContract: {
    '& .contractIcon, tr:nth-child(1) td:nth-child(1), tr:nth-child(n+2) td': {
      opacity: 0.4
    }
  }

I guess it's related to the multiple usage of :nth-child. When I migrate that code to:

  terminatedContract: {
    '& .contractIcon, tr:nth-of-type(1) td:nth-of-type(1), tr:nth-of-type(n+2) td': {
      opacity: 0.4
    }
  }

the issue disappears.

@Andarist
Copy link
Member

Thank you for the report - I've already merged in the fix for this and gonna release a new version in a second.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Potentially Unsafe Server-Rendering flag works on the first instance only
4 participants