Giter VIP home page Giter VIP logo

postcss-prefixwrap's Introduction

Hello, GitHub!

As a Security Focused Software Engineer, I am committed to participating in the development of a secure and accessible web.

Day Job

I currently work as a Lead Full Stack Web Developer at APNIC focused on Application Security, where I have the privilege of contributing to the organisations vision for "A global, open, stable, and secure Internet".

Open Source

I believe in sharing my knowledge and expertise with the wider development community, and that open source software is a key method to achieve this goal.

CI GitHub Pipeline SAST GitHub Pipeline Latest Release NPM Downloads Per Week

A PostCSS plugin that is used to wrap css styles with a css selector to constrain their affect on parent elements in a page.

CI GitHub Pipeline Deploy GitHub Pipeline

Hugo source code for https://tedman.dev.

postcss-prefixwrap's People

Contributors

ai avatar chocolateboy avatar dbtedman avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dtedman-apnic avatar log1x avatar lucaswerkmeister avatar mend-bolt-for-github[bot] avatar sbusch avatar skellla avatar tullaris avatar vonstroheim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

postcss-prefixwrap's Issues

Handling of root elements

Maybe this is more of a question but I would say that root elements (html, body) are treated a bit incorrectly.

Current behaivour:

Source:

html {
 color: red;
}

body {
 color: blue;
}

Result:

.wrap {
 color: red;
}

.wrap {
 color: blue;
}

Expected result:

html {
 color: red;
}

.wrap body {
 color: blue;
}

or even:

html {
 color: red;
}

body {
 color: blue;
}

Why I think the output should be as follows is: html is the true root element and it cannot have a class on top of that. So yea html tag should be left as it is. But body can already be influenced by html tag.

Unusable with Webpack?

Hiya,

Thanks for the plug-in! Question for you. I’m using postcss in a Webpack setup alongside CSS Modules. This requires css-loader be run after postcss and, in turn, means css-loader will fail because postcss-prefixwrap has added a wrapper class. This is an issue with CSS Modules… you can’t compose nested classes.

Do you know if there is a way around this problem?

Rule not wrapped when the first selector starts with the prefix

Hi,

I run into an issue when trying to wrap rules where the first selector starts with the prefix.

Example :

There are issue with rules starting with .test-4 (.test-4, .test-4, .test-5, .test-4, .other) selectors in the example below:

Trying to wrap the following with the prefix .te:

p {
    color: #ff0000;
}

.test-4 {
    color: #ff0000;
}

.test-4, .test-5 {
    color: #ff0000;
}

.test-4, .other {
    color: #ff0000;
}

h1.test-4, .test-5 {
    color: #ff0000;
}

.not-test-4 {
    color: #ff0000;
}

.other {
    color: #ff0000;
}

results in:

.te p {
    color: #ff0000;
}

.test-4 {
    color: #ff0000;
}

.test-4, .test-5 {
    color: #ff0000;
}

.test-4, .other {
    color: #ff0000;
}

.te h1.test-4, .te .test-5 {
    color: #ff0000;
}

.te .not-test-4 {
    color: #ff0000;
}

.te .other {
    color: #ff0000;
}

when the expected output would be:

.te p {
    color: #ff0000;
}

.te .test-4 {
    color: #ff0000;
}

.te .test-4, .te .test-5 {
    color: #ff0000;
}

.te .test-4, .te .other {
    color: #ff0000;
}

.te h1.test-4, .te .test-5 {
    color: #ff0000;
}

.te .not-test-4 {
    color: #ff0000;
}

.te .other {
    color: #ff0000;
}

Not necessarily a big issue as it is easy enough to change / add a letter to make it different, but it was enough to trip me up when trying to wrap blueprintjs's css with .bp (most rules starting with .bp3-). Examples extracted from my observations in that case.

Note: I can try to fix it sometime within the next week or so unless anyone does before.

PostCSS plugin postcss-prefixwrap requires PostCSS 8

I am getting this error whenever I run "npm run build:new". I tried a couple of fixes but none of them work for me. I have updated by react script to "^5.0.0", and then I am started to get this error. I tried to change the version of postcss-prefixwrap to the latest v1.28.1 but it didn't work. Please help me with this issue.

