Git Product home page Git Product logo

Comments (3)

jhildenbiddle avatar jhildenbiddle commented on August 26, 2024

Thank you for the kind words, @helgenlechner. Much appreciated, and happy to hear the ponyfill has worked well for you.

The behavior in the selector() function you are referring to is used to detect individual selectors within in a comma-separated list of selectors. Sanitized CSS is a side effect, not the goal. There are definitely optimizations that can be done though.

First, I've copied the selector() source below and added comments to explain each mutation:

// Match selector
const m = match(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/);

if (m) {
    return m[0]
        .trim()
        // Remove comments
        .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
        // Replace comma in comma-separated lists with marker
        .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m) {
            return m.replace(/,/g, '\u200C');
        })
        // Create array from comma-separated list of selectors
        .split(/\s*(?![^(]*\)),\s*/)
        // Restore comma in comma-separated lists
        .map(function(s) {
            return s.replace(/\u200C/g, ',');
        });
}

Here are a few CSS selector examples that would trip up the parser without the code above:

html,
/* :root, */
body {
 ...
}

.foo,
.bar, /* Comment, with a comma */
.baz {
  ...
}

body[attr="foo,bar"] { ... }

One issue with the selector() code above is that it processes all selectors the same way. Performance can be improved by implementing simple checks first to determine if more complex mutations need to be done. For example, if a simple test for /* within the selector string fails, we don't need execute a complex regular expression to replace all comments in a selector. The end result is that complex selectors may take bit longer, but simple selectors will be processed much faster. I've implemented these changes in branch 160:

function selector() {
whitespace();
while (css[0] === '}') {
error('extra closing bracket');
}
// Match selector
const m = match(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/);
if (m) {
let selector = m[0].trim();
let selectorItems;
const hasComment = /\/\*/.test(selector);
if (hasComment) {
// Remove comments
selector = selector.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '');
}
const hasCommaInQuotes = /["']\w*,\w*["']/.test(selector);
if (hasCommaInQuotes) {
// Replace comma in comma-separated lists with marker
selector = selector.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m) {
return m.replace(/,/g, '\u200C');
});
}
const hasMultipleSelectors = /,/.test(selector);
// Create array of selectors
if (hasMultipleSelectors) {
// From comma-separated list
selectorItems = selector.split(/\s*(?![^(]*\)),\s*/);
}
else {
selectorItems = [selector];
}
if (hasCommaInQuotes) {
// Restore comma in comma-separated lists
selectorItems = selectorItems.map(function(s) {
return s.replace(/\u200C/g, ',');
});
}
return selectorItems;
}
}

Feel free to check out the branch, run npm build, and test the results of the optimizations with your project. For reference, I ran a few rudimentary tests locally and saw a 50% increase in selector() performance. If all goes well, I'm happy to merge these changes and publish an update.

from css-vars-ponyfill.

helgenlechner avatar helgenlechner commented on August 26, 2024

Hi @jhildenbiddle! Looks like a great solution! I'm getting a nice performance improvement as well. Nice that a new option isn't needed either. Thank you for the quick help!

from css-vars-ponyfill.

jhildenbiddle avatar jhildenbiddle commented on August 26, 2024

@helgenlechner --

Published as 2.4.6. The feature branch has been removed, so be sure to update your package.json accordingly.

from css-vars-ponyfill.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.