css-blank-pseudo
Advanced tools
Comparing version 3.0.3 to 4.0.0
# Changes to CSS Blank Pseudo | ||
### 4.0.0 (July 8, 2022) | ||
- Updated: The polyfill now only attaches a single listener to the body so it's | ||
more efficient and also does less work at the MutationObserver handler. | ||
- Breaking: removed old CDN urls | ||
- Breaking: removed old CLI | ||
- Fix case insensitive matching. | ||
#### How to migrate: | ||
- If you use a CDN url, please update it. | ||
- Re-build your CSS with the new version of the library. | ||
```diff | ||
- <script src="https://unpkg.com/css-blank-pseudo/browser"></script> | ||
- <script src="https://unpkg.com/css-blank-pseudo/browser.min"></script> | ||
+ <script src="https://unpkg.com/css-blank-pseudo/dist/browser-global.js"></script> | ||
``` | ||
```diff | ||
- cssBlankPseudo(document) | ||
+ cssBlankPseudoInit() | ||
``` | ||
```diff | ||
- cssBlankPseudo({ | ||
- attr: false, | ||
- className: 'blank' | ||
- }) | ||
+ cssBlankPseudoInit({ | ||
+ replaceWith: '.blank' | ||
+ }) | ||
``` | ||
### 3.0.3 (February 5, 2022) | ||
@@ -4,0 +38,0 @@ |
@@ -1,2 +0,2 @@ | ||
self.cssBlankPseudo=function(e,t){var n=Object(t).className,r=Object(t).attr||"blank",o=Object(t).force;try{if(e.querySelector(":blank"),!o)return}catch(e){}var a,i,s,c=(e.ownerDocument||e).defaultView;d(c.HTMLInputElement),d(c.HTMLSelectElement),d(c.HTMLTextAreaElement),a=c.HTMLOptionElement,i=Object.getOwnPropertyDescriptor(a.prototype,"selected"),s=i.set,i.set=function(t){s.apply(this,arguments);var n=e.createEvent("Event");n.initEvent("change",!0,!0),this.dispatchEvent(n)},Object.defineProperty(a.prototype,"selected",i);var l=/^(INPUT|SELECT|TEXTAREA)$/;function p(){this.value||"SELECT"===this.nodeName&&this.options[this.selectedIndex].value?(r&&this.removeAttribute(r),n&&this.classList.remove(n),this.removeAttribute("blank")):(r&&this.setAttribute("blank",r),n&&this.classList.add(n))}function d(e){var t=Object.getOwnPropertyDescriptor(e.prototype,"value"),n=t.set;t.set=function(e){n.apply(this,arguments),p.apply(this)},Object.defineProperty(e.prototype,"value",t)}Array.prototype.forEach.call(e.querySelectorAll("INPUT,SELECT,TEXTAREA"),(function(e){"SELECT"===e.nodeName?e.addEventListener("change",p):e.addEventListener("input",p),p.call(e)})),new MutationObserver((function(e){e.forEach((function(e){Array.prototype.forEach.call(e.addedNodes||[],(function(e){1===e.nodeType&&l.test(e.nodeName)&&("SELECT"===e.nodeName?e.addEventListener("change",p):e.addEventListener("input",p),p.call(e))})),Array.prototype.forEach.call(e.removedNodes||[],(function(e){1===e.nodeType&&l.test(e.nodeName)&&("SELECT"===e.nodeName?e.removeEventListener("change",p):e.removeEventListener("input",p))}))}))})).observe(e,{childList:!0,subtree:!0})}; | ||
!function(){var e=[" ",">","~",":","+","@","#","(",")"];var t="js-blank-pseudo";function n(e){return"INPUT"===e.nodeName||"SELECT"===e.nodeName||"TEXTAREA"===e.nodeName}function r(e){var t;return"function"==typeof Event?t=new Event(e,{bubbles:!0}):(t=document.createEvent("Event")).initEvent(e,!0,!1),t}function o(e,t){var n=Object.getOwnPropertyDescriptor(e.prototype,"value"),r=n.set;n.set=function(){r.apply(this,arguments),t({target:this})},Object.defineProperty(e.prototype,"value",n)}self.cssBlankPseudoInit=function(c){var i={force:!1,replaceWith:"[blank]"};if(void 0!==c&&"force"in c&&(i.force=c.force),void 0!==c&&"replaceWith"in c&&(i.replaceWith=c.replaceWith),!function(t){for(var n=!0,r=0,o=e.length;r<o&&n;r++)t.indexOf(e[r])>-1&&(n=!1);return n}(i.replaceWith))throw new Error(i.replaceWith+" is not a valid replacement since it can't be applied to single elements.");try{if(document.querySelector(":blank"),!i.force)return}catch(e){}var a,d,l,u,s,f,p,v=("."===(a=i.replaceWith)[0]?(d=a.slice(1),l=function(e){return e.classList.remove(d)},u=function(e){return e.classList.add(d)}):(d=a.slice(1,-1),l=function(e){return e.removeAttribute(d,"")},u=function(e){return e.setAttribute(d,"")}),function(e){var t=e.target;n(t)&&(("SELECT"===t.nodeName?t.options[t.selectedIndex].value:t.value)?l(t):u(t))}),m=function(){document.body&&(document.body.addEventListener("change",v),document.body.addEventListener("input",v))},E=function(){Array.prototype.forEach.call(document.querySelectorAll("input, select, textarea"),(function(e){v({target:e})}))};if(document.body?m():window.addEventListener("load",m),-1===document.documentElement.className.indexOf(t)&&(document.documentElement.className+=" js-blank-pseudo"),o(self.HTMLInputElement,v),o(self.HTMLSelectElement,v),o(self.HTMLTextAreaElement,v),s=self.HTMLOptionElement,f=Object.getOwnPropertyDescriptor(s.prototype,"selected"),p=f.set,f.set=function(e){p.apply(this,arguments);var t=r("change");this.parentElement.dispatchEvent(t)},Object.defineProperty(s.prototype,"selected",f),E(),void 0!==self.MutationObserver)new MutationObserver((function(e){e.forEach((function(e){Array.prototype.forEach.call(e.addedNodes||[],(function(e){1===e.nodeType&&n(e)&&v({target:e})}))}))})).observe(document,{childList:!0,subtree:!0});else{var y=function(){return E()};window.addEventListener("load",y),window.addEventListener("DOMContentLoaded",y)}}}(); | ||
//# sourceMappingURL=browser-global.js.map |
186
package.json
{ | ||
"name": "css-blank-pseudo", | ||
"version": "3.0.3", | ||
"description": "Style form elements when they are empty", | ||
"author": "Jonathan Neal <jonathantneal@hotmail.com>", | ||
"license": "CC0-1.0", | ||
"homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/css-blank-pseudo#readme", | ||
"bugs": "https://github.com/csstools/postcss-plugins/issues", | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.mjs", | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.cjs", | ||
"default": "./dist/index.mjs" | ||
}, | ||
"./browser": { | ||
"import": "./dist/browser.mjs", | ||
"require": "./dist/browser.cjs", | ||
"default": "./dist/browser.mjs" | ||
}, | ||
"./browser-global": { | ||
"default": "./dist/browser-global.js" | ||
} | ||
}, | ||
"files": [ | ||
"CHANGELOG.md", | ||
"LICENSE.md", | ||
"README.md", | ||
"dist", | ||
"browser.js" | ||
], | ||
"bin": { | ||
"css-blank-pseudo": "dist/cli.cjs" | ||
}, | ||
"scripts": { | ||
"build": "rollup -c ../../rollup/default.js && npm run copy-browser-scripts-to-old-location", | ||
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"", | ||
"copy-browser-scripts-to-old-location": "node -e \"fs.copyFileSync('./dist/browser-global.js', './browser.js'); fs.copyFileSync('./dist/browser-global.js', './browser-legacy.js')\"", | ||
"lint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern", | ||
"prepublishOnly": "npm run clean && npm run build && npm run test", | ||
"stryker": "stryker run --logLevel error", | ||
"test": "node .tape.mjs && npm run test:exports", | ||
"test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs", | ||
"cli": "css-blank-pseudo", | ||
"test:exports": "node ./test/_import.mjs && node ./test/_require.cjs" | ||
}, | ||
"engines": { | ||
"node": "^12 || ^14 || >=16" | ||
}, | ||
"dependencies": { | ||
"postcss-selector-parser": "^6.0.9" | ||
}, | ||
"peerDependencies": { | ||
"postcss": "^8.4" | ||
}, | ||
"keywords": [ | ||
"postcss", | ||
"css", | ||
"postcss-plugin", | ||
"javascript", | ||
"js", | ||
"polyfill", | ||
"blank", | ||
"empty", | ||
"pseudo", | ||
"selectors", | ||
"accessibility", | ||
"a11y", | ||
"input", | ||
"select", | ||
"textarea" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/csstools/postcss-plugins.git", | ||
"directory": "plugins/css-blank-pseudo" | ||
}, | ||
"volta": { | ||
"extends": "../../package.json" | ||
} | ||
"name": "css-blank-pseudo", | ||
"description": "Style form elements when they are empty", | ||
"version": "4.0.0", | ||
"contributors": [ | ||
{ | ||
"name": "Antonio Laguna", | ||
"email": "antonio@laguna.es", | ||
"url": "https://antonio.laguna.es" | ||
}, | ||
{ | ||
"name": "Romain Menke", | ||
"email": "romainmenke@gmail.com" | ||
}, | ||
{ | ||
"name": "Jonathan Neal", | ||
"email": "jonathantneal@hotmail.com" | ||
} | ||
], | ||
"license": "CC0-1.0", | ||
"funding": { | ||
"type": "opencollective", | ||
"url": "https://opencollective.com/csstools" | ||
}, | ||
"engines": { | ||
"node": "^12 || ^14 || >=16" | ||
}, | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.cjs", | ||
"default": "./dist/index.mjs" | ||
}, | ||
"./browser": { | ||
"import": "./dist/browser.mjs", | ||
"require": "./dist/browser.cjs", | ||
"default": "./dist/browser.mjs" | ||
}, | ||
"./browser-global": { | ||
"default": "./dist/browser-global.js" | ||
} | ||
}, | ||
"files": [ | ||
"CHANGELOG.md", | ||
"LICENSE.md", | ||
"README.md", | ||
"dist" | ||
], | ||
"dependencies": { | ||
"postcss-selector-parser": "^6.0.10" | ||
}, | ||
"peerDependencies": { | ||
"postcss": "^8.2" | ||
}, | ||
"devDependencies": { | ||
"puppeteer": "^15.1.1" | ||
}, | ||
"scripts": { | ||
"build": "rollup -c ../../rollup/default.js", | ||
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"", | ||
"docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs", | ||
"lint": "npm run lint:eslint && npm run lint:package-json", | ||
"lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern", | ||
"lint:package-json": "node ../../.github/bin/format-package-json.mjs", | ||
"prepublishOnly": "npm run clean && npm run build && npm run test", | ||
"test": "node .tape.mjs && npm run test:exports && npm run test:invalid-replacement", | ||
"test:browser": "node ./test/_browser.mjs", | ||
"test:exports": "node ./test/_import.mjs && node ./test/_require.cjs", | ||
"test:invalid-replacement": "node ./test/_valid-replacements.mjs", | ||
"test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs" | ||
}, | ||
"homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/css-blank-pseudo#readme", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/csstools/postcss-plugins.git", | ||
"directory": "plugins/css-blank-pseudo" | ||
}, | ||
"bugs": "https://github.com/csstools/postcss-plugins/issues", | ||
"keywords": [ | ||
"a11y", | ||
"accessibility", | ||
"blank", | ||
"css", | ||
"empty", | ||
"input", | ||
"javascript", | ||
"js", | ||
"polyfill", | ||
"postcss", | ||
"postcss-plugin", | ||
"pseudo", | ||
"select", | ||
"selectors", | ||
"textarea" | ||
], | ||
"csstools": { | ||
"cssdbId": "blank-pseudo-class", | ||
"exportName": "postcssBlankPseudo", | ||
"humanReadableName": "PostCSS Blank Pseudo", | ||
"specUrl": "https://www.w3.org/TR/selectors-4/#blank" | ||
}, | ||
"volta": { | ||
"extends": "../../package.json" | ||
} | ||
} |
166
README.md
@@ -1,16 +0,20 @@ | ||
# CSS Blank Pseudo [<img src="http://jonathantneal.github.io/js-logo.svg" alt="" width="90" height="90" align="right">][CSS Blank Pseudo] | ||
# PostCSS Blank Pseudo [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS Logo" width="90" height="90" align="right">][postcss] | ||
[![NPM Version][npm-img]][npm-url] | ||
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord] | ||
[<img alt="npm version" src="https://img.shields.io/npm/v/css-blank-pseudo.svg" height="20">][npm-url] [<img alt="CSS Standard Status" src="https://cssdb.org/images/badges/blank-pseudo-class.svg" height="20">][css-url] [<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/workflows/test/badge.svg" height="20">][cli-url] [<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord] | ||
[CSS Blank Pseudo] lets you style form elements when they are empty, following | ||
[PostCSS Blank Pseudo] lets you style form elements when they are empty, following | ||
the [Selectors Level 4] specification. | ||
```css | ||
input { | ||
/* style an input */ | ||
```pcss | ||
input:blank { | ||
background-color: yellow; | ||
} | ||
/* becomes */ | ||
input[blank].js-blank-pseudo, .js-blank-pseudo input[blank] { | ||
background-color: yellow; | ||
} | ||
input:blank { | ||
/* style an input without a value */ | ||
background-color: yellow; | ||
} | ||
@@ -21,32 +25,39 @@ ``` | ||
From the command line, transform CSS files that use `:blank` selectors: | ||
Add [PostCSS Blank Pseudo] to your project: | ||
```bash | ||
npx css-blank-pseudo SOURCE.css --output TRANSFORMED.css | ||
npm install postcss css-blank-pseudo --save-dev | ||
``` | ||
Next, use your transformed CSS with this script: | ||
Use it as a [PostCSS] plugin: | ||
```html | ||
<link rel="stylesheet" href="TRANSFORMED.css"> | ||
<script src="https://unpkg.com/css-blank-pseudo/dist/browser-global.js"></script> | ||
<script>cssBlankPseudo(document)</script> | ||
```js | ||
const postcss = require('postcss'); | ||
const postcssBlankPseudo = require('css-blank-pseudo'); | ||
postcss([ | ||
postcssBlankPseudo(/* pluginOptions */) | ||
]).process(YOUR_CSS /*, processOptions */); | ||
``` | ||
⚠️ Please use a versioned url, like this : `https://unpkg.com/css-blank-pseudo@3.0.0/dist/browser-global.js` | ||
Without the version, you might unexpectedly get a new major version of the library with breaking changes. | ||
[PostCSS Blank Pseudo] runs in all Node environments, with special | ||
instructions for: | ||
⚠️ If you were using an older version via a CDN, please update the entire url. | ||
The old URL will no longer work in a future release. | ||
| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | | ||
| --- | --- | --- | --- | --- | --- | | ||
That’s it. The script works in most browsers. | ||
## Options | ||
## How it works | ||
### preserve | ||
The [PostCSS plugin](README-POSTCSS.md) clones rules containing `:blank`, | ||
replacing them with an alternative `[blank]` selector. | ||
The `preserve` option determines whether the original notation | ||
is preserved. By default, it is preserved. | ||
```css | ||
```js | ||
postcssBlankPseudo({ preserve: false }) | ||
``` | ||
```pcss | ||
input:blank { | ||
background-color: yellow; | ||
background-color: yellow; | ||
} | ||
@@ -56,51 +67,102 @@ | ||
input[blank] { | ||
background-color: yellow; | ||
input[blank].js-blank-pseudo, .js-blank-pseudo input[blank] { | ||
background-color: yellow; | ||
} | ||
``` | ||
### replaceWith | ||
The `replaceWith` option determines the selector to use when replacing | ||
the `:blank` pseudo. By default is `[blank]` | ||
```js | ||
postcssBlankPseudo({ replaceWith: '.css-blank' }) | ||
``` | ||
```pcss | ||
input:blank { | ||
background-color: yellow; | ||
background-color: yellow; | ||
} | ||
/* becomes */ | ||
.foo { | ||
color: blue; | ||
color: red; | ||
} | ||
.baz { | ||
color: green; | ||
} | ||
``` | ||
Next, the [JavaScript library](README-BROWSER.md) adds a `blank` attribute to | ||
elements otherwise matching `:blank` natively. | ||
Note that changing this option implies that it needs to be passed to the | ||
browser polyfill as well. | ||
## Browser | ||
```js | ||
import cssBlankPseudoInit from 'css-blank-pseudo/browser'; | ||
cssBlankPseudoInit(); | ||
``` | ||
or | ||
```html | ||
<input value="" blank> | ||
<input value="This element has a value"> | ||
<!-- When using a CDN url you will have to manually update the version number --> | ||
<script src="https://unpkg.com/css-blank-pseudo@3.0.3/dist/browser-global.js"></script> | ||
<script>cssBlankPseudoInit()</script> | ||
``` | ||
## ⚠️ `:not(:blank)` | ||
[PostCSS Blank Pseudo] works in all major browsers, including Safari 6+ and | ||
Internet Explorer 9+ without any additional polyfills. | ||
with option : `preserve` `true` | ||
This plugin conditionally uses `MutationObserver` to ensure recently inserted | ||
inputs get correct styling upon insertion. If you intend to rely on that | ||
behaviour for browsers that do not support `MutationObserver`, you have two | ||
options: | ||
```css | ||
input:not(:blank) { | ||
background-color: yellow; | ||
} | ||
1. Polyfill `MutationObserver`. As long as it runs before `cssBlankPseudoInit`, | ||
the polyfill will work. | ||
2. If you don't want to polyfill `MutationObserver` you can also manually fire | ||
a `change` event upon insertion so they're automatically inspected by the | ||
polyfill. | ||
/* becomes */ | ||
### Browser Usage | ||
input:not([blank]) { | ||
background-color: yellow; | ||
} | ||
#### force | ||
input:not(:blank) { | ||
background-color: yellow; | ||
} | ||
The `force` option determines whether the library runs even if the browser | ||
supports the selector or not. By default, it won't run if the browser does | ||
support the selector. | ||
```js | ||
cssBlankPseudoInit({ force: true }); | ||
``` | ||
When you do not include the JS polyfill one will always match in browsers that support `:blank` natively. | ||
In browsers that do not support `:blank` natively the rule will be invalid. | ||
#### replaceWith | ||
_currently no browsers support `:blank`_ | ||
Similar to the option for the PostCSS Plugin, `replaceWith` determines the | ||
attribute or class to apply to an element when it's considered to be `:blank`. | ||
```js | ||
cssBlankPseudoInit({ replaceWith: '.css-blank' }); | ||
``` | ||
This option should be used if it was changed at PostCSS configuration level. | ||
Please note that using a class, leverages `classList` under the hood which | ||
might not be supported on some old browsers such as IE9, so you may need | ||
to polyfill `classList` in those cases. | ||
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test | ||
[css-url]: https://cssdb.org/#blank-pseudo-class | ||
[discord]: https://discord.gg/bUadyRwkJS | ||
[npm-img]: https://img.shields.io/npm/v/css-blank-pseudo.svg | ||
[npm-url]: https://www.npmjs.com/package/css-blank-pseudo | ||
[CSS Blank Pseudo]: https://github.com/csstools/postcss-plugins/tree/main/plugins/css-blank-pseudo | ||
[PostCSS Preset Env]: https://preset-env.cssdb.org/ | ||
[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#blank | ||
[Gulp PostCSS]: https://github.com/postcss/gulp-postcss | ||
[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss | ||
[PostCSS]: https://github.com/postcss/postcss | ||
[PostCSS Loader]: https://github.com/postcss/postcss-loader | ||
[PostCSS Blank Pseudo]: https://github.com/csstools/postcss-plugins/tree/main/plugins/css-blank-pseudo | ||
[Selectors Level 4]: https://www.w3.org/TR/selectors-4/#blank |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
1
167
0
56068
1
13
54