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

Enable hooks to drop / retain individual css declarations #50

Open
daKmoR opened this issue Feb 10, 2021 · 1 comment
Open

Enable hooks to drop / retain individual css declarations #50

daKmoR opened this issue Feb 10, 2021 · 1 comment
Labels
enhancement New feature or request

Comments

@daKmoR
Copy link

daKmoR commented Feb 10, 2021

I want to optimize css file across multiple html files... those css files could be different so it would be nice if you could drop or retain individual declarations. Potentially via didRetainDeclaration and dropDeclaration.

it would allow doing something like this...

Screenshot 2021-02-09 at 00 32 58

if you would be interested in supporting this I could prepare a PR for it 🤗

let me know what you think 🤗


Some more details

I currently have it working in a fork and it usage looks like this

dropcss({
  html: page.html,
  css: page.css,
  didRetain: selector => {
    let sharedCount = sharedUsage.has(selector) ? sharedUsage.get(selector) : 0;
    sharedUsage.set(selector, sharedCount + 1);
  },
  didRetainDeclaration: ({ selector, property, value }) => {
    const key = `${selector} { ${property}: ${value} }`;
    let sharedCount = sharedDeclarations.has(key) ? sharedDeclarations.get(key) : 0;
    sharedDeclarations.set(key, sharedCount + 1);
  },
});

the code change itself is actually rather small and mostly in css.js

function generate(tokens, didRetain, didRetainDeclaration, shouldDropDeclaration) {
  let out = '',
    lastSelsLen = 0;

  for (let i = 0; i < tokens.length; i++) {
    let tok = tokens[i];

    switch (tok) {
      case SELECTORS:
        let sels = tokens[++i];
        lastSelsLen = sels.length;

        if (lastSelsLen > 0) {
          sels.forEach(didRetain);
          sels.forEach(selector => {
            const declarations = tokens[i + 2]
              .split(';')
              .map(line => line.trim())
              .filter(_ => !!_);

            let declarationIndex = 0;
            for (const declaration of declarations) {
              const [property, value] = declaration.split(':').map(value => value.trim());

              if (shouldDropDeclaration({ selector, declaration, property, value })) {
                declarations[declarationIndex] = null;
              } else {
                didRetainDeclaration({ selector, declaration, property, value });
              }
              tokens[i + 2] = declarations.filter(_ => !!_).join(';');
              if (tokens[i + 2] !== '') {
                tokens[i + 2] += ';';
              }
              declarationIndex += 1;
            }
          });
          out += sels.join();
        }
        break;
@leeoniya
Copy link
Owner

leeoniya commented Feb 11, 2021

i don't want to bake this into the core, but would be okay with adding a callback that can hook into this externally via a declaration processor callback here:

dropcss/src/css.js

Lines 204 to 207 in fd9b383

case PROPERTIES:
if (lastSelsLen > 0)
out += '{' + tokens[++i] + '}';
break;

{
   declProc(selsArr, declBlob) {
     // parse and filter declarations, and return new decls blob.
     return myFilteredDeclsBlob;
   }
}

you'll need to pull let sels; out of the for loop, so it can be picked up on the next iteration in PROPERTIES and passed into this callback.

feel free to make a PR if you get this working.

@leeoniya leeoniya added the enhancement New feature or request label Feb 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants