├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package.json └── test ├── fixtures ├── attribute-id.css ├── attribute-id.expected.css ├── classes.css ├── classes.expected.css ├── ids-no-override-option.css ├── ids-no-override-option.expected.css ├── ids.css ├── ids.expected.css ├── keyframes.css ├── keyframes.expected.css ├── multiple-classes.css ├── multiple-classes.expected.css ├── no-mangle-important-decl-in-id.css ├── no-mangle-important-decl-in-id.expected.css ├── repeat-option.css ├── repeat-option.expected.css ├── root-level-selectors.css ├── root-level-selectors.expected.css ├── selection-pseudo.css ├── selection-pseudo.expected.css ├── stackable-root-selector.css ├── stackable-root-selector.expected.css ├── stackable-root.css └── stackable-root.expected.css └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | .history/ 4 | .vscode/ 5 | todo.md 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | 3 | node_modules/ 4 | 5 | test/ 6 | .travis.yml 7 | 8 | 9 | todo.md -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - iojs 5 | - "0.12" 6 | - "0.10" 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v0.6.0 - 2017-10-9 2 | 3 | - Avoid mangling rules inside `@keyframes` 4 | - Thanks to [@IvanKalinin](https://github.com/IvanKalinin) for the contribution [#14](https://github.com/MadLittleMods/postcss-increase-specificity/pull/14) 5 | 6 | 7 | # v0.5.0 - 2017-5-26 8 | 9 | - Switch `options.stackableRoot` from `:not(#\20)` to `:not(#\9)` to save some bytes 10 | - Thanks to [@valtlai](https://github.com/valtlai) for the contribution [#12](https://github.com/MadLittleMods/postcss-increase-specificity/pull/12) 11 | 12 | 13 | # v0.4.0 - 2017-5-18 14 | 15 | - Switch `options.stackableRoot` from `:root` to `:not(#\20)` to get more specificity in selectors 16 | - Thanks to [@subzey](https://github.com/subzey) for the [idea](https://twitter.com/subzey/status/829050478721896448) and [@iamstarkov](https://github.com/iamstarkov) for the contribution [#9](https://github.com/MadLittleMods/postcss-increase-specificity/pull/9) 17 | 18 | 19 | # v0.3.0 - 2016-9-9 20 | 21 | - Update to postcss@5.x 22 | - Thanks to [@laucheukhim](https://github.com/laucheukhim) for the contribution [#5](https://github.com/MadLittleMods/postcss-increase-specificity/pull/5) 23 | 24 | 25 | # v0.2.2 - 2015-8-1 26 | 27 | - Add `options.stackableRoot` to customize the stackable selector used. Defaults to `:root` 28 | - Add [`postcss-plugin-context`](https://github.com/postcss/postcss-plugin-context) example. Only apply plugin to certain areas of the CSS. 29 | - Add note about the default `:root` not supported in IE8- 30 | 31 | 32 | # v0.2.1 - 2015-7-31 33 | 34 | - Switch to [`string.prototype.repeat`](https://www.npmjs.com/package/string.prototype.repeat) and [`object-assign`](https://www.npmjs.com/package/object-assign) 35 | - Use the PostCSS `decl.important` property instead of value finagling 36 | 37 | 38 | # v0.2.0 - 2015-7-30 39 | 40 | - Use [`repeat-string`](https://www.npmjs.com/package/repeat-string) instead of `String.prototype.repeat` which doesn't work in node.js 41 | 42 | 43 | # v0.1.2 - 2015-7-30 44 | 45 | - Add tests 46 | - npm release 47 | - Add badges to readme 48 | 49 | 50 | # v0.1.0 - 2015-7-30 51 | 52 | - First release 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eric Eastwood 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm version](https://badge.fury.io/js/postcss-increase-specificity.svg)](http://badge.fury.io/js/postcss-increase-specificity) [![Build Status](https://travis-ci.org/MadLittleMods/postcss-increase-specificity.svg)](https://travis-ci.org/MadLittleMods/postcss-increase-specificity) 2 | 3 | # PostCSS Increase Specificity 4 | 5 | [PostCSS](https://github.com/postcss/postcss) plugin to increase the specificity of your selectors. 6 | 7 | [Why?](#why-my-use-case) Dealing with CSS you can't remove(mainly from a 3rd party), [see the why section](#why-my-use-case). 8 | 9 | ### [Changelog](https://github.com/MadLittleMods/postcss-increase-specificity/blob/master/CHANGELOG.md) 10 | 11 | ### Install 12 | 13 | `npm install postcss-increase-specificity --save-dev` 14 | 15 | # Usage 16 | 17 | ## Basic Example 18 | 19 | ```js 20 | var postcss = require('postcss'); 21 | var increaseSpecificity = require('postcss-increase-specificity'); 22 | 23 | var fs = require('fs'); 24 | 25 | var mycss = fs.readFileSync('input.css', 'utf8'); 26 | 27 | // Process your CSS with postcss-increase-specificity 28 | var output = postcss([ 29 | increaseSpecificity(/*options*/) 30 | ]) 31 | .process(mycss) 32 | .css; 33 | 34 | console.log(output); 35 | ``` 36 | 37 | 38 | ## Results 39 | 40 | Input: 41 | 42 | ```css 43 | html { 44 | background: #485674; 45 | height: 100%; 46 | } 47 | 48 | .blocks { 49 | background: #34405B; 50 | } 51 | 52 | #main-nav { 53 | color: #ffffff; 54 | } 55 | 56 | [id="main-nav"] { 57 | border: 1px solid #ffffff; 58 | } 59 | 60 | .foo, 61 | .bar { 62 | display: inline-block; 63 | width: 50%; 64 | } 65 | 66 | ``` 67 | 68 | Output (result): 69 | 70 | ```css 71 | html:not(#\9):not(#\9):not(#\9) { 72 | background: #485674; 73 | height: 100%; 74 | } 75 | 76 | :not(#\9):not(#\9):not(#\9) .blocks { 77 | background: #34405B; 78 | } 79 | 80 | :not(#\9):not(#\9):not(#\9) #main-nav { 81 | color: #ffffff !important; 82 | } 83 | 84 | :not(#\9):not(#\9):not(#\9) [id="main-nav"] { 85 | border: 1px solid #ffffff !important; 86 | } 87 | 88 | :not(#\9):not(#\9):not(#\9) .foo, 89 | :not(#\9):not(#\9):not(#\9) .bar { 90 | display: inline-block; 91 | width: 50%; 92 | } 93 | 94 | ``` 95 | 96 | 97 | ## Only apply to certain sections of styles 98 | 99 | [`postcss-plugin-context`](https://github.com/postcss/postcss-plugin-context) allows you to apply plugins to only in certain areas of of your CSS. 100 | 101 | 102 | ```js 103 | var postcss = require('postcss'); 104 | var context = require('postcss-plugin-context'); 105 | var increaseSpecificity = require('postcss-increase-specificity'); 106 | 107 | var fs = require('fs'); 108 | 109 | var mycss = fs.readFileSync('input.css', 'utf8'); 110 | 111 | // Process your CSS with postcss-increase-specificity 112 | var output = postcss([ 113 | context({ 114 | increaseSpecificity: increaseSpecificity(/*options*/) 115 | }) 116 | ]) 117 | .process(mycss) 118 | .css; 119 | 120 | console.log(output); 121 | ``` 122 | 123 | Input: 124 | 125 | ```css 126 | /* these styles will be left alone */ 127 | html { 128 | background: #485674; 129 | height: 100%; 130 | } 131 | 132 | p { 133 | display: inline-block; 134 | width: 50%; 135 | } 136 | 137 | 138 | /* these styles will have the hacks prepended */ 139 | @context increaseSpecifity { 140 | #main-nav { 141 | color: #ffffff; 142 | } 143 | 144 | .blocks { 145 | background: #34405b; 146 | } 147 | 148 | .baz, 149 | .qux { 150 | display: inline-block; 151 | width: 50%; 152 | } 153 | } 154 | ``` 155 | 156 | 157 | # Why? *(my use case)* 158 | 159 | I had to use a 3rd party form-creation/data-aggregation service required by the client. The form is embedded in the website, via script tag, which unrolls an iframe with the form. The goal was to make the form match the rest of the site. 160 | 161 | The 3rd party form creation service *did* have an option for custom CSS, but you had to work around their existing layout and theme styles. Unfortunately, there was no blank(unstyled) theme to start from and you could not add any of your own selectors. Another problem was that they used really specific selectors and also some `!important` declarations. 162 | 163 | This meant I had to make my own selectors have a lot more specificity in order for my styles to have any effect. I wanted to write relatively clean CSS and still be able to overcome their styles automagically, so I created this plugin, `postcss-increase-specificity`. 164 | 165 | 166 | # What it does? *(by default)* 167 | 168 | - Prepend a descendant selector piece: `:not(#\9)` repeated the specified, `options.repeat`, number of times. 169 | - Add `!important` declarations to any selectors that have to do with an id. 170 | 171 | 172 | 173 | # Options 174 | 175 | - `repeat`: number - The number of times we prepend `options.stackableRoot` in front of your selector 176 | - Default: `3` 177 | - `overrideIds`: bool - Whether we should add `!important` to all declarations that use id's in any way. Because id's are so specific, the only way(essentially) to overcome another id is to use `!important`. 178 | - Default: `true` 179 | - `stackableRoot`: string - Selector that is repeated to make up the piece that is added to increase specificity 180 | - Default: `:not(#\9)` 181 | - *Warning:* The default `:not(#\9)` pseudo-class selector is not supported in IE8-. To support IE-, you can change this option to a class such as `.my-root` and add it to the `` tag in your markup. 182 | 183 | 184 | # Tests 185 | 186 | We have a suite of Mocha tests. 187 | 188 | `npm test` 189 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // postcss-increase-specificity v0.2.2 2 | 3 | var postcss = require('postcss'); 4 | var objectAssign = require('object-assign'); 5 | var escapeStringRegexp = require('escape-string-regexp'); 6 | require('string.prototype.repeat'); 7 | 8 | var CSS_ESCAPED_TAB = '\\9'; 9 | 10 | 11 | function increaseSpecifityOfRule(rule, opts) { 12 | rule.selectors = rule.selectors.map(function(selector) { 13 | // Apply it to the selector itself if the selector is a `root` level component 14 | // `html:not(#\\9):not(#\\9):not(#\\9)` 15 | if( 16 | selector === 'html' || 17 | selector === ':root' || 18 | selector === ':host' || 19 | selector === opts.stackableRoot 20 | ) { 21 | return selector + opts.stackableRoot.repeat(opts.repeat); 22 | } 23 | 24 | // Otherwise just make it a descendant (this is what will happen most of the time) 25 | // `:not(#\\9):not(#\\9):not(#\\9) .foo` 26 | return opts.stackableRoot.repeat(opts.repeat) + ' ' + selector; 27 | }); 28 | 29 | if(opts.overrideIds) { 30 | if( 31 | // If an id is in there somewhere 32 | (new RegExp('#(?!' + escapeStringRegexp(CSS_ESCAPED_TAB) + ')')).test(rule.selector) || 33 | // Or it is an attribute selector with an id 34 | (/\[id/).test(rule.selector) 35 | ) { 36 | rule.walkDecls(function(decl) { 37 | decl.important = true; 38 | }); 39 | } 40 | } 41 | } 42 | 43 | 44 | // Plugin that adds `:not(#\\9)` selectors to the front of the rule thus increasing specificity 45 | module.exports = postcss.plugin('postcss-increase-specificity', function(options) { 46 | var defaults = { 47 | // The number of times `:not(#\\9)` is appended in front of the selector 48 | repeat: 3, 49 | // Whether to add !important to declarations in rules with id selectors 50 | overrideIds: true, 51 | // The thing we repeat over and over to make up the piece that increases specificity 52 | stackableRoot: ':not(#' + CSS_ESCAPED_TAB + ')' 53 | }; 54 | 55 | var opts = objectAssign({}, defaults, options); 56 | 57 | return function(css) { 58 | css.walkRules(function(rule) { 59 | // Avoid adding additional selectors (stackableRoot) to descendant rules of @keyframe {} 60 | // i.e. `from`, `to`, or `{number}%` 61 | var isInsideKeyframes = rule.parent.type === 'atrule' && rule.parent.name === 'keyframes'; 62 | 63 | if(!isInsideKeyframes) { 64 | increaseSpecifityOfRule(rule, opts); 65 | } 66 | }); 67 | }; 68 | }); 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-increase-specificity", 3 | "version": "0.6.0", 4 | "description": "PostCSS plugin to increase the specificity of your selectors", 5 | "keywords": [ 6 | "postcss", 7 | "css", 8 | "postcss-plugin", 9 | "specificity" 10 | ], 11 | "author": "Eric Eastwood (http://ericeastwood.com/)", 12 | "license": "MIT", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/MadLittleMods/postcss-increase-specificity.git" 16 | }, 17 | "main": "index.js", 18 | "scripts": { 19 | "test": "mocha", 20 | "mocha": "mocha" 21 | }, 22 | "dependencies": { 23 | "escape-string-regexp": "^1.0.5", 24 | "object-assign": "^3.0.0", 25 | "postcss": "^5.1.2", 26 | "string.prototype.repeat": "^0.2.0" 27 | }, 28 | "devDependencies": { 29 | "bluebird": "^2.9.34", 30 | "chai": "^3.2.0", 31 | "chai-as-promised": "^5.1.0", 32 | "clean-css": "^3.3.7", 33 | "mocha": "^2.2.5" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/fixtures/attribute-id.css: -------------------------------------------------------------------------------- 1 | [id="foo"] { 2 | background: #f00; 3 | } 4 | 5 | [id^="bar"] { 6 | background: #0f0; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/attribute-id.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) [id="foo"] { 2 | background: #f00 !important; 3 | } 4 | 5 | :not(#\9):not(#\9):not(#\9) [id^="bar"] { 6 | background: #0f0 !important; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/classes.css: -------------------------------------------------------------------------------- 1 | .foo { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/classes.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) .foo { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/ids-no-override-option.css: -------------------------------------------------------------------------------- 1 | #foo { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/ids-no-override-option.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) #foo { 2 | background: #f00; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/ids.css: -------------------------------------------------------------------------------- 1 | #foo { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/ids.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) #foo { 2 | background: #f00 !important; 3 | } -------------------------------------------------------------------------------- /test/fixtures/keyframes.css: -------------------------------------------------------------------------------- 1 | @keyframes custom-animation { 2 | from { opacity: 0; } 3 | 50% { opacity: 0.5; } 4 | 60%, 70% {opacity: 0.7; } 5 | to { opacity: 1; } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/keyframes.expected.css: -------------------------------------------------------------------------------- 1 | @keyframes custom-animation { 2 | from { opacity: 0; } 3 | 50% { opacity: 0.5; } 4 | 60%, 70% {opacity: 0.7; } 5 | to { opacity: 1; } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/multiple-classes.css: -------------------------------------------------------------------------------- 1 | .foo, .bar { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/multiple-classes.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) .foo, :not(#\9):not(#\9):not(#\9) .bar { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/no-mangle-important-decl-in-id.css: -------------------------------------------------------------------------------- 1 | #foo { 2 | background: #f00 !important; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/no-mangle-important-decl-in-id.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) #foo { 2 | background: #f00 !important; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/repeat-option.css: -------------------------------------------------------------------------------- 1 | html { 2 | background: #fff; 3 | } 4 | 5 | .foo { 6 | background: #f00; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/repeat-option.expected.css: -------------------------------------------------------------------------------- 1 | html:not(#\9):not(#\9):not(#\9):not(#\9):not(#\9) { 2 | background: #fff; 3 | } 4 | 5 | :not(#\9):not(#\9):not(#\9):not(#\9):not(#\9) .foo { 6 | background: #f00; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/root-level-selectors.css: -------------------------------------------------------------------------------- 1 | html { 2 | background: #f00; 3 | } 4 | 5 | :not(#\9) { 6 | background: #0f0; 7 | } 8 | 9 | :host { 10 | background: #0f0; 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/root-level-selectors.expected.css: -------------------------------------------------------------------------------- 1 | html:not(#\9):not(#\9):not(#\9) { 2 | background: #f00; 3 | } 4 | 5 | :not(#\9):not(#\9):not(#\9):not(#\9) { 6 | background: #0f0; 7 | } 8 | 9 | :host:not(#\9):not(#\9):not(#\9) { 10 | background: #0f0; 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/selection-pseudo.css: -------------------------------------------------------------------------------- 1 | ::selection { 2 | background-color: #fcf1ab; color: #000; 3 | } 4 | ::-moz-selection { 5 | background-color: #fcf1ab; color: #000; 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/selection-pseudo.expected.css: -------------------------------------------------------------------------------- 1 | :not(#\9):not(#\9):not(#\9) ::selection { 2 | background-color: #fcf1ab; color: #000; 3 | } 4 | :not(#\9):not(#\9):not(#\9) ::-moz-selection { 5 | background-color: #fcf1ab; color: #000; 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/stackable-root-selector.css: -------------------------------------------------------------------------------- 1 | .my-root { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/stackable-root-selector.expected.css: -------------------------------------------------------------------------------- 1 | .my-root.my-root.my-root.my-root { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/stackable-root.css: -------------------------------------------------------------------------------- 1 | .foo { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/fixtures/stackable-root.expected.css: -------------------------------------------------------------------------------- 1 | .my-root.my-root.my-root .foo { 2 | background: #f00; 3 | } -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai'); 2 | var expect = chai.expect; 3 | var chaiAsPromised = require('chai-as-promised'); 4 | chai.use(chaiAsPromised); 5 | 6 | var postcss = require('postcss'); 7 | var increaseSpecifity = require('../'); 8 | 9 | var Promise = require('bluebird'); 10 | var fs = Promise.promisifyAll(require('fs')); 11 | var CleanCSS = require('clean-css'); 12 | 13 | 14 | 15 | function testPlugin(filePath, expectedFilePath, options) { 16 | options = options || {}; 17 | 18 | return fs.readFileAsync(filePath) 19 | .then(function(buffer) { 20 | var contents = String(buffer); 21 | var actual = postcss([ 22 | increaseSpecifity(options) 23 | ]) 24 | .process(contents); 25 | 26 | return actual.css; 27 | }) 28 | .then(function(actual) { 29 | return fs.readFileAsync(expectedFilePath) 30 | .then(function(buffer) { 31 | var contents = String(buffer); 32 | 33 | var cleanCss = new CleanCSS({ 34 | advanced: false, 35 | aggressiveMerging: false, 36 | mediaMerging: false, 37 | restructuring: false, 38 | shorthandCompacting: false, 39 | //keepBreaks: true, 40 | compatibility: '-properties.merging' 41 | }); 42 | 43 | expect(cleanCss.minify(actual).styles).to.equal(cleanCss.minify(contents).styles); 44 | //expect(actual).to.equal(contents); 45 | }); 46 | }); 47 | } 48 | 49 | 50 | describe('postcss-increase-specificity', function() { 51 | it('should work with classes `.foo`', function() { 52 | return testPlugin('./test/fixtures/classes.css', './test/fixtures/classes.expected.css'); 53 | }); 54 | 55 | it('should work with multiple classes `.foo, .bar`', function() { 56 | return testPlugin('./test/fixtures/multiple-classes.css', './test/fixtures/multiple-classes.expected.css'); 57 | }); 58 | 59 | it('should work with ids `#foo`', function() { 60 | return testPlugin('./test/fixtures/ids.css', './test/fixtures/ids.expected.css'); 61 | }); 62 | 63 | it('should work with attribute selectors with id `[id=foo]`', function() { 64 | return testPlugin('./test/fixtures/attribute-id.css', './test/fixtures/attribute-id.expected.css'); 65 | }); 66 | 67 | it('should work with root level selectors `html, :not(#\\9), :host`', function() { 68 | return testPlugin('./test/fixtures/root-level-selectors.css', './test/fixtures/root-level-selectors.expected.css'); 69 | }); 70 | 71 | it('should work with `::selection`', function() { 72 | return testPlugin('./test/fixtures/selection-pseudo.css', './test/fixtures/selection-pseudo.expected.css'); 73 | }); 74 | 75 | it('should not mangle a decl that already has an `!important` on it', function() { 76 | return testPlugin('./test/fixtures/no-mangle-important-decl-in-id.css', './test/fixtures/no-mangle-important-decl-in-id.expected.css'); 77 | }); 78 | 79 | it('should repeat `:not(#\\9)` appropriately `options.repeat', function() { 80 | return testPlugin( 81 | './test/fixtures/repeat-option.css', 82 | './test/fixtures/repeat-option.expected.css', 83 | { 84 | repeat: 5 85 | } 86 | ); 87 | }); 88 | 89 | it('should not add `!important` when `options.overrideIds = false`', function() { 90 | return testPlugin( 91 | './test/fixtures/ids-no-override-option.css', 92 | './test/fixtures/ids-no-override-option.expected.css', 93 | { 94 | overrideIds: false 95 | } 96 | ); 97 | }); 98 | 99 | it('should use stackableRoot `options.stackableRoot`', function() { 100 | return testPlugin( 101 | './test/fixtures/stackable-root.css', 102 | './test/fixtures/stackable-root.expected.css', 103 | { 104 | stackableRoot: '.my-root' 105 | } 106 | ); 107 | }); 108 | 109 | it('should consider a selector that uses a `options.stackableRoot` a root', function() { 110 | return testPlugin( 111 | './test/fixtures/stackable-root.css', 112 | './test/fixtures/stackable-root.expected.css', 113 | { 114 | stackableRoot: '.my-root' 115 | } 116 | ); 117 | }); 118 | 119 | it('should not change the descendant rules of @keyframes', function() { 120 | return testPlugin('./test/fixtures/keyframes.css', './test/fixtures/keyframes.expected.css'); 121 | }); 122 | }); 123 | --------------------------------------------------------------------------------