In an earlier ticket, the comment is posted that "postcss-prefixwrap" should work with postcss v8. but it does not work with that.

#140 (comment)

This is my package.json
{ "name": "components-web", "version": "0.1.0", "private": true, "dependencies": { "@babel/plugin-proposal-decorators": "^7.8.3", "@e-builder/react-components": "^1.0.41", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-regular-svg-icons": "^5.12.1", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/pro-light-svg-icons": "^5.12.1", "@fortawesome/pro-regular-svg-icons": "^5.12.1", "@fortawesome/pro-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "^0.1.8", "ajv": "^6.12.0", "antd": "^4.16.13", "apollo-boost": "^0.4.9", "aws-sdk": "^2.997.0", "axios": "^0.21.4", "bluebird": "^3.7.2", "cluster": "^0.7.7", "compression": "^1.7.1", "cookie-parser": "^1.4.3", "core-js": "^2.6.11", "cors": "^2.8.5", "crypto-js": "^3.3.0", "customize-cra": "^0.6.1", "evaporate": "^2.1.4", "express": "^4.16.2", "file-saver": "^1.3.8", "graphql": "^16.2.0", "helmet": "^3.21.3", "immutability-helper": "^3.0.1", "jquery": "^3.5.1", "mobx": "^4.15.4", "mobx-react": "^5.2.0", "moment": "^2.22.2", "morgan": "^1.9.0", "postcss": "^8.2.15", "postcss-prefixwrap": "^1.28.1", "primeicons": "^1.0.0", "primereact": "^3.4.0", "prop-types": "^15.6.1", "qrcode.react": "^0.9.3", "react": "^16.12.0", "react-apollo": "^2.1.9", "react-app-rewire-postcss": "^3.0.2", "react-app-rewired": "^2.1.5", "react-compound-timer": "^1.1.15", "react-dom": "^16.12.0", "react-resizable": "^3.0.4", "react-scripts": "^5.0.0", "react-test-renderer": "^16.12.0", "react-transition-group": "^2.9.0", "typescript": "^4.4.3", "validator": "^13.7.0" }, "devDependencies": { "eslint": "^7.32.0", "eslint-config-airbnb": "18.2.1", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^22.21.0", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-react": "^7.26.1", "source-map-explorer": "^2.3.1" }, "scripts": { "analyze": "source-map-explorer build/static/js/main.*", "start": "mkdir -p dist/static && node eb_app_config && npm run build && npm run build:new && node app", "start:test": "npm run test:nowatch && npm run start", "copy:global:new": "copy .\\dist\\global-functions.js > .\\dist\\components.new.js", "copy:media": "copy -r .\\build\\static\\media .\\dist\\static\\media", "build": "node set-build-bundle index-default.js && NODE_ENV='production' react-app-rewired build && npm run copy:build", "start:dev": "node set-build-bundle index-default.js && NODE_ENV='development' react-app-rewired start", "copy:js:new": "copy .\\build\\static\\js\\main*.js >> .\\dist\\components.new.js", "copy:css:new": "copy .\\build\\static\\css\\main*.css .\\dist\\components.new.css", "copy:build:new": "npm run copy:global:new && npm run copy:js:new && npm run copy:css:new ", "build:new": "node set-build-bundle index-new-ux.js && NODE_ENV='production' react-app-rewired build && npm run copy:build:new", "start:dev:new": "node set-build-bundle index-new-ux.js && NODE_ENV='development' react-app-rewired start", "test": "react-app-rewired test --env=jsdom", "test:nowatch": "node eb_app_config && CI=true react-app-rewired test --env=jsdom", "eject": "react-app-rewired eject", "test:lint": "eslint . --ext .js" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "babel": { "env": { "test": { "plugins": [ [ "@babel/plugin-proposal-decorators", { "legacy": true } ] ] } } } }

Selectors containing the word "body" or "html" treated as root

With the default configuration some selectors that contain "body" end up getting treated as the root body/html tag. So, for example, with a prefix of .my-custom-wrap, something like:

tbody {
  border: 10px solid red;
}

Will get turned into:

.my-custom-wrap {
  border: 10px solid red;
}

Whereas, this should become:

.my-custom-wrap tbody {
  border: 10px solid red;
}

This appears to be getting tripped up by the prefixRootTags regex, since that's matching any selector that contains either body or html anywhere in the selector. As another example, the class name .foobar-body or .foobar-html will also gets caught by the same issue.

I was able to solve this by turning on the prefixRootTags option, since in my case, I didn't necessarily need this logic to extract the body or html selector styles. But I think the issue might be that the regex is too aggressive. I haven't tested this, but maybe something more like /(^|[\s,]*)(body|html)([\s,]*|$)/ might help (that attempts to only match body or html surrounded by spaces, commas, or the beginning/end of line, but I'm not entirely sure about all the possible combinations).

Anyway, just thought I'd mention this and the potential workaround (if you don't need to extract those styles), but thanks for the plugin!

postcss.plugins was deprecated

PostCSS had moved to version 8.0 recently and therefore using postcss-prefixwrap shows the following message:

postcss.plugin was deprecated. Migration guide:
https://evilmartians.com/chronicles/postcss-8-plugin-migration

This is an issue for tests which fail whenever any non PASS message appears at the summary, what in turn creates confusion in Jenkins having test suite fail while all the tests are green.

Error: PostCSS plugin postcss-prefixwrap requires PostCSS 8.

I am getting this error whenever I run npm start. I tried a couple of fixes but none of them work for me. I tried to change the version of postcss-prefixwrap to 1.26.0 but it didn't work. Please help me with this issue. I have updated by react script to "^5.0.0", and then I am started to get this error.

This is my package.json

{ "name": "components-web", "version": "0.1.0", "private": true, "dependencies": { "@babel/plugin-proposal-decorators": "^7.8.3", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-regular-svg-icons": "^5.12.1", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/pro-light-svg-icons": "^5.12.1", "@fortawesome/pro-regular-svg-icons": "^5.12.1", "@fortawesome/pro-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "^0.1.8", "ajv": "^6.12.0", "antd": "^4.16.13", "apollo-boost": "^0.4.9", "aws-sdk": "^2.997.0", "axios": "^0.21.4", "bluebird": "^3.7.2", "cluster": "^0.7.7", "compression": "^1.7.1", "cookie-parser": "^1.4.3", "core-js": "^2.6.11", "cors": "^2.8.5", "crypto-js": "^3.3.0", "customize-cra": "^0.6.1", "evaporate": "^2.1.4", "express": "^4.16.2", "file-saver": "^1.3.8", "graphql": "^16.2.0", "helmet": "^3.21.3", "immutability-helper": "^3.0.1", "jquery": "^3.5.1", "mobx": "^4.15.4", "mobx-react": "^5.2.0", "moment": "^2.22.2", "morgan": "^1.9.0", "postcss": "^8.4.5", "postcss-cli": "^9.1.0", "postcss-loader": "^4.1.0", "postcss-prefixwrap": "^1.26.0", "primeicons": "^1.0.0", "primereact": "^3.4.0", "prop-types": "^15.6.1", "qrcode.react": "^0.9.3", "react": "^16.12.0", "react-apollo": "^2.1.9", "react-app-rewire-postcss": "^3.0.2", "react-app-rewired": "^2.1.5", "react-compound-timer": "^1.1.15", "react-dom": "^16.12.0", "react-resizable": "^3.0.4", "react-scripts": "^5.0.0", "react-test-renderer": "^16.12.0", "react-transition-group": "^2.9.0", "typescript": "^4.4.3", "validator": "^13.7.0" }, "devDependencies": { "eslint": "^7.32.0", "eslint-config-airbnb": "18.2.1", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^22.21.0", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-react": "^7.26.1", "source-map-explorer": "^2.3.1" }, "peerDependencies": { "postcss": "^8.4.5" }, "scripts": { "analyze": "source-map-explorer build/static/js/main.*", "start": "mkdir -p dist/static && node eb_app_config && npm run build:new && node app", "start:test": "npm run test:nowatch && npm run start", "copy:js:new": "copy .\\build\\static\\js\\main*.js >> .\\dist\\components.new.js", "copy:css:new": "copy .\\build\\static\\css\\main*.css .\\dist\\components.new.css", "copy:build:new": "npm run copy:global:new && npm run copy:js:new && npm run copy:css:new ", "copy:global:new": "copy .\\dist\\global-functions.js > .\\dist\\components.new.js", "copy:media": "copy -r .\\build\\static\\media .\\dist\\static\\media", "build:new": "node set-build-bundle index-new-ux.js && NODE_ENV='production' react-app-rewired build && npm run copy:build:new", "start:dev:new": "node set-build-bundle index-new-ux.js && NODE_ENV='development' DISABLE_ESLINT_PLUGIN=true react-app-rewired start", "test": "react-app-rewired test --env=jsdom", "test:nowatch": "node eb_app_config && CI=true react-app-rewired test --env=jsdom", "eject": "react-app-rewired eject", "test:lint": "eslint . --ext .js" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "babel": { "env": { "test": { "plugins": [ [ "@babel/plugin-proposal-decorators", { "legacy": true } ] ] } } } }

Option to disable replacing of html and body with wrapper prefix

Hello. I've tried to use this plugin to add prefix to some css frameworks to use them inside specific container. However when it replaces html and body with wrapper it cause unnecessary styles that applied to container (e.g. min-width, overflows and so on) that breaks container.

html {
  background-color: #fff;
  font-size: 16px;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  min-width: 300px;
  overflow-x: hidden;
  overflow-y: scroll;
  text-rendering: optimizeLegibility;
}

became

.mywrapper {
  background-color: #fff;
  font-size: 16px;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  min-width: 300px;
  overflow-x: hidden;
  overflow-y: scroll;
  text-rendering: optimizeLegibility;
}

Is there any option to avoid this (possibly skip such replacement)?

Using "/" path separator in "whitelist", "blacklist" config doesn't work in windows env

Internally the "patterns" provided via whitelist, blacklist options are "Regex matched" against the current CSS file's "path" during post-css execution.

Check code here -> https://github.com/dbtedman/postcss-prefixwrap/blob/main/src/PostCSSPrefixWrap.ts#L113

The docs doesn't mention this explicitly. Instead it just specifies "File" whitelist & "File" blacklist.
image

Users may think that they can provide file paths in these configs and later suffer when running same projects in different env (windows), due to different path separator patterns.

--

Explicitly mentioning that the whitelist, blacklist options are actually Rx patterns, will help users avoid these platform issues.

Support for multiline selectors

Example

.a,
.b,
.c {color: red}

Output:

.wrapper .a,
.b,
.c {color: red}

So wrapper applied only to .a class, but not .b and .c.

[Feature request] Add support for compound selector

Request

Add option appendCompoundSelector that generates 2 selectors: PREFIX .container, PREFIX.container. This will allow the style rules to start applying from the prefix level, removing the need to have extra divs.

Basically:

    // Anything other than a root tag is always prefixed.
    if (isNotRootTag(cleanedSelector)) {
        let result = prefixSelector + " " + cleanedSelector;
        if (appendCompoundSelector) {
            result += `, ${prefixSelector}${cleanedSelector}`;
        }
        return result;
    }

Use case

I have 3 levels of styles:

  • WP site
  • App (WP plugin) - eof
  • Component library - eac

The apps need to use a css prefix to overwrite site styles, but unfortunately the component library also needs a css prefix, otherwise import will fail

`@apply` cannot be used with .font-light because .font-light is included in multiple rulesets. 

This causes cascade problems between Tailwind utility classes and generic styles when dealing with slotted content (EX ".eof .eac menu" > ".eof .mx-9"). Using .eac *:not(.ssc) prefix stops the styles from cascading (ssc - stop style cascade):

/** @type {import('postcss-load-config').Config} */
const config = {
    plugins: [
        require("postcss-import"),
        require("tailwindcss"),
        require("postcss-nested"),
        require("autoprefixer"),
        require("postcss-prefixwrap")('.eac *:not(.ssc)', {
            ignoredSelectors: ["body" , /^body.(.+)/],
        })
   ]
}

But it requires an extra div before the styles start applying, making the html structure cumbersome:

<template>
    <div show.bind="isVisible" class="ssc eac">
    <div>
    <div class="tooltip-container">
        <div class="e4-tooltip ${minWidth === 'wide' ? 'e4-tooltip-wide' : ''} e4-tooltip-${position}" ref="elem">
            <div class="e4-tooltip-arrow" ref="tooltipArrow"></div>
            <div class="overflow-hidden overflow-y-auto py-2 px-4 text-xs leading-snug text-center">
                <div class="ssc ${appStylePrefix}">
                <div>
                    <slot></slot>
                </div>
                </div>
            </div>
        </div>
    </div>
    </div>
    </div>
</template>

keyframes

This plugin is wrapping also the animation made with keyframes and it is breaking it

Example output CSS

@keyframes pulse {
  .my-custom-wrap 0% {
    opacity: 1;
    -webkit-transform: scale(1);
            transform: scale(1); }
  .my-custom-wrap 80% {
    opacity: 0;
    -webkit-transform: scale(2);
            transform: scale(2); }
  .my-custom-wrap 100% {
    opacity: 0;
    -webkit-transform: scale(3);
            transform: scale(3); } }

Issues with combination of postcss-nested

If postcss-prefixwrap is used with latest 5.x version of postcss-nested library the end output is wrong.

Instead of wrap class being applied just once it gets applied multiple times. Based on times how many "nested" lvls are used in source file.

Example:
source:

.demo {
   &--lite {
       color:red;
   }
}

Before upgrade to 5.x result:
.root .demo--lite {color:red}

After upgrade to 5.x result:
.root .root .demo--lite {color:red}

postcss-nested plugin maintainers are saying that this is issue because plugin is not using PostCSS 8 plugin Api.

Version 1.35.0 not working

Hi,

When i use latest version, got below error.
And return to 1.34.0,back to normal.

postcss.config.js

module.exports = {
    plugins: [
        require("autoprefixer"), 
        require("postcss-prefixwrap")('.test'),
    ],
}
Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
Error: Cannot find module 'plugin/PostCSSPrefixWrap'
Require stack:
- /Users/.../node_modules/postcss-prefixwrap/build/plugin/PostCSS8Plugin.js
- /Users/.../node_modules/postcss-prefixwrap/build/plugin/PostCSSPlugin.js
- /Users/.../node_modules/postcss-prefixwrap/build/index.js
- /Users/.../postcss.config.js
- /Users/.../node_modules/cosmiconfig/dist/loaders.js
- /Users/.../node_modules/cosmiconfig/dist/ExplorerBase.js

Integration Test Rethink

Our current integration testing strategy was unable to catch a recent import path bug. To avoid this in future, a rethought approach is necessary.

We need to isolate ourselves from our build tooling, operating on the build output (plugin source) directly.

Can't install without peer dependency errors

Hello and thanks for this great plugin

yarn add postcss@^8
yarn add postcss-prefixwrap --dev --exact

Results in an error

[email protected]" has incorrect peer dependency "postcss@7.*.*|^8.1.0".

I'm not experienced with postCSS at all but though trial and error installed [email protected] has the

"peerDependencies": {
    "postcss": "*"
  },

This works for my use-case but I suspect the "or" in the dependency may be off.

I'm using yarn 1.22.10

Cannot compile with `tsc` (was: "1.34.0 -> 1.35.1 broke the types")

In 1.34.0, the plugin is properly being typed as PostCSSAcceptedPlugin, but in 1.35.1, it's any.

It seems that build/index.d.ts is trying to import the types from the wrong place? 🤔

declare const _default: import("./Types").PostCSS8Plugin | import("./Types").PostCSS7Plugin;

Why add every className?

When using less, how can I set it to be added only for the outermost className?
local stytle
image

build style
image

This way the microHeader style does not work~

Add ability to replace the :root pseudo-class directly or through generic addition

Hi @dbtedman,

Thanks for this plugin as it seems to be working well overall, however, I am just noticing that it will not work for css with the :root pseudo-class. Looking at the purpose of this plugin, it seems that this should also be replaced upon processing.

It seems in this case, the easiest solution to this problem would be to modify 'IS_ROOT_TAG' inside Selector.ts to be

const IS_ROOT_TAG = /^(body|html|:root).*$/;

or alternatively, to perhaps create an option for more generic usage while allowing this to be 'opt in' and more backwards compatible. Perhaps, for example, and 'additionalRootTags' array option could be passed in and used to costruct a dynamically built root tag regex here.

What are your thoughts on this?

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.