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

Is this possible to obfuscate "hover:" class name or something like that from TailwindCSS? I also have some question and feature request #6

Closed
hoangnhan2ka3 opened this issue Jan 29, 2024 · 34 comments
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@hoangnhan2ka3
Copy link

First of all, I really appreciate your efforts on this project ✨, thank you @soranoo and all Sponsors !

This is almost what I needed, really easy to use, really full features and highly customizable.
Besides, it also helps my code look mysterious 😈 and professional.

I want to make some contributions to make this project even more perfect, to be widely known and to be a perfect replacement for a certain "no longer maintained package" named Post*** 😄.

My specs:

OS: Windows 11
IDE: VS Code v1.85.2
Nextjs 14.1
Frontend cloud: Vercel
Using: next-css-obfuscator v2.0.6

👉 1. Also obfuscate something like "hover:" in TailwindCSS class:

There are things that are really easy to confuse like *:hover in normal CSS and hover:* in TailwindCSS class, both have hover and :.

In my test project, I have ONLY one class end with "...text-yellow-300" (I mean there is no other class named "yellow") like this:

Screenshot 2024-01-29 070831


And when npm run build, in css-obfuscator/conversion.json file:

Screenshot 2024-01-29 071613

(I also delete .next/cache folder and old css-obfuscator folder, which contain conversion.json before running this build command).

Result:

Screenshot 2024-01-29 092640


In expected:

".hover\\:text-yellow-300": ".kj33u9",

// or at least

".hover\\:text-yellow-300": ".hover\\:kj33u9",

But no. So... I don't know what is the :hover suffix (which is the main problem) when detecting that class name 🥲. And why it detect another alone class ".text-yellow-300" which doesn't exist.

Actually, I found a temporary solution when editing your utils.js file in the node_modules folder, I will talk about this problem in part 2.

👉 2. The problem of selectorClasses.length > 1:

I think part of the problem lies in this line of utils.js:

