Comparing version
267
cssesc.js
@@ -1,177 +0,130 @@ | ||
/*! http://mths.be/cssesc v0.1.0 by @mathias */ | ||
;(function(root) { | ||
/*! https://mths.be/cssesc v1.0.0 by @mathias */ | ||
'use strict'; | ||
// Detect free variables `exports` | ||
var freeExports = typeof exports == 'object' && exports; | ||
const object = {}; | ||
const hasOwnProperty = object.hasOwnProperty; | ||
const merge = function(options, defaults) { | ||
if (!options) { | ||
return defaults; | ||
} | ||
const result = {}; | ||
for (let key in defaults) { | ||
// `if (defaults.hasOwnProperty(key) { … }` is not needed here, since | ||
// only recognized option names are used. | ||
result[key] = hasOwnProperty.call(options, key) | ||
? options[key] | ||
: defaults[key]; | ||
} | ||
return result; | ||
}; | ||
// Detect free variable `module` | ||
var freeModule = typeof module == 'object' && module && | ||
module.exports == freeExports && module; | ||
const regexAnySingleEscape = /[ -,\./;-@\[-\^`\{-~]/; | ||
const regexSingleEscape = /[ !#-&\(-,\./;-@\[\]\^`\{-~]/; | ||
const regexAlwaysEscape = /['"\\]/; | ||
const regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g; | ||
// Detect free variable `global`, from Node.js or Browserified code, | ||
// and use it as `root` | ||
var freeGlobal = typeof global == 'object' && global; | ||
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { | ||
root = freeGlobal; | ||
// https://mathiasbynens.be/notes/css-escapes#css | ||
const cssesc = function(string, options) { | ||
options = merge(options, cssesc.options); | ||
if (options.quotes != 'single' && options.quotes != 'double') { | ||
options.quotes = 'single'; | ||
} | ||
const quote = options.quotes == 'double' ? '"' : '\''; | ||
const isIdentifier = options.isIdentifier; | ||
/*--------------------------------------------------------------------------*/ | ||
var object = {}; | ||
var hasOwnProperty = object.hasOwnProperty; | ||
var merge = function(options, defaults) { | ||
if (!options) { | ||
return defaults; | ||
} | ||
var key; | ||
var result = {}; | ||
for (key in defaults) { | ||
// `if (defaults.hasOwnProperty(key) { … }` is not needed here, since | ||
// only recognized option names are used | ||
result[key] = hasOwnProperty.call(options, key) | ||
? options[key] | ||
: defaults[key]; | ||
} | ||
return result; | ||
}; | ||
/*--------------------------------------------------------------------------*/ | ||
var regexAnySingleEscape = /[\x20-\x2C\x2E\x2F\x3B-\x40\x5B-\x5E\x60\x7B-\x7E]/; | ||
var regexSingleEscape = /[\x20\x21\x23-\x26\x28-\x2C\x2E\x2F\x3B-\x40\x5B\x5D\x5E\x60\x7B-\x7E]/; | ||
var regexAlwaysEscape = /['"\\]/; | ||
var regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g; | ||
// http://mathiasbynens.be/notes/css-escapes#css | ||
var cssesc = function(string, options) { | ||
// Handle options | ||
options = merge(options, cssesc.options); | ||
if (options.quotes != 'single' && options.quotes != 'double') { | ||
options.quotes = 'single'; | ||
} | ||
var quote = options.quotes == 'double' ? '"' : '\''; | ||
var isIdentifier = options.isIdentifier; | ||
var firstChar = string.charAt(0); | ||
var output = ''; | ||
var counter = 0; | ||
var length = string.length; | ||
var value; | ||
var character; | ||
var codePoint; | ||
var extra; // used for potential low surrogates | ||
while (counter < length) { | ||
character = string.charAt(counter++); | ||
codePoint = character.charCodeAt(); | ||
// if it’s not a printable ASCII character | ||
if (codePoint < 0x20 || codePoint > 0x7E) { | ||
if (codePoint >= 0xD800 && codePoint <= 0xDBFF && counter < length) { | ||
// high surrogate, and there is a next character | ||
extra = string.charCodeAt(counter++); | ||
if ((extra & 0xFC00) == 0xDC00) { // next character is low surrogate | ||
codePoint = ((codePoint & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; | ||
} else { | ||
// unmatched surrogate; only append this code unit, in case the next | ||
// code unit is the high surrogate of a surrogate pair | ||
counter--; | ||
} | ||
const firstChar = string.charAt(0); | ||
let output = ''; | ||
let counter = 0; | ||
const length = string.length; | ||
while (counter < length) { | ||
const character = string.charAt(counter++); | ||
let codePoint = character.charCodeAt(); | ||
let value; | ||
// If it’s not a printable ASCII character… | ||
if (codePoint < 0x20 || codePoint > 0x7E) { | ||
if (codePoint >= 0xD800 && codePoint <= 0xDBFF && counter < length) { | ||
// It’s a high surrogate, and there is a next character. | ||
const extra = string.charCodeAt(counter++); | ||
if ((extra & 0xFC00) == 0xDC00) { // next character is low surrogate | ||
codePoint = ((codePoint & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; | ||
} else { | ||
// It’s an unmatched surrogate; only append this code unit, in case | ||
// the next code unit is the high surrogate of a surrogate pair. | ||
counter--; | ||
} | ||
value = '\\' + codePoint.toString(16).toUpperCase() + ' '; | ||
} else { | ||
if (options.escapeEverything) { | ||
if (regexAnySingleEscape.test(character)) { | ||
value = '\\' + character; | ||
} else { | ||
value = '\\' + codePoint.toString(16).toUpperCase() + ' '; | ||
} | ||
// `:` can be escaped as `\:`, but that fails in IE < 8 | ||
} else if (/[\t\n\f\r\x0B:]/.test(character)) { | ||
if (!isIdentifier && character == ':') { | ||
value = character; | ||
} else { | ||
value = '\\' + codePoint.toString(16).toUpperCase() + ' '; | ||
} | ||
} else if ( | ||
character == '\\' || | ||
( | ||
!isIdentifier && | ||
( | ||
(character == '"' && quote == character) || | ||
(character == '\'' && quote == character) | ||
) | ||
) || | ||
(isIdentifier && regexSingleEscape.test(character)) | ||
) { | ||
} | ||
value = '\\' + codePoint.toString(16).toUpperCase() + ' '; | ||
} else { | ||
if (options.escapeEverything) { | ||
if (regexAnySingleEscape.test(character)) { | ||
value = '\\' + character; | ||
} else { | ||
value = '\\' + codePoint.toString(16).toUpperCase() + ' '; | ||
} | ||
// Note: `:` could be escaped as `\:`, but that fails in IE < 8. | ||
} else if (/[\t\n\f\r\x0B:]/.test(character)) { | ||
if (!isIdentifier && character == ':') { | ||
value = character; | ||
} else { | ||
value = '\\' + codePoint.toString(16).toUpperCase() + ' '; | ||
} | ||
} else if ( | ||
character == '\\' || | ||
( | ||
!isIdentifier && | ||
( | ||
(character == '"' && quote == character) || | ||
(character == '\'' && quote == character) | ||
) | ||
) || | ||
(isIdentifier && regexSingleEscape.test(character)) | ||
) { | ||
value = '\\' + character; | ||
} else { | ||
value = character; | ||
} | ||
output += value; | ||
} | ||
output += value; | ||
} | ||
if (isIdentifier) { | ||
if (/^_/.test(output)) { | ||
// Prevent IE6 from ignoring the rule altogether (in case this is for an | ||
// identifier used as a selector) | ||
output = '\\_' + output.slice(1); | ||
} else if (/^-[-\d]/.test(output)) { | ||
output = '\\-' + output.slice(1); | ||
} else if (/\d/.test(firstChar)) { | ||
output = '\\3' + firstChar + ' ' + output.slice(1); | ||
} | ||
if (isIdentifier) { | ||
if (/^_/.test(output)) { | ||
// Prevent IE6 from ignoring the rule altogether (in case this is for an | ||
// identifier used as a selector) | ||
output = '\\_' + output.slice(1); | ||
} else if (/^-[-\d]/.test(output)) { | ||
output = '\\-' + output.slice(1); | ||
} else if (/\d/.test(firstChar)) { | ||
output = '\\3' + firstChar + ' ' + output.slice(1); | ||
} | ||
} | ||
// Remove spaces after `\HEX` escapes that are not followed by a hex digit, | ||
// since they’re redundant. Note that this is only possible if the escape | ||
// sequence isn’t preceded by an odd number of backslashes. | ||
output = output.replace(regexExcessiveSpaces, function($0, $1, $2) { | ||
if ($1 && $1.length % 2) { | ||
// it’s not safe to remove the space, so don’t | ||
return $0; | ||
} | ||
// strip the space | ||
return ($1 || '') + $2; | ||
}); | ||
if (!isIdentifier && options.wrap) { | ||
return quote + output + quote; | ||
// Remove spaces after `\HEX` escapes that are not followed by a hex digit, | ||
// since they’re redundant. Note that this is only possible if the escape | ||
// sequence isn’t preceded by an odd number of backslashes. | ||
output = output.replace(regexExcessiveSpaces, function($0, $1, $2) { | ||
if ($1 && $1.length % 2) { | ||
// It’s not safe to remove the space, so don’t. | ||
return $0; | ||
} | ||
return output; | ||
}; | ||
// Strip the space. | ||
return ($1 || '') + $2; | ||
}); | ||
// Expose default options (so they can be overridden globally) | ||
cssesc.options = { | ||
'escapeEverything': false, | ||
'isIdentifier': false, | ||
'quotes': 'single', | ||
'wrap': false | ||
}; | ||
if (!isIdentifier && options.wrap) { | ||
return quote + output + quote; | ||
} | ||
return output; | ||
}; | ||
cssesc.version = '0.1.0'; | ||
// Expose default options (so they can be overridden globally). | ||
cssesc.options = { | ||
'escapeEverything': false, | ||
'isIdentifier': false, | ||
'quotes': 'single', | ||
'wrap': false | ||
}; | ||
/*--------------------------------------------------------------------------*/ | ||
cssesc.version = '1.0.0'; | ||
// Some AMD build optimizers, like r.js, check for specific condition patterns | ||
// like the following: | ||
if ( | ||
typeof define == 'function' && | ||
typeof define.amd == 'object' && | ||
define.amd | ||
) { | ||
define(function() { | ||
return cssesc; | ||
}); | ||
} else if (freeExports && !freeExports.nodeType) { | ||
if (freeModule) { // in Node.js or RingoJS v0.8.0+ | ||
freeModule.exports = cssesc; | ||
} else { // in Narwhal or RingoJS v0.7.0- | ||
freeExports.cssesc = cssesc; | ||
} | ||
} else { // in Rhino or a web browser | ||
root.cssesc = cssesc; | ||
} | ||
}(this)); | ||
module.exports = cssesc; |
@@ -1,2 +0,2 @@ | ||
Copyright Mathias Bynens <http://mathiasbynens.be/> | ||
Copyright Mathias Bynens <https://mathiasbynens.be/> | ||
@@ -3,0 +3,0 @@ Permission is hereby granted, free of charge, to any person obtaining |
101
package.json
{ | ||
"name": "cssesc", | ||
"version": "0.1.0", | ||
"description": "A JavaScript library for escaping CSS strings and identifiers while generating the shortest possible ASCII-only output.", | ||
"homepage": "http://mths.be/cssesc", | ||
"main": "cssesc.js", | ||
"bin": "bin/cssesc", | ||
"man": "man/cssesc.1", | ||
"keywords": [ | ||
"css", | ||
"escape", | ||
"identifier", | ||
"string", | ||
"tool" | ||
], | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "http://mths.be/mit" | ||
} | ||
], | ||
"author": { | ||
"name": "Mathias Bynens", | ||
"url": "http://mathiasbynens.be/" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/mathiasbynens/cssesc.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/mathiasbynens/cssesc/issues" | ||
}, | ||
"files": [ | ||
"LICENSE-MIT.txt", | ||
"cssesc.js", | ||
"bin/", | ||
"man/" | ||
], | ||
"directories": { | ||
"test": "tests" | ||
}, | ||
"scripts": { | ||
"test": "node tests/tests.js" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"grunt": "~0.4.1", | ||
"grunt-shell": "~0.3.1", | ||
"grunt-template": "~0.2.0", | ||
"istanbul": "~0.1.42", | ||
"qunit-clib": "~1.3.0", | ||
"qunitjs": "~1.11.0", | ||
"regenerate": "~0.5.2", | ||
"requirejs": "~2.1.8" | ||
} | ||
"name": "cssesc", | ||
"version": "1.0.0", | ||
"description": "A JavaScript library for escaping CSS strings and identifiers while generating the shortest possible ASCII-only output.", | ||
"homepage": "https://mths.be/cssesc", | ||
"engines": { | ||
"node": ">=4" | ||
}, | ||
"main": "cssesc.js", | ||
"bin": "bin/cssesc", | ||
"man": "man/cssesc.1", | ||
"keywords": [ | ||
"css", | ||
"escape", | ||
"identifier", | ||
"string", | ||
"tool" | ||
], | ||
"license": "MIT", | ||
"author": { | ||
"name": "Mathias Bynens", | ||
"url": "https://mathiasbynens.be/" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/mathiasbynens/cssesc.git" | ||
}, | ||
"bugs": "https://github.com/mathiasbynens/cssesc/issues", | ||
"files": [ | ||
"LICENSE-MIT.txt", | ||
"cssesc.js", | ||
"bin/", | ||
"man/" | ||
], | ||
"scripts": { | ||
"build": "grunt template", | ||
"test": "mocha tests", | ||
"cover": "istanbul cover --report html node_modules/.bin/_mocha tests -- -u exports -R spec" | ||
}, | ||
"devDependencies": { | ||
"codecov": "^1.0.1", | ||
"grunt": "^1.0.1", | ||
"grunt-template": "^1.0.0", | ||
"istanbul": "^0.4.4", | ||
"mocha": "^2.5.3", | ||
"regenerate": "^1.2.1", | ||
"requirejs": "^2.1.16" | ||
} | ||
} |
@@ -1,7 +0,9 @@ | ||
# cssesc [](https://travis-ci.org/mathiasbynens/cssesc) [](https://gemnasium.com/mathiasbynens/cssesc) | ||
# cssesc [](https://travis-ci.org/mathiasbynens/cssesc) [](https://codecov.io/gh/mathiasbynens/cssesc) | ||
A JavaScript library for escaping CSS strings and identifiers while generating the shortest possible ASCII-only output. | ||
This is a JavaScript library for [escaping text for use in CSS strings or identifiers](http://mathiasbynens.be/notes/css-escapes) while generating the shortest possible valid ASCII-only output. [Here’s an online demo.](http://mothereff.in/css-escapes) | ||
This is a JavaScript library for [escaping text for use in CSS strings or identifiers](https://mathiasbynens.be/notes/css-escapes) while generating the shortest possible valid ASCII-only output. [Here’s an online demo.](https://mothereff.in/css-escapes) | ||
[A polyfill for the CSSOM `CSS.escape()` method is available in a separate repository.](https://mths.be/cssescape) (In comparison, _cssesc_ is much more powerful.) | ||
Feel free to fork if you see possible improvements! | ||
@@ -11,17 +13,5 @@ | ||
Via [Bower](http://bower.io/): | ||
Via [npm](https://www.npmjs.com/): | ||
```bash | ||
bower install cssesc | ||
``` | ||
Via [Component](https://github.com/component/component): | ||
```bash | ||
component install mathiasbynens/cssesc | ||
``` | ||
Via [npm](http://npmjs.org/): | ||
```bash | ||
npm install cssesc | ||
@@ -36,36 +26,31 @@ ``` | ||
In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/): | ||
In [Node.js](https://nodejs.org/): | ||
```js | ||
var cssesc = require('cssesc'); | ||
const cssesc = require('cssesc'); | ||
``` | ||
In [Narwhal](http://narwhaljs.org/): | ||
In Ruby using [the `ruby-cssesc` wrapper gem](https://github.com/borodean/ruby-cssesc): | ||
```js | ||
var cssesc = require('cssesc').cssesc; | ||
```bash | ||
gem install ruby-cssesc | ||
``` | ||
In [Rhino](http://www.mozilla.org/rhino/): | ||
```js | ||
load('cssesc.js'); | ||
```ruby | ||
require 'ruby-cssesc' | ||
CSSEsc.escape('I ♥ Ruby', is_identifier: true) | ||
``` | ||
Using an AMD loader like [RequireJS](http://requirejs.org/): | ||
In Sass using [`sassy-escape`](https://github.com/borodean/sassy-escape): | ||
```js | ||
require( | ||
{ | ||
'paths': { | ||
'cssesc': 'path/to/cssesc' | ||
} | ||
}, | ||
['cssesc'], | ||
function(cssesc) { | ||
console.log(cssesc); | ||
} | ||
); | ||
```bash | ||
gem install sassy-escape | ||
``` | ||
```scss | ||
body { | ||
content: escape('I ♥ Sass', $is-identifier: true); | ||
} | ||
``` | ||
## API | ||
@@ -75,3 +60,3 @@ | ||
This function takes a value and returns an escaped version of the value where any characters that are not printable ASCII symbols are escaped using the shortest possible (but valid) [escape sequences for use in CSS strings or identifiers](http://mathiasbynens.be/notes/css-escapes). | ||
This function takes a value and returns an escaped version of the value where any characters that are not printable ASCII symbols are escaped using the shortest possible (but valid) [escape sequences for use in CSS strings or identifiers](https://mathiasbynens.be/notes/css-escapes). | ||
@@ -162,2 +147,19 @@ ```js | ||
#### Overriding the default options globally | ||
The global default settings can be overridden by modifying the `css.options` object. This saves you from passing in an `options` object for every call to `encode` if you want to use the non-default setting. | ||
```js | ||
// Read the global default setting for `escapeEverything`: | ||
cssesc.options.escapeEverything; | ||
// → `false` by default | ||
// Override the global default setting for `escapeEverything`: | ||
cssesc.options.escapeEverything = true; | ||
// Using the global default setting for `escapeEverything`, which is now `true`: | ||
cssesc('foo © bar ≠ baz 𝌆 qux'); | ||
// → '\\66\\6F\\6F\\ \\A9\\ \\62\\61\\72\\ \\2260\\ \\62\\61\\7A\\ \\1D306\\ \\71\\75\\78' | ||
``` | ||
### `cssesc.version` | ||
@@ -193,20 +195,12 @@ | ||
This library has been tested in at least Chrome 28-30, Firefox 3-23, Safari 4-6, Opera 10-15, IE 6-10, Node.js v0.10.0, Narwhal 0.3.2, RingoJS 0.8-0.9, PhantomJS 1.9.0, and Rhino 1.7RC4. | ||
This library supports Node.js v4+ only. For a version that supports browser and environments out-of-the-box, [see v0.1.0](https://github.com/mathiasbynens/cssesc/releases/tag/v0.1.0). | ||
## Unit tests & code coverage | ||
After cloning this repository, run `npm install` to install the dependencies needed for development and testing. You may want to install Istanbul _globally_ using `npm install istanbul -g`. | ||
Once that’s done, you can run the unit tests in Node using `npm test` or `node tests/tests.js`. To run the tests in Rhino, Ringo, Narwhal, and web browsers as well, use `grunt test`. | ||
To generate [the code coverage report](http://rawgithub.com/mathiasbynens/cssesc/master/coverage/cssesc/cssesc.js.html), use `grunt cover`. | ||
## Author | ||
| [](http://twitter.com/mathias "Follow @mathias on Twitter") | | ||
| [](https://twitter.com/mathias "Follow @mathias on Twitter") | | ||
|---| | ||
| [Mathias Bynens](http://mathiasbynens.be/) | | ||
| [Mathias Bynens](https://mathiasbynens.be/) | | ||
## License | ||
This library is available under the [MIT](http://mths.be/mit) license. | ||
This library is available under the [MIT](https://mths.be/mit) license. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
7
-12.5%0
-100%17677
-7.15%120
-24.05%2
100%202
-2.88%