— Roadmap Card
Description
Right now it’s a bit complex the way people can test class names in a processor:
const test = node => node.props.className.split(" ").includes("my-class")
const test = node => /my-class/.test(node.props.className)
User Stories
As a package developer
I want to add processors based on class names
so that the processor tests are easy to use and understand
Possible solution
@orballo proposed these two solutions:
1. Add hasClass() to node
const test = node => node.hasClass("my-class");
2. Switch className to an array
const test = node => node.className.inclues("my-class");
I’m more in favor of the first one because it’s backward compatible.
             
            
              
              
              
            
            
                
                
              
                
           
          
            
            
              
I totally agree.
I think we could redefine this feature to something more general, like adding helpers for processors tests. Another case that I found in some occasions is when you need to get an array of nodes after searching through the tree, which usually requires to implement a recursive function. Maybe something like the following could be helpful:
node.find(node => node.component === "img")
             
            
              
              
              
            
            
                
                
              
           
          
            
            
              Could you add an example of what you are doing right now?
             
            
              
              
              
            
            
                
                
              
           
          
            
            
              Here is an example of a gallery from where I’d like to get an array of images to map them to an array of urls later:
const process = node => {
    const images = (function searchImages(node: Node) {
      let result: Node[] = [];
      if (node.type !== "element") return result;
      if (node.component === "img") {
        result.push(node);
      } else if (node.children && node.children.length) {
        node.children.forEach(child => {
          result = result.concat(searchImages(child));
        });
      }
      return result;
    })(node);
   
   node.props.media = images.map(image => image.props.src);
   node.component = Gallery;
   return node;
}
This could be something like:
const process = node => {
    const images = node.find(node => node.type === "element"
      && node.component === "image");
   
   node.props.media = images.map(image => image.props.src);
   node.component = Gallery;
   return node;
}
             
            
              
              
              
            
            
                
                
              
                
           
          
            
            
              Ok, I see. What about allowing you to apply the same processor pattern?
const images = [];
node.process({
  test: node.component === "image",
  process: node => { images.push(node); }
})
             
            
              
              
              
            
            
                
                
              
                
           
          
            
            
              Ok, I think that would be easier. Anyway, we need a different feature for this. Would you mind opening it @orballo 
             
            
              
              
              
            
            
                
                
              
                
           
          
            
            
              As suggested by @orballo in Styling the HTML content with the `css` prop we can also do something like this instead of node.hasClass:
{
 test: node => node.is(".wp-block-button"),
 test: node => node.is("a.wp-block-button"),
 test: node => node.is("#accept"),
 test: node => node.is('input[type="submit"]'),
}
I think it’s a great idea because people are already used to this syntax and it’s faster and cleaner.
I wonder if there is a JavaScript library that can extract that selector query to tag, class, id and so on…
             
            
              
              
              
            
            
                
                
              
           
          
            
            
              
It wasn’t hard to find: https://github.com/fb55/css-what and it’s only 4Kbs 
             
            
              
              
              
            
            
                
                
              
                
           
          
            
            
              I think we can integrate this with our processors. It’d be really cool to do things like:
// Select anchor that links to a dailymotion video
test: ({ node }) => node.is("a[href^='https://dailymotion.com/video']")
// Select images that belong to a Gutenberg block
test: ({ node }) => node.is("img < .wp-block-image")
// Select images that don't belong to a Gutenberg block
test: ({ node }) => node.is("img < :not(.wp-block-image)")
// Select a figure that has an image children with left alignment
test: ({ node }) => node.is("figure > image.align-left")
// Select a button block with background
test: ({ node }) => node.is(".wp-block-button.has-background")
I have created a little sandbox to play with this: https://codesandbox.io/s/css-what-quop3
You can check it out to see the type of object it returns for each case.