if (selectorClasses.length > 1) {

When I edit it to selectorClasses.length >= 1, this is the result:

Screenshot 2024-01-29 081320

"Nears". But of course this does not work ⛔ too because of wrong class detected with :hover suffix.

Doesn't stop there, this edit also affects "single character" then "-[${custom parameter}]"
eg: z-[9999], min-h-[80rem], etc. (almost all)


With selectorClasses.length > 1:

Screenshot 2024-01-29 092229


With selectorClasses.length >= 1:

Screenshot 2024-01-29 084939

Almost every TW custom parameter class except hover: works perfectly (for me) with selectorClasses.length >= 1. And I run dev, run build + run start or deploy to Vercel with no error (I haven't tried all the TW classes and don't know if there are any special cases or exceptions, but this works for me for now)

🫶 If possible, please update an option for this selectorClassesLength as a temporary solution for custom parameter TW class.

👉 3. Truth about select direct child "*:":

If u know u know:

Screenshot 2024-01-29 094126

Even though this *: class exists in the parent div, it really only has an effect on the children div.

I'm really not sure what will happen if we successfully obfuscate this *: class ⁉️

Screenshot 2024-01-29 094937

I think it's possible but quite difficult to do hmmm...

The script is to just obfuscate the .\\*\\:font-extrabold part and I think

.jzn6lz > * {
    font-weight: 800;
}

will do the rest.

Okay and... the remain problem of *: is same same as hover:

Screenshot 2024-01-29 095924

It is true that it must be .\\*\\:font-extrabold > * to work but we don't need to detect the > * part but .\\*\\:font-extrabold right?

At last I do think that fix the hover: problem is much possible than *: haha 😄.

👉 4. Feature request:

Screenshot 2024-01-29 101716

You know 👉👈... I think this feature is not useless but it's really not as useful as doing the opposite. I mean the tag with marker class will not be obfuscated, it is more valuable to use than having to add a marker to each tag you want to obfuscate, but yes, don't delete the current option because it is usable in some cases. Is it possible?

And once again I really thank you and everyone who has contributed and built this project, please continue to develop it further 🥳.

@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 29, 2024

Oh, I forgot, I was very surprised that when using selectorClasses.length >= 1, the class .animate-\\[pulse-404_3s_linear_infinite\\] becomes a super concise class like .w2zhoa but still used okay haha, that's the unexpected effect of this package.

Edited:
Hmmm... I am wrong. I wonder why it didn't delete the old TW class because now it's useless huh 🥲.

Screenshot 2024-01-29 234226

Now I know why you said in Warning "As a trade-off, the obfuscation will make your CSS files larger"

Maybe it's still not optimized as well as I thought 🤡.

@soranoo
Copy link
Owner

soranoo commented Jan 29, 2024

What a fantastic issue format! I really appreciate your enthusiasm and contribution to this package.

  1. Regarding the issues, I will investigate them ASAP.
  2. Regarding the opposite of obfuscate marker, I don't think it is a good idea to implement it right now. There is serious issue (see the 🐛 Known Issues) with the current obfuscate marker feature and I don't think I can solve it shortly. The bigger obstacle at this moment is the way to track functions being called within a component so that we can obstacles its children's component. I tried to parse the JS and have some proof of concepts but I don't think I have enough knowledge handling this. If you are familiar with it please, please give me some hints.

@soranoo soranoo added the good first issue Good for newcomers label Jan 29, 2024
@soranoo
Copy link
Owner

soranoo commented Jan 29, 2024

Plus, if you have a test project for this, would you mind to share with me?

@hoangnhan2ka3
Copy link
Author

Thank you for reply!

  1. Actually, I've been intending to obfuscate this TW class for a long time. I only see facebook.com and blueagle.top available. like this, but it seems that the two still cannot agree on the number of characters in the obfuscated class, which is still not perfect (unlike your package 💕).

  2. Yeah you're right, the issue of opposite markers is probably not the highest priority right now. If feasible, can you address the fixable issues first? I mean the selectorClasses.length >= 1 problem.

  3. Regarding testing project, I will comment here ASAP when I finish preparing. (Again, sorry that's as far as I can help right now).
    This is my test domain, you can check out. Try the 404 page with mouse wheel scroll 😄.

  4. I actually have more than one feature request 😄

  • Like being able to identify and replace the class .big in const bigElement = document.querySelector(".big")
  • A feature to delete the old TW class because really after If there is a new obfuscated class, the old class is no longer needed, and if it exists, it will really increase the weight of the css file. It might be really difficult but try reversing the way you detect the classes before obfuscating and saving, then after everything is done, delete it.

    (I'm not sure if after running this package, new classes are created. Did it release at once and then add it with TW's css file? Or the obfuscate process is done "in parallel" with TW's css file export process, because I see each new obfuscated class coming next to a class with similar functionality but of TW. Rather than the entire new obfuscated class being located at the bottom of the css file or separated into another file).

If you can really do this, this will be a huge boom for your package.

#waitingforamiracle

@soranoo soranoo added the bug Something isn't working label Jan 29, 2024
@soranoo
Copy link
Owner

soranoo commented Jan 29, 2024

Yes, fixing the bugs is my top priority right now.

Regarding the feature request,

  1. So you would like to replace a specific class with a class you want?
  2. Maybe I should add an option to del all TW classes if they have an obfuscated version (for full obfuscation). The reason I keep the TW classes is to prevent breaking the site when some obfuscation fails.

soranoo added a commit that referenced this issue Jan 29, 2024
[#] Better action pseudo-class handling
[+] Able to filter out vendor pseudo-classes
[+] Able to handle Tailwind CSS selector's number with "." and "/", eg. "ml-0.5", "ml-1/2"
[+] Able to handle Tailwind CSS negative selector, eg. "-ml-1"
[+] Able to handle [attribute / Tailwind CSS custom parameter] selector
@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 30, 2024

Yeah if you can actually delete exactly the OBFUSCATED TW classes then maybe there won't be any problem 🫡, otherwise you can try making a beta version of the package for example.

But I think you can fix the other problems first and then remove the old TW class problem for the end.

soranoo added a commit that referenced this issue Jan 30, 2024
[-] Removed `customTailwindDarkModeSelector` Option
[#] Updated Unit Tests
soranoo added a commit that referenced this issue Jan 30, 2024
@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

@hoangnhan2ka3 The beta version is ready!

npm run next-css-obfuscator@beta

Looking forward to your feedback~

@hoangnhan2ka3
Copy link
Author

hi there @soranoo =))))

This my first look about the fix of *: class

Screenshot 2024-01-31 084943

Wait for me for full feedback, looks very interesting 💣

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

Investigation Report

  1. hover: and :hover
    • Since I have used Tailwind for quite a long time I had forgotten the hover: is from Tailwind. 🙃
    • Incorrect pseudo-classes handling. bb90dd0
  2. The problem of selectorClasses.length > 1 and Tailwind universal selector

Feature Update

  • Removed customTailwindDarkModeSelector option
  • Delete original CSS automatically after obfuscation (for full obfuscation)

New README

@hoangnhan2ka3
Copy link
Author

I'm extremely honored to be tagged in the README ✨.

And I'm surprised by the structure of your code after this change quite a bit, thank you for your effective efforts 🎉.

There are actually a lot of improvements, especially with the hover: class, which is almost fine for now.

You also fixed the problem bb90dd0#commitcomment-138032346

Screenshot 2024-01-31 115010

which is noice 💕💕.

Ok now let's get to the main point.

👉 1. The Biggest One *: class:

hi there @soranoo =))))

