adobe / helix-html-pipeline

A library for rendering the html response in Helix3.
https://www.hlx.live/
Apache License 2.0
13 stars 17 forks source link

Allow all valid class names #731

Closed twhite313 closed 4 weeks ago

twhite313 commented 1 month ago

Is your feature request related to a problem? Please describe. Currently the pipeline sanitizes class names to lowercase and hyphenated. This negates many valid class names, including the use of BEM notation and others.

Currently class names, such as class--name and class__name, are output as class-name in both cases.

Describe the solution you'd like Change the names.map function to allow any valid CSS syntax (https://developer.mozilla.org/en-US/docs/Web/CSS/ident), including, but not limited to:

Describe alternatives you've considered Because this is in the pipeline build, I do not see any other alternatives. Any authored class name gets returned sanitized before block-level code can affect it.

twhite313 commented 1 month ago

I realize this is a potential breaking change. Is there a mechanism to allow users to opt in? Keep the old, add the new behind a flag?

Tested a possible solution. Existing function on top, proposed on bottom, tested with same data set. Proposed retains casing, converts spaces to hyphens, removes leading/training space and hyphens, allows 1-2 hyphen/underscore.

// Existing function
        function sanitizeNames(names) {
            return names.map((name) => name
                .toLowerCase() // Convert to lowercase
                .replace(/[^0-9a-z]+/g, '-') // Replace non-alphanumeric characters with hyphens
                .replace(/^-+/, '') // Removes leading hyphens from the string
                .replace(/-+$/, '')) // Removes trailing hyphens from the string
            .filter((name) => !!name);
        }

        // Proposed function
        function sanitizeClasses(classes) {
            return classes.map((cls) => cls
                .replace(/[^0-9a-zA-Z_-]+/g, '-') // Allow hyphens and underscores
                .replace(/-{3,}/g, '--') // Replace more than 2 hyphens with exactly 2 hyphens
                .replace(/_{3,}/g, '__') // Replace more than 2 underscores with exactly 2 underscores
                .replace(/^-+/, '') // Removes leading hyphens from the string
                .replace(/-+$/, '') // Removes trailing hyphens from the string
                .trim()) // Remove leading and trailing spaces
            .filter((cls) => !!cls);
        }

        // Test data
        const testNames = [
            "MixedCase123",
            "Space In Name",
            "Under_Score",
            "Hyphen-Case",
            "Bob!@#$%^&*()",
            "  ",
            "-removeLeadingHyphen",
            "removeTrainingHyphen-",
            " removeLeadingAndTrailingSpaces  ",
            "block--element__modifier"
        ];

        // Call the function with test data
        const sanitizedNames = sanitizeNames(testNames);
        const sanitizedClasses = sanitizeClasses(testNames);

        // Log the results
        console.log(sanitizedNames);
        console.log(sanitizedClasses);

class-sanitizer

tripodsan commented 4 weeks ago

the class names are generated from author input in the documents, so the existing transformation rules cannot be changed. also, there is no opt-in mechanism for projects yet.