jackall3n / postcss-scope

🔭 A small plugin to allow you to scope your css with a custom selector
5 stars 2 forks source link

handling of multi-line selectors #3

Closed JimCat1103 closed 1 year ago

JimCat1103 commented 1 year ago

Thank you for providing this small plugin. I noticed a potential issue with the current handling of multi-line selectors in this specific piece of code:

if (node.type === "rule") {
    if (/^(body|html|:root)/.test(node.selector)) {
        node.selector = node.selector.replace(/^(body|html|:root)/, scope);
        return;
    }
    node.selector = `${scope} ${node.selector}`;
}

The current implementation seems to fail under certain circumstances, such as when node.selector is

html,
body 

, the output will becomes

scope,
body

or node.selector is

h1,
h2,
h3

, the output will becomes

scope,
h2,
h3

I have made an optimization in the code:

if (node.type === 'rule') {
    // use /gm for all global and multi-line
    if (/^(body|html|\*|:root)/gm.test(node.selector)) {
      node.selector = node.selector.replace(/^(body|html|\*|:root)/gm, scope);
      return;
    }
    // Split the selector into multiple lines
    let selectors = node.selector.split('\n');
    // Add scope to each line
    selectors = selectors.map(selector => `${scope} ${selector}`);
    // Join them back into a single string
    node.selector = selectors.join('\n');
}

I hope this can be helpful. Thank you.

jackall3n commented 1 year ago

Hi @jim19901103,

Thanks for raising this, and thanks for the optimisation! I was able to use postcss-selector-parser in the end which supports this functionality.

I've released 1.6.0 with this fix.