This my first look about the fix of *: class

Screenshot 2024-01-31 084943 Wait for me for full feedback, looks very interesting 💣

Well~, the problem is the same of hover: class I've commented on your edit bb90dd0#commitcomment-138032286 yesterday:

  • Obfuscated ✅:
Screenshot 2024-01-31 100206

Good group separation !

  • Replaced ✅:
Screenshot 2024-01-31 100933


Screenshot 2024-01-31 102537

Yeah I mean "replace", not "change":

/* From this */
.\*\:justify-center > * {
    justify-content: center;
}

/* To this */
.\*\:hbk62l > * {
    justify-content: center;
}

IN THE CSS FILE !!!

Or at least for now, it can be called "add more".
Because the problem I'm about to talk about in next part still doesn't seem to be quite right, even though you mentioned it in the Change log.

  • Doesn't have an effect cuz there are no .hbk62l in css file ⛔:
Screenshot 2024-01-31 103556

I also tried deploying to Vercel, Redeploy without caching,... but nothing changed...

👉 2. Is this real 🤔:

In new beta Readme, you said Delete original CSS automatically after obfuscation (only apply at full obfuscation), WOW 🤯.

After reading carefully the new Tips section, I think it's an issue.

Looks like I haven't experienced that yet, don't know if it's a problem because I'm using tsx or if our version is different.
As u can see, unused classes have not been deleted/ replaced. (I tried with one default and one custom TW class but same output parameter)

Screenshot 2024-01-31 105911

Easy-to-see version of View page source:

Screenshot 2024-01-31 110951

In conversion.json file:

Screenshot 2024-01-31 110821

But please don't worry, as I said before, let's solve the superficial problems first, a little file size of css file is not a big deal now, but it would be a really great option if it could be done.

I was planning to suggest more features but it doesn't seem necessary right now, I'm looking forward to your next patch @soranoo .

In addition, I also discovered some more bugs:

  • Although these classes have been included in classIgnore, perhaps this update makes it no longer work.
Screenshot 2024-01-31 111813

In my next-css-obfuscator.config.cjs:

Screenshot 2024-01-31 112404
  • Select/ detect class without space with attribute:
Screenshot 2024-01-31 114415

Yeah this [pop-t], [pop-b], [pop-l] and [pop-r] is my custom attribute used for long-hover popup like this:

Screenshot 2024-01-31 113209 Screenshot 2024-01-31 113314

Just like title attribute:

Screenshot 2024-01-31 113506

The project containing pop is an old project based on static HTML so I haven't tried it on the Nextjs project this time, but I think it will also have some problem with deleting/ replacing the obfuscated class inside. css files

@hoangnhan2ka3
Copy link
Author

It seems more correct then ~ @soranoo

Before:

Screenshot 2024-01-31 110318

After:

Screenshot 2024-01-31 194007

✨ I don't see classes that should not be duplicated anymore.

But what happen with the new CSS rules count haha 🤔.

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

Tailwind Universal Selector

  • Regarding the Tailwind universal selector, *\:class is a single class (like dark\:class and hover\:class) so there is no reason to treat it differently.

classIgnore

  • The classIgnore is expected to only accept string[ ] therefore RegExp doesn't work with it. (I will support it later on)
  • I don't see any issue with classIgnore. But note that .hex.hex-c are two classes, you should register them as ["hex", "hex-c"] not ["hex.hex-c"]

[attribute] Selector

@hoangnhan2ka3
Copy link
Author

✨Report to commander @soranoo , mission success !

Screenshot 2024-01-31 224212 Screenshot 2024-01-31 223634 Screenshot 2024-01-31 224055

I've been trying with new CSS rules count but it still doesn't work 🥲
Please provide an official version to npm.

Screenshot 2024-01-31 223801

@hoangnhan2ka3
Copy link
Author

Plus, there are 2 Obfuscation in the log 👀:

Screenshot 2024-01-31 231643

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

Let's have a final beta before release!

npm run next-css-obfuscator@beta

I had added/merged some options. Btw classIgnore option now supports Regex.
New README

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

Plus, there are 2 Obfuscation in the log 👀:

Screenshot 2024-01-31 231643

I will remove it before the official release.

soranoo added a commit that referenced this issue Jan 31, 2024
@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 31, 2024

Okayyyy newwww buggggg:

// layout.tsx

import localFont from 'next/font/local';

const gilroy = localFont ({
    src: [
        {
            path: "../fonts/SVN-Gilroy.woff2",
            weight: "400",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyMedium.woff2",
            weight: "500",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroySemiBold.woff2",
            weight: "600",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyBold.woff2",
            weight: "700",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyHeavy.woff2",
            weight: "800",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyBlack.woff2",
            weight: "900",
            style: "normal",
        },
    ],
});

export default function RootLayout({
    children,
}: Readonly<{
    children: React.ReactNode;
}>) {
    return (
        <html lang="en" className={gilroy.className}>
            <head>
                <meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1" />
                <meta name="last-modified" content={new Date().toLocaleDateString()}/>
            </head>
            <body className="dark">
                <noscript>You need to enable JavaScript to run this site.</noscript>
                <ProgressTopbar />
                <main className="flex">
                    <HomeLayout />
                    <div className="p-6 size-full">
                        {children}
                    </div>
                </main>
            </body>
        </html>
    );
}

U see <html lang="en" className={gilroy.className}>

In production, it will look like this if no obfuscation:

Screenshot 2024-01-31 233519

Please refer to Nextjs local fonts

I tried not including __className_38b0b7 in classIgnore so it looks like a normal person.

And when run this package:

In normal pages ✅:

Screenshot 2024-01-31 234832

In 404 page ⛔(a.k.a not-found.tsx page) :

Screenshot 2024-01-31 234112

Yes, fonts have not been applied.

In previous comments, I put __className_38b0b7 in classIgnore so I didn't detect this problem.

__className_38b0b7 will not change even when deploying or run build + run start or run dev, but when you add fonts or update fonts I think it will change. So I think adding exactly __className_38b0b7 to classIgnore is not a good idea, right?

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

try put /__.*/ into classIgnore?

@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 31, 2024

Nope,

  • Case 1:
Screenshot 2024-01-31 235339

Result 1:

Screenshot 2024-01-31 235142
  • Case 2:
Screenshot 2024-01-31 235436

Result 2:

Screenshot 2024-01-31 235304

Do you have any updates about classIgnore that I missed? Do I need to update?

I tried putting className={gilroy.className} in body as well but still the same.

@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 31, 2024

okay I just updated with classIgnore which already supports Regex, everything is fine, so a class like __className_38b0b7 cannot be obfuscated, right?

I also just tried with some other Regex and they work fine too:

Screenshot 2024-02-01 002907

Result:

Screenshot 2024-02-01 003257

Thanks @soranoo 💕!

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

I guess yes... I will add this to the doc

@hoangnhan2ka3
Copy link
Author

So it seems like there's only one "problem" left, which is replacing the class in querySelector or something like that.

Screenshot 2024-02-01 003650

I tried removing .big and .small from classIgnore and the rotation effect no longer seems to work.

@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 31, 2024

One more :)))) Sorry I'm so annoying just pointing out the bug without doing anything to help you 🥲.

👉 filter tag inside svg tag:

Screenshot 2024-02-01 005032

In the comments above, I had to put filter in classIgnore to not cause the filter tag to obfuscate, hmmm... I don't know why it detected filter tag as a class.

Screenshot 2024-02-01 005433

In conversion.json file:

Screenshot 2024-02-01 005736

OMG is it really a class 🤯? How.

Note: filter attribute was not changed ✅:

Screenshot 2024-02-01 010832

👉 Also with iframe tag:

Screenshot 2024-02-01 010014 Screenshot 2024-02-01 010221

I thought it was an element of HTML huh?

Screenshot 2024-02-01 010054

With <filter>:

Screenshot 2024-02-01 010346

Without <filter>:

Screenshot 2024-02-01 010400

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

So it seems like there's only one "problem" left, which is replacing the class in querySelector or something like that.

Screenshot 2024-02-01 003650 I tried removing `.big` and `.small` from `classIgnore` and the rotation effect no longer seems to work.

I don't think is it a good idea to use querySelector but not useRef. You are using React not jQuery

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

After some testing, I decided not to edit the regex since the javascript obfuscation will messed up by that ..

@hoangnhan2ka3
Copy link
Author

That's okay, don't try too hard

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

For a temp fix, add the following to the class conversion json,

{
// ....
"..big": ".big",
}

@hoangnhan2ka3
Copy link
Author

That's not called a natural deployment, right?

Okay, I'll live with .big and .small in classIgnore, no problem 🤡

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

Yes, directly editing the conversion JSON is not recommended. Btw can I mention your site in the dome section?

@hoangnhan2ka3
Copy link
Author

Ok, but let me provide another domain with same content, cuz I will use hoangnhan.uk for more deployment.

U can use hoangnhan.co.uk, I will update it in a minute

@hoangnhan2ka3
Copy link
Author

hoangnhan2ka3 commented Jan 31, 2024

hoangnhan.co.uk is ready @soranoo, I just wait for new npm package to update and u can mention it.

or when I finish my project on my main domain hoangnhanne.id.vn, you can mention it too :D.

@soranoo
Copy link
Owner

soranoo commented Jan 31, 2024

Please notify me when your site goes into production! Looking forward to your fantastic work.

@hoangnhan2ka3
Copy link
Author

It's just a 100dvh website haha 🤡

@soranoo soranoo closed this as completed in 858b3f2 Feb 1, 2024
@soranoo
Copy link
Owner

soranoo commented Feb 1, 2024

@hoangnhan2ka3 The 2.1.0 is out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants