deleted inigui, created features
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
v0.3.0:
|
||||
date: 2015-01-18
|
||||
changes:
|
||||
- PostCSS 4.0
|
||||
- Use a new PostCSS instance for each Grunt target (#12)
|
||||
v0.2.0:
|
||||
date: 2014-11-14
|
||||
changes:
|
||||
- PostCSS 3.0
|
||||
- Maps now inline and containing sourcesContent by default
|
||||
v0.1.0:
|
||||
date: 2014-09-25
|
||||
changes:
|
||||
- First release
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Dmitry Nikitenko <dima.nikitenko@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
# grunt-postcss
|
||||
[](https://travis-ci.org/nDmitry/grunt-postcss)
|
||||
[](https://david-dm.org/nDmitry/grunt-postcss)
|
||||
|
||||
> Apply several post-processors to your CSS using [PostCSS](https://github.com/postcss/postcss).
|
||||
|
||||
## Getting Started
|
||||
This plugin requires Grunt `~0.4.0`
|
||||
|
||||
If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
|
||||
|
||||
```shell
|
||||
npm install grunt-postcss --save-dev
|
||||
```
|
||||
|
||||
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
|
||||
|
||||
```js
|
||||
grunt.loadNpmTasks('grunt-postcss');
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
$ npm install grunt-postcss autoprefixer-core csswring
|
||||
```
|
||||
|
||||
```js
|
||||
grunt.initConfig({
|
||||
postcss: {
|
||||
options: {
|
||||
map: true,
|
||||
processors: [
|
||||
require('autoprefixer-core')({browsers: 'last 1 version'}).postcss,
|
||||
require('csswring').postcss
|
||||
]
|
||||
},
|
||||
dist: {
|
||||
src: 'css/*.css'
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The usage and options are similar with [grunt-autoprefixer](https://github.com/nDmitry/grunt-autoprefixer#options) (except `browsers` option). The only new option is:
|
||||
|
||||
#### options.processors
|
||||
Type: `Array`
|
||||
Default value: `[]`
|
||||
|
||||
An array of PostCSS compatible post-processors.
|
||||
|
||||
## Why would I use this?
|
||||
|
||||
Unlike the traditional approach with separate plugins, grunt-postcss allows you to parse and save CSS only once applying all post-processors in memory and thus reducing your build time. PostCSS is also a simple tool for writing your own CSS post-processors.
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
'use strict';
|
||||
var escapeStringRegexp = require('escape-string-regexp');
|
||||
var ansiStyles = require('ansi-styles');
|
||||
var stripAnsi = require('strip-ansi');
|
||||
var hasAnsi = require('has-ansi');
|
||||
var supportsColor = require('supports-color');
|
||||
var defineProps = Object.defineProperties;
|
||||
var chalk = module.exports;
|
||||
|
||||
function build(_styles) {
|
||||
var builder = function builder() {
|
||||
return applyStyle.apply(builder, arguments);
|
||||
};
|
||||
builder._styles = _styles;
|
||||
// __proto__ is used because we must return a function, but there is
|
||||
// no way to create a function with a different prototype.
|
||||
builder.__proto__ = proto;
|
||||
return builder;
|
||||
}
|
||||
|
||||
var styles = (function () {
|
||||
var ret = {};
|
||||
|
||||
ansiStyles.grey = ansiStyles.gray;
|
||||
|
||||
Object.keys(ansiStyles).forEach(function (key) {
|
||||
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
|
||||
|
||||
ret[key] = {
|
||||
get: function () {
|
||||
return build(this._styles.concat(key));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return ret;
|
||||
})();
|
||||
|
||||
var proto = defineProps(function chalk() {}, styles);
|
||||
|
||||
function applyStyle() {
|
||||
// support varags, but simply cast to string in case there's only one arg
|
||||
var args = arguments;
|
||||
var argsLen = args.length;
|
||||
var str = argsLen !== 0 && String(arguments[0]);
|
||||
if (argsLen > 1) {
|
||||
// don't slice `arguments`, it prevents v8 optimizations
|
||||
for (var a = 1; a < argsLen; a++) {
|
||||
str += ' ' + args[a];
|
||||
}
|
||||
}
|
||||
|
||||
if (!chalk.enabled || !str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/*jshint validthis: true*/
|
||||
var nestedStyles = this._styles;
|
||||
|
||||
for (var i = 0; i < nestedStyles.length; i++) {
|
||||
var code = ansiStyles[nestedStyles[i]];
|
||||
// Replace any instances already present with a re-opening code
|
||||
// otherwise only the part of the string until said closing code
|
||||
// will be colored, and the rest will simply be 'plain'.
|
||||
str = code.open + str.replace(code.closeRe, code.open) + code.close;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function init() {
|
||||
var ret = {};
|
||||
|
||||
Object.keys(styles).forEach(function (name) {
|
||||
ret[name] = {
|
||||
get: function () {
|
||||
return build([name]);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
defineProps(chalk, init());
|
||||
|
||||
chalk.styles = ansiStyles;
|
||||
chalk.hasColor = hasAnsi;
|
||||
chalk.stripColor = stripAnsi;
|
||||
chalk.supportsColor = supportsColor;
|
||||
|
||||
// detect mode if not set manually
|
||||
if (chalk.enabled === undefined) {
|
||||
chalk.enabled = chalk.supportsColor;
|
||||
}
|
||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../has-ansi/cli.js
|
||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../strip-ansi/cli.js
|
||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../supports-color/cli.js
|
||||
Generated
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
var styles = module.exports;
|
||||
|
||||
var codes = {
|
||||
reset: [0, 0],
|
||||
|
||||
bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
|
||||
dim: [2, 22],
|
||||
italic: [3, 23],
|
||||
underline: [4, 24],
|
||||
inverse: [7, 27],
|
||||
hidden: [8, 28],
|
||||
strikethrough: [9, 29],
|
||||
|
||||
black: [30, 39],
|
||||
red: [31, 39],
|
||||
green: [32, 39],
|
||||
yellow: [33, 39],
|
||||
blue: [34, 39],
|
||||
magenta: [35, 39],
|
||||
cyan: [36, 39],
|
||||
white: [37, 39],
|
||||
gray: [90, 39],
|
||||
|
||||
bgBlack: [40, 49],
|
||||
bgRed: [41, 49],
|
||||
bgGreen: [42, 49],
|
||||
bgYellow: [43, 49],
|
||||
bgBlue: [44, 49],
|
||||
bgMagenta: [45, 49],
|
||||
bgCyan: [46, 49],
|
||||
bgWhite: [47, 49]
|
||||
};
|
||||
|
||||
Object.keys(codes).forEach(function (key) {
|
||||
var val = codes[key];
|
||||
var style = styles[key] = {};
|
||||
style.open = '\u001b[' + val[0] + 'm';
|
||||
style.close = '\u001b[' + val[1] + 'm';
|
||||
});
|
||||
Generated
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "ansi-styles",
|
||||
"version": "1.1.0",
|
||||
"description": "ANSI escape codes for styling strings in the terminal",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/ansi-styles"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/ansi-styles/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/ansi-styles",
|
||||
"_id": "ansi-styles@1.1.0",
|
||||
"_shasum": "eaecbf66cd706882760b2f4691582b8f55d7a7de",
|
||||
"_from": "ansi-styles@>=1.1.0 <2.0.0",
|
||||
"_npmVersion": "1.4.9",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "eaecbf66cd706882760b2f4691582b8f55d7a7de",
|
||||
"tarball": "http://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+70
@@ -0,0 +1,70 @@
|
||||
# ansi-styles [](https://travis-ci.org/sindresorhus/ansi-styles)
|
||||
|
||||
> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
|
||||
|
||||
You probably want the higher-level [chalk](https://github.com/sindresorhus/chalk) module for styling your strings.
|
||||
|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save ansi-styles
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansi = require('ansi-styles');
|
||||
|
||||
console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
Each style has an `open` and `close` property.
|
||||
|
||||
|
||||
## Styles
|
||||
|
||||
### General
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `italic` *(not widely supported)*
|
||||
- `underline`
|
||||
- `inverse`
|
||||
- `hidden`
|
||||
- `strikethrough` *(not widely supported)*
|
||||
|
||||
### Text colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue`
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `gray`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
|
||||
|
||||
module.exports = function (str) {
|
||||
if (typeof str !== 'string') {
|
||||
throw new TypeError('Expected a string');
|
||||
}
|
||||
|
||||
return str.replace(matchOperatorsRe, '\\$&');
|
||||
};
|
||||
Generated
Vendored
+69
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "escape-string-regexp",
|
||||
"version": "1.0.2",
|
||||
"description": "Escape RegExp special characters",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sindresorhus/escape-string-regexp"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"regex",
|
||||
"regexp",
|
||||
"re",
|
||||
"regular",
|
||||
"expression",
|
||||
"escape",
|
||||
"string",
|
||||
"str",
|
||||
"special",
|
||||
"characters"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"gitHead": "0587ee0ee03ea3fcbfa3c15cf67b47f214e20987",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/escape-string-regexp/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/escape-string-regexp",
|
||||
"_id": "escape-string-regexp@1.0.2",
|
||||
"_shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1",
|
||||
"_from": "escape-string-regexp@>=1.0.0 <2.0.0",
|
||||
"_npmVersion": "1.4.23",
|
||||
"_npmUser": {
|
||||
"name": "jbnicolai",
|
||||
"email": "jappelman@xebia.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "jbnicolai",
|
||||
"email": "jappelman@xebia.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1",
|
||||
"tarball": "http://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
# escape-string-regexp [](https://travis-ci.org/sindresorhus/escape-string-regexp)
|
||||
|
||||
> Escape RegExp special characters
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save escape-string-regexp
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var escapeStringRegexp = require('escape-string-regexp');
|
||||
|
||||
var escapedString = escapeStringRegexp('how much $ for a unicorn?');
|
||||
//=> how much \$ for a unicorn\?
|
||||
|
||||
new RegExp(escapedString);
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
var pkg = require('./package.json');
|
||||
var hasAnsi = require('./');
|
||||
var input = process.argv[2];
|
||||
|
||||
function stdin(cb) {
|
||||
var ret = '';
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', function (data) {
|
||||
ret += data;
|
||||
});
|
||||
process.stdin.on('end', function () {
|
||||
cb(ret);
|
||||
});
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log([
|
||||
pkg.description,
|
||||
'',
|
||||
'Usage',
|
||||
' $ has-ansi <string>',
|
||||
' $ echo <string> | has-ansi',
|
||||
'',
|
||||
'Exits with code 0 if input has ANSI escape codes and 1 if not'
|
||||
].join('\n'));
|
||||
}
|
||||
|
||||
function init(data) {
|
||||
process.exit(hasAnsi(data) ? 0 : 1);
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('--help') !== -1) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('--version') !== -1) {
|
||||
console.log(pkg.version);
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.stdin.isTTY) {
|
||||
if (!input) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
init(input);
|
||||
} else {
|
||||
stdin(init);
|
||||
}
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
var ansiRegex = require('ansi-regex');
|
||||
var re = new RegExp(ansiRegex().source); // remove the `g` flag
|
||||
module.exports = re.test.bind(re);
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
module.exports = function () {
|
||||
return /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g;
|
||||
};
|
||||
Generated
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "ansi-regex",
|
||||
"version": "0.2.1",
|
||||
"description": "Regular expression for matching ANSI escape codes",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/ansi-regex"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"command-line",
|
||||
"text",
|
||||
"regex",
|
||||
"regexp",
|
||||
"re",
|
||||
"match",
|
||||
"test",
|
||||
"find",
|
||||
"pattern"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/ansi-regex/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/ansi-regex",
|
||||
"_id": "ansi-regex@0.2.1",
|
||||
"_shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
|
||||
"_from": "ansi-regex@>=0.2.1 <0.3.0",
|
||||
"_npmVersion": "1.4.9",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
|
||||
"tarball": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
# ansi-regex [](https://travis-ci.org/sindresorhus/ansi-regex)
|
||||
|
||||
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save ansi-regex
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansiRegex = require('ansi-regex');
|
||||
|
||||
ansiRegex().test('\u001b[4mcake\u001b[0m');
|
||||
//=> true
|
||||
|
||||
ansiRegex().test('cake');
|
||||
//=> false
|
||||
|
||||
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
|
||||
//=> ['\u001b[4m', '\u001b[0m']
|
||||
```
|
||||
|
||||
*It's a function so you can create multiple instances. Regexes with the global flag will have the `.lastIndex` property changed for each call to methods on the instance. Therefore reusing the instance with multiple calls will not work as expected for `.test()`.*
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
+85
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"name": "has-ansi",
|
||||
"version": "0.1.0",
|
||||
"description": "Check if a string has ANSI escape codes",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/has-ansi"
|
||||
},
|
||||
"bin": {
|
||||
"has-ansi": "cli.js"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"cli.js"
|
||||
],
|
||||
"keywords": [
|
||||
"cli",
|
||||
"bin",
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"shell",
|
||||
"xterm",
|
||||
"command-line",
|
||||
"text",
|
||||
"regex",
|
||||
"regexp",
|
||||
"re",
|
||||
"match",
|
||||
"test",
|
||||
"find",
|
||||
"pattern",
|
||||
"has"
|
||||
],
|
||||
"dependencies": {
|
||||
"ansi-regex": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/has-ansi/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/has-ansi",
|
||||
"_id": "has-ansi@0.1.0",
|
||||
"_shasum": "84f265aae8c0e6a88a12d7022894b7568894c62e",
|
||||
"_from": "has-ansi@>=0.1.0 <0.2.0",
|
||||
"_npmVersion": "1.4.9",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "84f265aae8c0e6a88a12d7022894b7568894c62e",
|
||||
"tarball": "http://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
# has-ansi [](https://travis-ci.org/sindresorhus/has-ansi)
|
||||
|
||||
> Check if a string has [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save has-ansi
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var hasAnsi = require('has-ansi');
|
||||
|
||||
hasAnsi('\u001b[4mcake\u001b[0m');
|
||||
//=> true
|
||||
|
||||
hasAnsi('cake');
|
||||
//=> false
|
||||
```
|
||||
|
||||
|
||||
## CLI
|
||||
|
||||
```sh
|
||||
$ npm install --global has-ansi
|
||||
```
|
||||
|
||||
```
|
||||
$ has-ansi --help
|
||||
|
||||
Usage
|
||||
$ has-ansi <string>
|
||||
$ echo <string> | has-ansi
|
||||
|
||||
Exits with code 0 if input has ANSI escape codes and 1 if not
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
var fs = require('fs');
|
||||
var pkg = require('./package.json');
|
||||
var strip = require('./');
|
||||
var input = process.argv[2];
|
||||
|
||||
function help() {
|
||||
console.log([
|
||||
pkg.description,
|
||||
'',
|
||||
'Usage',
|
||||
' $ strip-ansi <input-file> > <output-file>',
|
||||
' $ cat <input-file> | strip-ansi > <output-file>',
|
||||
'',
|
||||
'Example',
|
||||
' $ strip-ansi unicorn.txt > unicorn-stripped.txt'
|
||||
].join('\n'));
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('--help') !== -1) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('--version') !== -1) {
|
||||
console.log(pkg.version);
|
||||
return;
|
||||
}
|
||||
|
||||
if (input) {
|
||||
process.stdout.write(strip(fs.readFileSync(input, 'utf8')));
|
||||
return;
|
||||
}
|
||||
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', function (data) {
|
||||
process.stdout.write(strip(data));
|
||||
});
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
'use strict';
|
||||
var ansiRegex = require('ansi-regex')();
|
||||
|
||||
module.exports = function (str) {
|
||||
return typeof str === 'string' ? str.replace(ansiRegex, '') : str;
|
||||
};
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
module.exports = function () {
|
||||
return /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g;
|
||||
};
|
||||
Generated
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "ansi-regex",
|
||||
"version": "0.2.1",
|
||||
"description": "Regular expression for matching ANSI escape codes",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/ansi-regex"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"command-line",
|
||||
"text",
|
||||
"regex",
|
||||
"regexp",
|
||||
"re",
|
||||
"match",
|
||||
"test",
|
||||
"find",
|
||||
"pattern"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/ansi-regex/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/ansi-regex",
|
||||
"_id": "ansi-regex@0.2.1",
|
||||
"_shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
|
||||
"_from": "ansi-regex@>=0.2.1 <0.3.0",
|
||||
"_npmVersion": "1.4.9",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9",
|
||||
"tarball": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
# ansi-regex [](https://travis-ci.org/sindresorhus/ansi-regex)
|
||||
|
||||
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save ansi-regex
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansiRegex = require('ansi-regex');
|
||||
|
||||
ansiRegex().test('\u001b[4mcake\u001b[0m');
|
||||
//=> true
|
||||
|
||||
ansiRegex().test('cake');
|
||||
//=> false
|
||||
|
||||
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
|
||||
//=> ['\u001b[4m', '\u001b[0m']
|
||||
```
|
||||
|
||||
*It's a function so you can create multiple instances. Regexes with the global flag will have the `.lastIndex` property changed for each call to methods on the instance. Therefore reusing the instance with multiple calls will not work as expected for `.test()`.*
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"name": "strip-ansi",
|
||||
"version": "0.3.0",
|
||||
"description": "Strip ANSI escape codes",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"strip-ansi": "cli.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/strip-ansi"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"cli.js"
|
||||
],
|
||||
"keywords": [
|
||||
"strip",
|
||||
"trim",
|
||||
"remove",
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"dependencies": {
|
||||
"ansi-regex": "^0.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/strip-ansi/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/strip-ansi",
|
||||
"_id": "strip-ansi@0.3.0",
|
||||
"_shasum": "25f48ea22ca79187f3174a4db8759347bb126220",
|
||||
"_from": "strip-ansi@>=0.3.0 <0.4.0",
|
||||
"_npmVersion": "1.4.9",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "25f48ea22ca79187f3174a4db8759347bb126220",
|
||||
"tarball": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
# strip-ansi [](https://travis-ci.org/sindresorhus/strip-ansi)
|
||||
|
||||
> Strip [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save strip-ansi
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var stripAnsi = require('strip-ansi');
|
||||
|
||||
stripAnsi('\x1b[4mcake\x1b[0m');
|
||||
//=> 'cake'
|
||||
```
|
||||
|
||||
|
||||
## CLI
|
||||
|
||||
```sh
|
||||
$ npm install --global strip-ansi
|
||||
```
|
||||
|
||||
```sh
|
||||
$ strip-ansi --help
|
||||
|
||||
Usage
|
||||
$ strip-ansi <input-file> > <output-file>
|
||||
$ cat <input-file> | strip-ansi > <output-file>
|
||||
|
||||
Example
|
||||
$ strip-ansi unicorn.txt > unicorn-stripped.txt
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
var pkg = require('./package.json');
|
||||
var supportsColor = require('./');
|
||||
var input = process.argv[2];
|
||||
|
||||
function help() {
|
||||
console.log([
|
||||
pkg.description,
|
||||
'',
|
||||
'Usage',
|
||||
' $ supports-color',
|
||||
'',
|
||||
'Exits with code 0 if color is supported and 1 if not'
|
||||
].join('\n'));
|
||||
}
|
||||
|
||||
if (!input || process.argv.indexOf('--help') !== -1) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('--version') !== -1) {
|
||||
console.log(pkg.version);
|
||||
return;
|
||||
}
|
||||
|
||||
process.exit(supportsColor ? 0 : 1);
|
||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
module.exports = (function () {
|
||||
if (process.argv.indexOf('--no-color') !== -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('--color') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (process.stdout && !process.stdout.isTTY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('COLORTERM' in process.env) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (process.env.TERM === 'dumb') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})();
|
||||
Generated
Vendored
+78
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "supports-color",
|
||||
"version": "0.2.0",
|
||||
"description": "Detect whether a terminal supports color",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/supports-color"
|
||||
},
|
||||
"bin": {
|
||||
"supports-color": "cli.js"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"cli.js"
|
||||
],
|
||||
"keywords": [
|
||||
"cli",
|
||||
"bin",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"ansi",
|
||||
"styles",
|
||||
"tty",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"command-line",
|
||||
"support",
|
||||
"supports",
|
||||
"capability",
|
||||
"detect"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/supports-color/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/supports-color",
|
||||
"_id": "supports-color@0.2.0",
|
||||
"_shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a",
|
||||
"_from": "supports-color@>=0.2.0 <0.3.0",
|
||||
"_npmVersion": "1.4.9",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a",
|
||||
"tarball": "http://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
# supports-color [](https://travis-ci.org/sindresorhus/supports-color)
|
||||
|
||||
> Detect whether a terminal supports color
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save supports-color
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var supportsColor = require('supports-color');
|
||||
|
||||
if (supportsColor) {
|
||||
console.log('Terminal supports color');
|
||||
}
|
||||
```
|
||||
|
||||
It obeys the `--color` and `--no-color` CLI flags.
|
||||
|
||||
|
||||
## CLI
|
||||
|
||||
```sh
|
||||
$ npm install --global supports-color
|
||||
```
|
||||
|
||||
```sh
|
||||
$ supports-color --help
|
||||
|
||||
Usage
|
||||
$ supports-color
|
||||
|
||||
# Exits with code 0 if color is supported and 1 if not
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
Generated
Vendored
+82
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "chalk",
|
||||
"version": "0.5.1",
|
||||
"description": "Terminal string styling done right. Created because the `colors` module does some really horrible things.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sindresorhus/chalk"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "jbnicolai",
|
||||
"email": "jappelman@xebia.com"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"bench": "matcha benchmark.js"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"ansi",
|
||||
"styles",
|
||||
"tty",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"dependencies": {
|
||||
"ansi-styles": "^1.1.0",
|
||||
"escape-string-regexp": "^1.0.0",
|
||||
"has-ansi": "^0.1.0",
|
||||
"strip-ansi": "^0.3.0",
|
||||
"supports-color": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"matcha": "^0.5.0",
|
||||
"mocha": "*"
|
||||
},
|
||||
"gitHead": "994758f01293f1fdcf63282e9917cb9f2cfbdaac",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/chalk/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/chalk",
|
||||
"_id": "chalk@0.5.1",
|
||||
"_shasum": "663b3a648b68b55d04690d49167aa837858f2174",
|
||||
"_from": "chalk@>=0.5.1 <0.6.0",
|
||||
"_npmVersion": "1.4.14",
|
||||
"_npmUser": {
|
||||
"name": "jbnicolai",
|
||||
"email": "jappelman@xebia.com"
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "663b3a648b68b55d04690d49167aa837858f2174",
|
||||
"tarball": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
# <img width="300" src="https://cdn.rawgit.com/sindresorhus/chalk/77ae94f63ab1ac61389b190e5a59866569d1a376/logo.svg" alt="chalk">
|
||||
|
||||
> Terminal string styling done right
|
||||
|
||||
[](https://travis-ci.org/sindresorhus/chalk)
|
||||

|
||||
|
||||
[colors.js](https://github.com/Marak/colors.js) is currently the most popular string styling module, but it has serious deficiencies like extending String.prototype which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough.
|
||||
|
||||
**Chalk is a clean and focused alternative.**
|
||||
|
||||

|
||||
|
||||
|
||||
## Why
|
||||
|
||||
- Highly performant
|
||||
- Doesn't extend String.prototype
|
||||
- Expressive API
|
||||
- Ability to nest styles
|
||||
- Clean and focused
|
||||
- Auto-detects color support
|
||||
- Actively maintained
|
||||
- [Used by 1000+ modules](https://npmjs.org/browse/depended/chalk)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save chalk
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
|
||||
// style a string
|
||||
console.log( chalk.blue('Hello world!') );
|
||||
|
||||
// combine styled and normal strings
|
||||
console.log( chalk.blue('Hello'), 'World' + chalk.red('!') );
|
||||
|
||||
// compose multiple styles using the chainable API
|
||||
console.log( chalk.blue.bgRed.bold('Hello world!') );
|
||||
|
||||
// pass in multiple arguments
|
||||
console.log( chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz') );
|
||||
|
||||
// nest styles
|
||||
console.log( chalk.red('Hello', chalk.underline.bgBlue('world') + '!') );
|
||||
|
||||
// nest styles of the same type even (color, underline, background)
|
||||
console.log( chalk.green('I am a green line ' + chalk.blue('with a blue substring') + ' that becomes green again!') );
|
||||
```
|
||||
|
||||
Easily define your own themes.
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
var error = chalk.bold.red;
|
||||
console.log(error('Error!'));
|
||||
```
|
||||
|
||||
Take advantage of console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data).
|
||||
|
||||
```js
|
||||
var name = 'Sindre';
|
||||
console.log(chalk.green('Hello %s'), name);
|
||||
//=> Hello Sindre
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### chalk.`<style>[.<style>...](string, [string...])`
|
||||
|
||||
Example: `chalk.red.bold.underline('Hello', 'world');`
|
||||
|
||||
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter.
|
||||
|
||||
Multiple arguments will be separated by space.
|
||||
|
||||
### chalk.enabled
|
||||
|
||||
Color support is automatically detected, but you can override it.
|
||||
|
||||
### chalk.supportsColor
|
||||
|
||||
Detect whether the terminal [supports color](https://github.com/sindresorhus/supports-color).
|
||||
|
||||
Can be overridden by the user with the flags `--color` and `--no-color`.
|
||||
|
||||
Used internally and handled for you, but exposed for convenience.
|
||||
|
||||
### chalk.styles
|
||||
|
||||
Exposes the styles as [ANSI escape codes](https://github.com/sindresorhus/ansi-styles).
|
||||
|
||||
Generally not useful, but you might need just the `.open` or `.close` escape code if you're mixing externally styled strings with yours.
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
|
||||
console.log(chalk.styles.red);
|
||||
//=> {open: '\u001b[31m', close: '\u001b[39m'}
|
||||
|
||||
console.log(chalk.styles.red.open + 'Hello' + chalk.styles.red.close);
|
||||
```
|
||||
|
||||
### chalk.hasColor(string)
|
||||
|
||||
Check whether a string [has color](https://github.com/sindresorhus/has-ansi).
|
||||
|
||||
### chalk.stripColor(string)
|
||||
|
||||
[Strip color](https://github.com/sindresorhus/strip-ansi) from a string.
|
||||
|
||||
Can be useful in combination with `.supportsColor` to strip color on externally styled text when it's not supported.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
var styledString = getText();
|
||||
|
||||
if (!chalk.supportsColor) {
|
||||
styledString = chalk.stripColor(styledString);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Styles
|
||||
|
||||
### General
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `italic` *(not widely supported)*
|
||||
- `underline`
|
||||
- `inverse`
|
||||
- `hidden`
|
||||
- `strikethrough` *(not widely supported)*
|
||||
|
||||
### Text colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue`
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `gray`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
# jsdiff
|
||||
|
||||
[](http://travis-ci.org/kpdecker/jsdiff)
|
||||
|
||||
A javascript text differencing implementation.
|
||||
|
||||
Based on the algorithm proposed in
|
||||
["An O(ND) Difference Algorithm and its Variations" (Myers, 1986)](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927).
|
||||
|
||||
## Installation
|
||||
|
||||
npm install diff
|
||||
|
||||
or
|
||||
|
||||
git clone git://github.com/kpdecker/jsdiff.git
|
||||
|
||||
## API
|
||||
|
||||
* `JsDiff.diffChars(oldStr, newStr[, callback])` - diffs two blocks of text, comparing character by character.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.diffWords(oldStr, newStr[, callback])` - diffs two blocks of text, comparing word by word, ignoring whitespace.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.diffWordsWithSpace(oldStr, newStr[, callback])` - diffs two blocks of text, comparing word by word, treating whitespace as significant.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.diffLines(oldStr, newStr[, callback])` - diffs two blocks of text, comparing line by line.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.diffSentences(oldStr, newStr[, callback])` - diffs two blocks of text, comparing sentence by sentence.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.diffCss(oldStr, newStr[, callback])` - diffs two blocks of text, comparing CSS tokens.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.diffJson(oldObj, newObj[, callback])` - diffs two JSON objects, comparing the fields defined on each. The order of fields, etc does not matter in this comparison.
|
||||
|
||||
Returns a list of change objects (See below).
|
||||
|
||||
* `JsDiff.createPatch(fileName, oldStr, newStr, oldHeader, newHeader)` - creates a unified diff patch.
|
||||
|
||||
Parameters:
|
||||
* `fileName` : String to be output in the filename sections of the patch
|
||||
* `oldStr` : Original string value
|
||||
* `newStr` : New string value
|
||||
* `oldHeader` : Additional information to include in the old file header
|
||||
* `newHeader` : Additional information to include in thew new file header
|
||||
|
||||
* `JsDiff.applyPatch(oldStr, diffStr)` - applies a unified diff patch.
|
||||
|
||||
Return a string containing new version of provided data.
|
||||
|
||||
* `convertChangesToXML(changes)` - converts a list of changes to a serialized XML format
|
||||
|
||||
|
||||
All methods above which accept the optional callback method will run in sync mode when that parameter is omitted and in async mode when supplied. This allows for larger diffs without blocking the event loop.
|
||||
|
||||
### Change Objects
|
||||
Many of the methods above return change objects. These objects are consist of the following fields:
|
||||
|
||||
* `value`: Text content
|
||||
* `added`: True if the value was inserted into the new string
|
||||
* `removed`: True of the value was removed from the old string
|
||||
|
||||
Note that some cases may omit a particular flag field. Comparison on the flag fields should always be done in a truthy or falsy manner.
|
||||
|
||||
## Examples
|
||||
|
||||
Basic example in Node
|
||||
|
||||
```js
|
||||
require('colors')
|
||||
var jsdiff = require('diff');
|
||||
|
||||
var one = 'beep boop';
|
||||
var other = 'beep boob blah';
|
||||
|
||||
var diff = jsdiff.diffChars(one, other);
|
||||
|
||||
diff.forEach(function(part){
|
||||
// green for additions, red for deletions
|
||||
// grey for common parts
|
||||
var color = part.added ? 'green' :
|
||||
part.removed ? 'red' : 'grey';
|
||||
process.stderr.write(part.value[color]);
|
||||
});
|
||||
|
||||
console.log()
|
||||
```
|
||||
Running the above program should yield
|
||||
|
||||
<img src="images/node_example.png" alt="Node Example">
|
||||
|
||||
Basic example in a web page
|
||||
|
||||
```html
|
||||
<pre id="display"></pre>
|
||||
<script src="diff.js"></script>
|
||||
<script>
|
||||
var one = 'beep boop';
|
||||
var other = 'beep boob blah';
|
||||
|
||||
var diff = JsDiff.diffChars(one, other);
|
||||
|
||||
diff.forEach(function(part){
|
||||
// green for additions, red for deletions
|
||||
// grey for common parts
|
||||
var color = part.added ? 'green' :
|
||||
part.removed ? 'red' : 'grey';
|
||||
var span = document.createElement('span');
|
||||
span.style.color = color;
|
||||
span.appendChild(document
|
||||
.createTextNode(part.value));
|
||||
display.appendChild(span);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
Open the above .html file in a browser and you should see
|
||||
|
||||
<img src="images/web_example.png" alt="Node Example">
|
||||
|
||||
**[Full online demo](http://kpdecker.github.com/jsdiff)**
|
||||
|
||||
## License
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2009-2011, Kevin Decker kpdecker@gmail.com
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of Kevin Decker nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
[](https://bitdeli.com/free "Bitdeli Badge")
|
||||
|
||||
+542
@@ -0,0 +1,542 @@
|
||||
/* See LICENSE file for terms of use */
|
||||
|
||||
/*
|
||||
* Text diff implementation.
|
||||
*
|
||||
* This library supports the following APIS:
|
||||
* JsDiff.diffChars: Character by character diff
|
||||
* JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
|
||||
* JsDiff.diffLines: Line based diff
|
||||
*
|
||||
* JsDiff.diffCss: Diff targeted at CSS content
|
||||
*
|
||||
* These methods are based on the implementation proposed in
|
||||
* "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
|
||||
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
|
||||
*/
|
||||
(function(global, undefined) {
|
||||
var JsDiff = (function() {
|
||||
/*jshint maxparams: 5*/
|
||||
/*istanbul ignore next*/
|
||||
function map(arr, mapper, that) {
|
||||
if (Array.prototype.map) {
|
||||
return Array.prototype.map.call(arr, mapper, that);
|
||||
}
|
||||
|
||||
var other = new Array(arr.length);
|
||||
|
||||
for (var i = 0, n = arr.length; i < n; i++) {
|
||||
other[i] = mapper.call(that, arr[i], i, arr);
|
||||
}
|
||||
return other;
|
||||
}
|
||||
function clonePath(path) {
|
||||
return { newPos: path.newPos, components: path.components.slice(0) };
|
||||
}
|
||||
function removeEmpty(array) {
|
||||
var ret = [];
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (array[i]) {
|
||||
ret.push(array[i]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function escapeHTML(s) {
|
||||
var n = s;
|
||||
n = n.replace(/&/g, '&');
|
||||
n = n.replace(/</g, '<');
|
||||
n = n.replace(/>/g, '>');
|
||||
n = n.replace(/"/g, '"');
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
function buildValues(components, newString, oldString, useLongestToken) {
|
||||
var componentPos = 0,
|
||||
componentLen = components.length,
|
||||
newPos = 0,
|
||||
oldPos = 0;
|
||||
|
||||
for (; componentPos < componentLen; componentPos++) {
|
||||
var component = components[componentPos];
|
||||
if (!component.removed) {
|
||||
if (!component.added && useLongestToken) {
|
||||
var value = newString.slice(newPos, newPos + component.count);
|
||||
value = map(value, function(value, i) {
|
||||
var oldValue = oldString[oldPos + i];
|
||||
return oldValue.length > value.length ? oldValue : value;
|
||||
});
|
||||
|
||||
component.value = value.join('');
|
||||
} else {
|
||||
component.value = newString.slice(newPos, newPos + component.count).join('');
|
||||
}
|
||||
newPos += component.count;
|
||||
|
||||
// Common case
|
||||
if (!component.added) {
|
||||
oldPos += component.count;
|
||||
}
|
||||
} else {
|
||||
component.value = oldString.slice(oldPos, oldPos + component.count).join('');
|
||||
oldPos += component.count;
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
var Diff = function(ignoreWhitespace) {
|
||||
this.ignoreWhitespace = ignoreWhitespace;
|
||||
};
|
||||
Diff.prototype = {
|
||||
diff: function(oldString, newString, callback) {
|
||||
var self = this;
|
||||
|
||||
function done(value) {
|
||||
if (callback) {
|
||||
setTimeout(function() { callback(undefined, value); }, 0);
|
||||
return true;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the identity case (this is due to unrolling editLength == 0
|
||||
if (newString === oldString) {
|
||||
return done([{ value: newString }]);
|
||||
}
|
||||
if (!newString) {
|
||||
return done([{ value: oldString, removed: true }]);
|
||||
}
|
||||
if (!oldString) {
|
||||
return done([{ value: newString, added: true }]);
|
||||
}
|
||||
|
||||
newString = this.tokenize(newString);
|
||||
oldString = this.tokenize(oldString);
|
||||
|
||||
var newLen = newString.length, oldLen = oldString.length;
|
||||
var maxEditLength = newLen + oldLen;
|
||||
var bestPath = [{ newPos: -1, components: [] }];
|
||||
|
||||
// Seed editLength = 0, i.e. the content starts with the same values
|
||||
var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
|
||||
if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
|
||||
// Identity per the equality and tokenizer
|
||||
return done([{value: newString.join('')}]);
|
||||
}
|
||||
|
||||
// Main worker method. checks all permutations of a given edit length for acceptance.
|
||||
function execEditLength() {
|
||||
for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
|
||||
var basePath;
|
||||
var addPath = bestPath[diagonalPath-1],
|
||||
removePath = bestPath[diagonalPath+1];
|
||||
oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
|
||||
if (addPath) {
|
||||
// No one else is going to attempt to use this value, clear it
|
||||
bestPath[diagonalPath-1] = undefined;
|
||||
}
|
||||
|
||||
var canAdd = addPath && addPath.newPos+1 < newLen;
|
||||
var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
|
||||
if (!canAdd && !canRemove) {
|
||||
// If this path is a terminal then prune
|
||||
bestPath[diagonalPath] = undefined;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Select the diagonal that we want to branch from. We select the prior
|
||||
// path whose position in the new string is the farthest from the origin
|
||||
// and does not pass the bounds of the diff graph
|
||||
if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
|
||||
basePath = clonePath(removePath);
|
||||
self.pushComponent(basePath.components, undefined, true);
|
||||
} else {
|
||||
basePath = addPath; // No need to clone, we've pulled it from the list
|
||||
basePath.newPos++;
|
||||
self.pushComponent(basePath.components, true, undefined);
|
||||
}
|
||||
|
||||
var oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);
|
||||
|
||||
// If we have hit the end of both strings, then we are done
|
||||
if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
|
||||
return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));
|
||||
} else {
|
||||
// Otherwise track this path as a potential candidate and continue.
|
||||
bestPath[diagonalPath] = basePath;
|
||||
}
|
||||
}
|
||||
|
||||
editLength++;
|
||||
}
|
||||
|
||||
// Performs the length of edit iteration. Is a bit fugly as this has to support the
|
||||
// sync and async mode which is never fun. Loops over execEditLength until a value
|
||||
// is produced.
|
||||
var editLength = 1;
|
||||
if (callback) {
|
||||
(function exec() {
|
||||
setTimeout(function() {
|
||||
// This should not happen, but we want to be safe.
|
||||
/*istanbul ignore next */
|
||||
if (editLength > maxEditLength) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (!execEditLength()) {
|
||||
exec();
|
||||
}
|
||||
}, 0);
|
||||
})();
|
||||
} else {
|
||||
while(editLength <= maxEditLength) {
|
||||
var ret = execEditLength();
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
pushComponent: function(components, added, removed) {
|
||||
var last = components[components.length-1];
|
||||
if (last && last.added === added && last.removed === removed) {
|
||||
// We need to clone here as the component clone operation is just
|
||||
// as shallow array clone
|
||||
components[components.length-1] = {count: last.count + 1, added: added, removed: removed };
|
||||
} else {
|
||||
components.push({count: 1, added: added, removed: removed });
|
||||
}
|
||||
},
|
||||
extractCommon: function(basePath, newString, oldString, diagonalPath) {
|
||||
var newLen = newString.length,
|
||||
oldLen = oldString.length,
|
||||
newPos = basePath.newPos,
|
||||
oldPos = newPos - diagonalPath,
|
||||
|
||||
commonCount = 0;
|
||||
while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
|
||||
newPos++;
|
||||
oldPos++;
|
||||
commonCount++;
|
||||
}
|
||||
|
||||
if (commonCount) {
|
||||
basePath.components.push({count: commonCount});
|
||||
}
|
||||
|
||||
basePath.newPos = newPos;
|
||||
return oldPos;
|
||||
},
|
||||
|
||||
equals: function(left, right) {
|
||||
var reWhitespace = /\S/;
|
||||
return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));
|
||||
},
|
||||
tokenize: function(value) {
|
||||
return value.split('');
|
||||
}
|
||||
};
|
||||
|
||||
var CharDiff = new Diff();
|
||||
|
||||
var WordDiff = new Diff(true);
|
||||
var WordWithSpaceDiff = new Diff();
|
||||
WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
|
||||
return removeEmpty(value.split(/(\s+|\b)/));
|
||||
};
|
||||
|
||||
var CssDiff = new Diff(true);
|
||||
CssDiff.tokenize = function(value) {
|
||||
return removeEmpty(value.split(/([{}:;,]|\s+)/));
|
||||
};
|
||||
|
||||
var LineDiff = new Diff();
|
||||
LineDiff.tokenize = function(value) {
|
||||
var retLines = [],
|
||||
lines = value.split(/^/m);
|
||||
|
||||
for(var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i],
|
||||
lastLine = lines[i - 1];
|
||||
|
||||
// Merge lines that may contain windows new lines
|
||||
if (line === '\n' && lastLine && lastLine[lastLine.length - 1] === '\r') {
|
||||
retLines[retLines.length - 1] += '\n';
|
||||
} else if (line) {
|
||||
retLines.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
return retLines;
|
||||
};
|
||||
|
||||
var SentenceDiff = new Diff();
|
||||
SentenceDiff.tokenize = function (value) {
|
||||
return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/));
|
||||
};
|
||||
|
||||
var JsonDiff = new Diff();
|
||||
// Discriminate between two lines of pretty-printed, serialized JSON where one of them has a
|
||||
// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:
|
||||
JsonDiff.useLongestToken = true;
|
||||
JsonDiff.tokenize = LineDiff.tokenize;
|
||||
JsonDiff.equals = function(left, right) {
|
||||
return LineDiff.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'));
|
||||
};
|
||||
|
||||
var objectPrototypeToString = Object.prototype.toString;
|
||||
|
||||
// This function handles the presence of circular references by bailing out when encountering an
|
||||
// object that is already on the "stack" of items being processed.
|
||||
function canonicalize(obj, stack, replacementStack) {
|
||||
stack = stack || [];
|
||||
replacementStack = replacementStack || [];
|
||||
|
||||
var i;
|
||||
|
||||
for (var i = 0 ; i < stack.length ; i += 1) {
|
||||
if (stack[i] === obj) {
|
||||
return replacementStack[i];
|
||||
}
|
||||
}
|
||||
|
||||
var canonicalizedObj;
|
||||
|
||||
if ('[object Array]' === objectPrototypeToString.call(obj)) {
|
||||
stack.push(obj);
|
||||
canonicalizedObj = new Array(obj.length);
|
||||
replacementStack.push(canonicalizedObj);
|
||||
for (i = 0 ; i < obj.length ; i += 1) {
|
||||
canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);
|
||||
}
|
||||
stack.pop();
|
||||
replacementStack.pop();
|
||||
} else if (typeof obj === 'object' && obj !== null) {
|
||||
stack.push(obj);
|
||||
canonicalizedObj = {};
|
||||
replacementStack.push(canonicalizedObj);
|
||||
var sortedKeys = [];
|
||||
for (var key in obj) {
|
||||
sortedKeys.push(key);
|
||||
}
|
||||
sortedKeys.sort();
|
||||
for (i = 0 ; i < sortedKeys.length ; i += 1) {
|
||||
var key = sortedKeys[i];
|
||||
canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);
|
||||
}
|
||||
stack.pop();
|
||||
replacementStack.pop();
|
||||
} else {
|
||||
canonicalizedObj = obj;
|
||||
}
|
||||
return canonicalizedObj;
|
||||
}
|
||||
|
||||
return {
|
||||
Diff: Diff,
|
||||
|
||||
diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },
|
||||
diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },
|
||||
diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },
|
||||
diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },
|
||||
diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },
|
||||
|
||||
diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },
|
||||
diffJson: function(oldObj, newObj, callback) {
|
||||
return JsonDiff.diff(
|
||||
typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, ' '),
|
||||
typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, ' '),
|
||||
callback
|
||||
);
|
||||
},
|
||||
|
||||
createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
|
||||
var ret = [];
|
||||
|
||||
ret.push('Index: ' + fileName);
|
||||
ret.push('===================================================================');
|
||||
ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
|
||||
ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
|
||||
|
||||
var diff = LineDiff.diff(oldStr, newStr);
|
||||
if (!diff[diff.length-1].value) {
|
||||
diff.pop(); // Remove trailing newline add
|
||||
}
|
||||
diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier
|
||||
|
||||
function contextLines(lines) {
|
||||
return map(lines, function(entry) { return ' ' + entry; });
|
||||
}
|
||||
function eofNL(curRange, i, current) {
|
||||
var last = diff[diff.length-2],
|
||||
isLast = i === diff.length-2,
|
||||
isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
|
||||
|
||||
// Figure out if this is the last line for the given file and missing NL
|
||||
if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
|
||||
curRange.push('\\ No newline at end of file');
|
||||
}
|
||||
}
|
||||
|
||||
var oldRangeStart = 0, newRangeStart = 0, curRange = [],
|
||||
oldLine = 1, newLine = 1;
|
||||
for (var i = 0; i < diff.length; i++) {
|
||||
var current = diff[i],
|
||||
lines = current.lines || current.value.replace(/\n$/, '').split('\n');
|
||||
current.lines = lines;
|
||||
|
||||
if (current.added || current.removed) {
|
||||
if (!oldRangeStart) {
|
||||
var prev = diff[i-1];
|
||||
oldRangeStart = oldLine;
|
||||
newRangeStart = newLine;
|
||||
|
||||
if (prev) {
|
||||
curRange = contextLines(prev.lines.slice(-4));
|
||||
oldRangeStart -= curRange.length;
|
||||
newRangeStart -= curRange.length;
|
||||
}
|
||||
}
|
||||
curRange.push.apply(curRange, map(lines, function(entry) { return (current.added?'+':'-') + entry; }));
|
||||
eofNL(curRange, i, current);
|
||||
|
||||
if (current.added) {
|
||||
newLine += lines.length;
|
||||
} else {
|
||||
oldLine += lines.length;
|
||||
}
|
||||
} else {
|
||||
if (oldRangeStart) {
|
||||
// Close out any changes that have been output (or join overlapping)
|
||||
if (lines.length <= 8 && i < diff.length-2) {
|
||||
// Overlapping
|
||||
curRange.push.apply(curRange, contextLines(lines));
|
||||
} else {
|
||||
// end the range and output
|
||||
var contextSize = Math.min(lines.length, 4);
|
||||
ret.push(
|
||||
'@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
|
||||
+ ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
|
||||
+ ' @@');
|
||||
ret.push.apply(ret, curRange);
|
||||
ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
|
||||
if (lines.length <= 4) {
|
||||
eofNL(ret, i, current);
|
||||
}
|
||||
|
||||
oldRangeStart = 0; newRangeStart = 0; curRange = [];
|
||||
}
|
||||
}
|
||||
oldLine += lines.length;
|
||||
newLine += lines.length;
|
||||
}
|
||||
}
|
||||
|
||||
return ret.join('\n') + '\n';
|
||||
},
|
||||
|
||||
applyPatch: function(oldStr, uniDiff) {
|
||||
var diffstr = uniDiff.split('\n');
|
||||
var diff = [];
|
||||
var remEOFNL = false,
|
||||
addEOFNL = false;
|
||||
|
||||
for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
|
||||
if(diffstr[i][0] === '@') {
|
||||
var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
|
||||
diff.unshift({
|
||||
start:meh[3],
|
||||
oldlength:meh[2],
|
||||
oldlines:[],
|
||||
newlength:meh[4],
|
||||
newlines:[]
|
||||
});
|
||||
} else if(diffstr[i][0] === '+') {
|
||||
diff[0].newlines.push(diffstr[i].substr(1));
|
||||
} else if(diffstr[i][0] === '-') {
|
||||
diff[0].oldlines.push(diffstr[i].substr(1));
|
||||
} else if(diffstr[i][0] === ' ') {
|
||||
diff[0].newlines.push(diffstr[i].substr(1));
|
||||
diff[0].oldlines.push(diffstr[i].substr(1));
|
||||
} else if(diffstr[i][0] === '\\') {
|
||||
if (diffstr[i-1][0] === '+') {
|
||||
remEOFNL = true;
|
||||
} else if(diffstr[i-1][0] === '-') {
|
||||
addEOFNL = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var str = oldStr.split('\n');
|
||||
for (var i = diff.length - 1; i >= 0; i--) {
|
||||
var d = diff[i];
|
||||
for (var j = 0; j < d.oldlength; j++) {
|
||||
if(str[d.start-1+j] !== d.oldlines[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
|
||||
}
|
||||
|
||||
if (remEOFNL) {
|
||||
while (!str[str.length-1]) {
|
||||
str.pop();
|
||||
}
|
||||
} else if (addEOFNL) {
|
||||
str.push('');
|
||||
}
|
||||
return str.join('\n');
|
||||
},
|
||||
|
||||
convertChangesToXML: function(changes){
|
||||
var ret = [];
|
||||
for ( var i = 0; i < changes.length; i++) {
|
||||
var change = changes[i];
|
||||
if (change.added) {
|
||||
ret.push('<ins>');
|
||||
} else if (change.removed) {
|
||||
ret.push('<del>');
|
||||
}
|
||||
|
||||
ret.push(escapeHTML(change.value));
|
||||
|
||||
if (change.added) {
|
||||
ret.push('</ins>');
|
||||
} else if (change.removed) {
|
||||
ret.push('</del>');
|
||||
}
|
||||
}
|
||||
return ret.join('');
|
||||
},
|
||||
|
||||
// See: http://code.google.com/p/google-diff-match-patch/wiki/API
|
||||
convertChangesToDMP: function(changes){
|
||||
var ret = [], change;
|
||||
for ( var i = 0; i < changes.length; i++) {
|
||||
change = changes[i];
|
||||
ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
canonicalize: canonicalize
|
||||
};
|
||||
})();
|
||||
|
||||
/*istanbul ignore next */
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = JsDiff;
|
||||
}
|
||||
else if (typeof define === 'function' && define.amd) {
|
||||
/*global define */
|
||||
define([], function() { return JsDiff; });
|
||||
}
|
||||
else if (typeof global.JsDiff === 'undefined') {
|
||||
global.JsDiff = JsDiff;
|
||||
}
|
||||
})(this);
|
||||
Generated
Vendored
+64
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "diff",
|
||||
"version": "1.2.2",
|
||||
"description": "A javascript text diff implementation.",
|
||||
"keywords": [
|
||||
"diff",
|
||||
"javascript"
|
||||
],
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "kpdecker",
|
||||
"email": "kpdecker@gmail.com"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "http://github.com/kpdecker/jsdiff/issues",
|
||||
"email": "kpdecker@gmail.com"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "BSD",
|
||||
"url": "http://github.com/kpdecker/jsdiff/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/kpdecker/jsdiff.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
},
|
||||
"main": "./diff",
|
||||
"scripts": {
|
||||
"test": "istanbul cover node_modules/.bin/_mocha test/*.js"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"colors": "~0.6.2",
|
||||
"istanbul": "^0.3.2",
|
||||
"mocha": "~1.6",
|
||||
"should": "~1.2"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"files": [
|
||||
"diff.js"
|
||||
],
|
||||
"gitHead": "5199cc4ee4f16b33f5bfddd4d70e2df8338caf60",
|
||||
"homepage": "https://github.com/kpdecker/jsdiff",
|
||||
"_id": "diff@1.2.2",
|
||||
"_shasum": "27f936a1f5831581024e9ac78fbda7330ce79e85",
|
||||
"_from": "diff@>=1.2.1 <2.0.0",
|
||||
"_npmVersion": "1.4.28",
|
||||
"_npmUser": {
|
||||
"name": "kpdecker",
|
||||
"email": "kpdecker@gmail.com"
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "27f936a1f5831581024e9ac78fbda7330ce79e85",
|
||||
"tarball": "http://registry.npmjs.org/diff/-/diff-1.2.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/diff/-/diff-1.2.2.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
+1125
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+190
@@ -0,0 +1,190 @@
|
||||
## 4.0.4
|
||||
* Fix indent detection in some rare cases.
|
||||
|
||||
## 4.0.3
|
||||
* Faster API with 6to5 Loose mode.
|
||||
* Fix indexed source maps support.
|
||||
|
||||
## 4.0.2
|
||||
* Do not copy IE hacks to code style.
|
||||
|
||||
## 4.0.1
|
||||
* Add `source.input` to `Root` too.
|
||||
|
||||
## 4.0 “Duke Flauros”
|
||||
* Rename `Container#childs` to `nodes`.
|
||||
* Rename `PostCSS#processors` to `plugins`.
|
||||
* Add `Node#replaceValues()` method.
|
||||
* Add `Node#moveTo()`, `moveBefore()` and `moveAfter()` methods.
|
||||
* Add `Node#cloneBefore()` and `cloneAfter()` shortcuts.
|
||||
* Add `Node#next()`, `prev()` and `root()` shorcuts.
|
||||
* Add `Node#replaceWith()` method.
|
||||
* Add `Node#error()` method.
|
||||
* Add `Container#removeAll()` method.
|
||||
* Add filter argument to `eachDecl()` and `eachAtRule()`.
|
||||
* Add `Node#source.input` and move `source.file` or `source.id` to `input`.
|
||||
* Change code indent, when node was moved.
|
||||
* Better fix code style on `Rule`, `AtRule` and `Comment` nodes changes.
|
||||
* Allow to create rules and at-rules by hash shortcut in append methods.
|
||||
* Add class name to CSS syntax error output.
|
||||
|
||||
## 3.0.7
|
||||
* Fix IE filter parsing with multiple commands.
|
||||
* Safer way to consume PostCSS object as plugin (by Maxime Thirouin).
|
||||
|
||||
## 3.0.6
|
||||
* Fix missing semicolon when comment comes after last declaration.
|
||||
* Fix Safe Mode declaration parsing on unclosed blocks.
|
||||
|
||||
## 3.0.5
|
||||
* Fix parser to support difficult cases with backslash escape and brackets.
|
||||
* Add `CssSyntaxError#stack` (by Maxime Thirouin).
|
||||
|
||||
## 3.0.4
|
||||
* Fix Safe Mode on unknown word before declaration.
|
||||
|
||||
## 3.0.3
|
||||
* Increase tokenizer speed (by Roman Dvornov).
|
||||
|
||||
## 3.0.2
|
||||
* Fix empty comment parsing.
|
||||
* Fix `Root#normalize` in some inserts.
|
||||
|
||||
## 3.0.1
|
||||
* Fix Rhino JS runtime support.
|
||||
* Typo in deprecated warning (by Maxime Thirouin).
|
||||
|
||||
## 3.0 “Marquis Andrealphus”
|
||||
* New parser, which become the fastest ever CSS parser written in JavaScript.
|
||||
* Parser can now parse declarations and rules in one parent (like in `@page`)
|
||||
and nested declarations for plugins like `postcss-nested`.
|
||||
* Child nodes array is now in `childs` property, instead of `decls` and `rules`.
|
||||
* `map.inline` and `map.sourcesContent` options are now `true` by default.
|
||||
* Fix iterators (`each`, `insertAfter`) on children array changes.
|
||||
* Use previous source map to show origin source of CSS syntax error.
|
||||
* Use 6to5 ES6 compiler, instead of ES6 Transpiler.
|
||||
* Use code style for manually added rules from existing rules.
|
||||
* Use `from` option from previous source map `file` field.
|
||||
* Set `to` value to `from` if `to` option is missing.
|
||||
* Use better node source name when missing `from` option.
|
||||
* Show a syntax error when `;` is missed between declarations.
|
||||
* Allow to pass `PostCSS` instance or list of plugins to `use()` method.
|
||||
* Allow to pass `Result` instance to `process()` method.
|
||||
* Trim Unicode BOM on source maps parsing.
|
||||
* Parse at-rules without spaces like `@import"file"`.
|
||||
* Better previous `sourceMappingURL` annotation comment cleaning.
|
||||
* Do not remove previous `sourceMappingURL` comment on `map.annotation: false`.
|
||||
* Parse nameless at-rules in Safe Mode.
|
||||
* Fix source map generation for nodes without source.
|
||||
* Fix next child `before` if `Root` first child got removed.
|
||||
|
||||
## 2.2.6
|
||||
* Fix map generation for nodes without source (by Josiah Savary).
|
||||
|
||||
## 2.2.5
|
||||
* Fix source map with BOM marker support (by Mohammad Younes).
|
||||
* Fix source map paths (by Mohammad Younes).
|
||||
|
||||
## 2.2.4
|
||||
* Fix `prepend()` on empty `Root`.
|
||||
|
||||
## 2.2.3
|
||||
* Allow to use object shortcut in `use()` with functions like `autoprefixer`.
|
||||
|
||||
## 2.2.2
|
||||
* Add shortcut to set processors in `use()` via object with `.postcss` property.
|
||||
|
||||
## 2.2.1
|
||||
* Send `opts` from `Processor#process(css, opts)` to processors.
|
||||
|
||||
## 2.2 “Marquis Cimeies”
|
||||
* Use GNU style syntax error messages.
|
||||
* Add `Node#replace` method.
|
||||
* Add `CssSyntaxError#reason` property.
|
||||
|
||||
## 2.1.2
|
||||
* Fix UTF-8 support in inline source map.
|
||||
* Fix source map `sourcesContent` if there is no `from` and `to` options.
|
||||
|
||||
## 2.1.1
|
||||
* Allow to miss `to` and `from` options for inline source maps.
|
||||
* Add `Node#source.id` if file name is unknown.
|
||||
* Better detect splitter between rules in CSS concatenation tools.
|
||||
* Automatically clone node in insert methods.
|
||||
|
||||
## 2.1 “King Amdusias”
|
||||
* Change Traceur ES6 compiler to ES6 Transpiler.
|
||||
* Show broken CSS line in syntax error.
|
||||
|
||||
## 2.0 “King Belial”
|
||||
* Project was rewritten from CoffeeScript to ES6.
|
||||
* Add Safe Mode to works with live input or with hacks from legacy code.
|
||||
* More safer parser to pass all hacks from Browserhacks.com.
|
||||
* Use real properties instead of magic getter/setter for raw propeties.
|
||||
|
||||
## 1.0 “Marquis Decarabia”
|
||||
* Save previous source map for each node to support CSS concatenation
|
||||
with multiple previous maps.
|
||||
* Add `map.sourcesContent` option to add origin content to `sourcesContent`
|
||||
inside map.
|
||||
* Allow to set different place of output map in annotation comment.
|
||||
* Allow to use arrays and `Root` in `Container#append` and same methods.
|
||||
* Add `Root#prevMap` with information about previous map.
|
||||
* Allow to use latest PostCSS from GitHub by npm.
|
||||
* `Result` now is lazy and it will stringify output CSS only if you use `css` or
|
||||
`map` property.
|
||||
* Use separated `map.prev` option to set previous map.
|
||||
* Rename `inlineMap` option to `map.inline`.
|
||||
* Rename `mapAnnotation` option to `map.annotation`.
|
||||
* `Result#map` now return `SourceMapGenerator` object, instead of string.
|
||||
* Run previous map autodetect only if input CSS contains annotation comment.
|
||||
* Add `map: 'inline'` shortcut for `map: { inline: true }` option.
|
||||
* `Node#source.file` now will contains absolute path.
|
||||
* Clean `Declaration#between` style on node clone.
|
||||
|
||||
## 0.3.5
|
||||
* Allow to use `Root` or `Result` as first argument in `process()`.
|
||||
* Save parsed AST to `Result#root`.
|
||||
|
||||
## 0.3.4
|
||||
* Better space symbol detect to read UTF-8 BOM correctly.
|
||||
|
||||
## 0.3.3
|
||||
* Remove source map hacks by using new Mozilla’s `source-map` (by Simon Lydell).
|
||||
|
||||
## 0.3.2
|
||||
* Add URI encoding support for inline source maps.
|
||||
|
||||
## 0.3.1
|
||||
* Fix relative paths from previous source map.
|
||||
* Safer space split in `Rule#selectors` (by Simon Lydell).
|
||||
|
||||
## 0.3 “Prince Seere”
|
||||
* Add `Comment` node for comments between declarations or rules.
|
||||
* Add source map annotation comment to output CSS.
|
||||
* Allow to inline source map to annotation comment by data:uri.
|
||||
* Fix source maps on Windows.
|
||||
* Fix source maps for styles in subdirectory (by @nDmitry and @lydell).
|
||||
* Autodetect previous source map.
|
||||
* Add `first` and `last` shortcuts to container nodes.
|
||||
* Parse `!important` to separated property in `Declaration`.
|
||||
* Allow to break iteration by returning `false`.
|
||||
* Copy code style to new nodes.
|
||||
* Add `eachInside` method to recursivelly iterate all nodes.
|
||||
* Add `selectors` shortcut to get selectors array.
|
||||
* Add `toResult` method to `Rule` to simplify work with several input files.
|
||||
* Clean declaration’s `value`, rule’s `selector` and at-rule’s `params`
|
||||
by storing spaces in `between` property.
|
||||
|
||||
## 0.2 “Duke Dantalion”
|
||||
* Add source map support.
|
||||
* Add shortcuts to create nodes.
|
||||
* Method `process()` now returns object with `css` and `map` keys.
|
||||
* Origin CSS file option was renamed from `file` to `from`.
|
||||
* Rename `Node#remove()` method to `removeSelf()` to fix name conflict.
|
||||
* Node source was moved to `source` property with origin file
|
||||
and node end position.
|
||||
* You can set own stringify function.
|
||||
|
||||
## 0.1 “Count Andromalius”
|
||||
* Initial release.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2013 Andrey Sitnik <andrey@sitnik.ru>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Generated
Vendored
+394
@@ -0,0 +1,394 @@
|
||||
# PostCSS [](https://travis-ci.org/postcss/postcss) [](https://gitter.im/postcss/postcss?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
<img align="right" width="95" height="95" src="http://postcss.github.io/postcss/logo.svg" title="Philosopher’s stone, logo of PostCSS">
|
||||
|
||||
PostCSS is a tool to transform CSS by JS plugins. This plugins can add vendor
|
||||
prefixes, polyfill CSS 4 features, inline images, add variables
|
||||
and mixins support. PostCSS with most popular [Autoprefixer] plugin
|
||||
is used by Google, Twitter, Alibaba and Shopify.
|
||||
|
||||
PostCSS does same work as Sass, LESS or Stylus. But, instead of preprocessors,
|
||||
PostCSS is modular, 4—40 times faster and much powerful
|
||||
(Autoprefixer is impossible on preprocessors).
|
||||
|
||||
PostCSS is very small. It contains only CSS parser, CSS node tree API,
|
||||
source map generator and node tree stringifier. All features (like variables
|
||||
or nesting) are made by plugins. PostCSS plugin is just a JS function, that
|
||||
accepts CSS node tree, reads and transforms some of nodes in tree.
|
||||
|
||||
For example, with [Autoprefixer], [cssnext], [CSS Grace],
|
||||
[postcss-nested], [postcss-mixins] and [postcss-easings] plugins
|
||||
you will be able to write this CSS:
|
||||
|
||||
```css
|
||||
@define-mixin social-icon $color {
|
||||
& {
|
||||
background: $color;
|
||||
&:hover {
|
||||
background: color($color whiteness(+10%))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.social-icon {
|
||||
transition: background 200ms ease-in-sine;
|
||||
font-variant-caps: small-caps;
|
||||
&.is-twitter {
|
||||
@mixin social-icon #55acee;
|
||||
}
|
||||
&.is-facebook {
|
||||
@mixin social-icon #3b5998;
|
||||
}
|
||||
&:active {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
@custom-media --mobile (width <= 640px);
|
||||
|
||||
@custom-selector --heading h1, h2, h3, h4, h5, h6;
|
||||
|
||||
.post-article --heading {
|
||||
margin-top: 10rem;
|
||||
@media (--mobile) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Twitter account for articles, releases and new plugins: [@postcss].
|
||||
Weibo account: [postcss].
|
||||
|
||||
<a href="https://evilmartians.com/?utm_source=postcss">
|
||||
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
||||
</a>
|
||||
|
||||
[Autoprefixer]: https://github.com/postcss/autoprefixer
|
||||
[CSS Grace]: https://github.com/cssdream/cssgrace
|
||||
[@postcss]: https://twitter.com/postcss
|
||||
[postcss]: http://weibo.com/postcss
|
||||
[cssnext]: https://github.com/cssnext/cssnext
|
||||
|
||||
## Differences with preprocessors
|
||||
|
||||
1. With preprocessors you write your CSS on special programming language.
|
||||
It is like a PHP, but you mix control statement with styles. As result your
|
||||
styles is slow, because programming language is too compilcated. With PostCSS
|
||||
you write styles on normal CSS, just with custom at-rules and functions.
|
||||
2. Preprocessors tools (like Compass) is written mainly in same
|
||||
preprocessors language. As result this tools is very limited. The libraries
|
||||
adds only a custom functions, variables or mixins. There is no way to add new
|
||||
syntax for CSS 4 polyfills. In PostCSS all magic is written on JS and uses
|
||||
big universe of npm packages. So you have better and smarter tools.
|
||||
3. All features is built in this preprocessor’s language. Adding new features
|
||||
is very difficult for developers, so languages develop slow. All features
|
||||
of PostCSS is just a small JS functions, which transform CSS nodes tree.
|
||||
Many developers create new features and you have bigger choice.
|
||||
|
||||
## Features
|
||||
|
||||
### Modularity
|
||||
|
||||
Without a plugins, PostCSS just parse your CSS and stringify it back without
|
||||
change of any byte. All features is made by small JS funcions
|
||||
from PostCSS plugins. You can choose only features, that you need.
|
||||
|
||||
Variables is a nice example. There are 2 different plugins for variables.
|
||||
[postcss-simple-vars] has Sass like syntax:
|
||||
|
||||
```css
|
||||
a {
|
||||
color: $link-color;
|
||||
}
|
||||
```
|
||||
|
||||
[postcss-custom-properties] is a polyfill for [W3C CSS Custom Properties] draft:
|
||||
|
||||
```css
|
||||
a {
|
||||
color: var(--link-color);
|
||||
}
|
||||
```
|
||||
|
||||
In PostCSS you can choose what variables syntax you want or even take both.
|
||||
|
||||
[W3C CSS Custom Properties]: http://www.w3.org/TR/css-variables/
|
||||
[postcss-custom-properties]: https://github.com/postcss/postcss-custom-properties
|
||||
[postcss-simple-vars]: https://github.com/postcss/postcss-simple-vars
|
||||
|
||||
### Perfomance
|
||||
|
||||
PostCSS is one of the fastest CSS parsers written on JS. Only [CSSOM] is 10%
|
||||
faster and only because it parses CSS not so accurate as PostCSS does.
|
||||
Modular architecture makes PostCSS code is simple and easy to maintain.
|
||||
|
||||
As result PostCSS is incredible fast. PostCSS is written on JS, but even with
|
||||
big [cssnext] plugin pack, it is 4 times faster than [libsass] written on C++.
|
||||
|
||||
If you uses Ruby Sass right now, you will be excited with PostCSS developing
|
||||
process, because PostCSS is 40 times faster that Ruby Sass.
|
||||
|
||||
[cssnext]: https://github.com/cssnext/cssnext
|
||||
[libsass]: https://github.com/sass/libsass
|
||||
[CSSOM]: https://github.com/NV/CSSOM
|
||||
|
||||
### Powerful Tools
|
||||
|
||||
PostCSS plugins can read and rebuild entire CSS node tree.
|
||||
As result PostCSS has many powerful tools that would be impossible
|
||||
on preprocessors. Autoprefixer is a good example of how PostCSS plugin could
|
||||
be useful.
|
||||
|
||||
PostCSS allows you to build linters (like [doiuse] or [BEM Linter]),
|
||||
code review tools (like [list-selectors]) or minifiers (like [CSSWring]).
|
||||
With [postcss-data-packer] plugin you can create a “sprite” from inlined images
|
||||
by moving all `data:uri` values to separated file.
|
||||
|
||||
But my favorite example of PostCSS power is [RTLCSS]. As you know Jews and Arabs
|
||||
has right-to-left writing. Because writing affects to people perspective
|
||||
you need to change your site design (check out [Arabic Wikipedia]).
|
||||
RTLCSS plugin mirrors you design, replace `left` to `right` in your styles,
|
||||
change values order in `margin`, etc.
|
||||
|
||||
[postcss-data-packer]: https://github.com/Ser-Gen/postcss-data-packer
|
||||
[Arabic Wikipedia]: https://ar.wikipedia.org/wiki/%D9%84%D8%BA%D8%A9_%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9
|
||||
[list-selectors]: https://github.com/davidtheclark/list-selectors
|
||||
[BEM Linter]: https://github.com/necolas/postcss-bem-linter
|
||||
[CSSWring]: https://github.com/hail2u/node-csswring
|
||||
[doiuse]: https://github.com/anandthakker/doiuse
|
||||
[RTLCSS]: https://github.com/MohammadYounes/rtlcss
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Add PostCSS to your build tool. See [Grunt], [Gulp] and [webpack] plugins
|
||||
for further instructions.
|
||||
2. Select plugins from list below and add them to your PostCSS.
|
||||
3. Make awesome products.
|
||||
|
||||
[webpack]: https://github.com/postcss/postcss-loader
|
||||
[Grunt]: https://github.com/nDmitry/grunt-postcss
|
||||
[Gulp]: https://github.com/w0rm/gulp-postcss
|
||||
|
||||
## Plugins Packs
|
||||
|
||||
* [cssnext] is a pack of CSS 4 polyfills plugins.
|
||||
* [ACSS] contains plugins to control your CSS by special annotation comments.
|
||||
|
||||
[cssnext]: https://github.com/putaindecode/cssnext
|
||||
[ACSS]: https://github.com/morishitter/acss
|
||||
|
||||
## Plugins
|
||||
|
||||
* [Autoprefixer] adds vendor prefixes to rules by Can I Use.
|
||||
* [cssgrace] with helpers and CSS 3 polyfills for IE and other old browsers.
|
||||
* [csswring] is a CSS minifier.
|
||||
* [rtlcss] mirrors styles for right-to-left locales.
|
||||
* [pixrem] is a `rem` unit polyfill.
|
||||
* [css-mqpacker] joins same CSS media queries into one rule.
|
||||
* [postcss-assets] inlines files and inserts image width and height.
|
||||
* [css2modernizr] analyzes your CSS and output only used Modernizr’s settings.
|
||||
* [postcss-bem-linter] lints CSS for SUIT CSS methodology.
|
||||
* [pleeease-filters] converts WebKit filters to SVG filter for other browsers.
|
||||
* [postcss-custom-selectors] to add custom alias for selectors.
|
||||
* [doiuse] lints CSS for browser support against Can I Use database.
|
||||
* [webpcss] adds links to WebP images for browsers that support it.
|
||||
* [postcss-import] inlines `@import` rules content.
|
||||
* [postcss-nested] unwraps nested rules.
|
||||
* [postcss-media-minmax] adds `<=` and `=>` statements to CSS media queries.
|
||||
* [postcss-mixins] to use mixins.
|
||||
* [postcss-easings] replaces easing name to `cubic-bezier()`.
|
||||
* [postcss-url] rebases or inlines `url()`.
|
||||
* [postcss-epub] adds `-epub-` prefix.
|
||||
* [postcss-custom-properties] is a polyfill for W3C CSS variables spec.
|
||||
* [mq4-hover-shim] is a shim for the `@media (hover: hover)` feature.
|
||||
* [postcss-color-palette] transforms CSS 2 color keywords to a custom palette.
|
||||
* [postcss-custom-media] to add custom alias for media queries.
|
||||
* [css-byebye] removes CSS rules by some criteria.
|
||||
* [postcss-simple-vars] adds Sass-style variables support.
|
||||
* [postcss-data-packer] moves an inlined data into a separate file.
|
||||
* [postcss-color-gray] adds `gray()` function.
|
||||
* [postcss-brand-colors] inserts branding colors by companies name.
|
||||
* [list-selectors] is a code review tool for your CSS.
|
||||
* [postcss-calc] reduce `calc()` with same units.
|
||||
* [postcss-font-variant] adds readable front variant properies support.
|
||||
* [postcss-simple-extend] adds `@extend` support.
|
||||
* [postcss-size] adds `size` shorcut to set width and height in one property.
|
||||
* [postcss-color-hex] transforms `rgb()` and `rgba()` to hex.
|
||||
* [postcss-host] make `:host` selectors work properly with pseudo-classes.
|
||||
* [postcss-color-rebeccapurple] is a `rebeccapurple` color polyfill.
|
||||
* [postcss-color-function] adds functions to transform colors.
|
||||
* [postcss-color-hex-alpha] adds `#rrggbbaa` and `#rgba` notation support.
|
||||
* [postcss-color-hwb] transforms `hwb()` to `rgb()`.
|
||||
* [postcss-single-charset] pops first `@charset` rule.
|
||||
|
||||
[postcss-color-rebeccapurple]: https://github.com/postcss/postcss-color-rebeccapurple
|
||||
[postcss-custom-properties]: https://github.com/postcss/postcss-custom-properties
|
||||
[postcss-custom-selectors]: https://github.com/postcss/postcss-custom-selectors
|
||||
[postcss-color-hex-alpha]: https://github.com/postcss/postcss-color-hex-alpha
|
||||
[postcss-color-function]: https://github.com/postcss/postcss-color-function
|
||||
[postcss-single-charset]: https://github.com/hail2u/postcss-single-charset
|
||||
[postcss-color-palette]: https://github.com/zaim/postcss-color-palette
|
||||
[postcss-simple-extend]: https://github.com/davidtheclark/postcss-simple-extend
|
||||
[postcss-media-minmax]: https://github.com/postcss/postcss-media-minmax
|
||||
[postcss-custom-media]: https://github.com/postcss/postcss-custom-media
|
||||
[postcss-brand-colors]: https://github.com/postcss/postcss-brand-colors
|
||||
[postcss-font-variant]: https://github.com/postcss/postcss-font-variant
|
||||
[postcss-simple-vars]: https://github.com/postcss/postcss-simple-vars
|
||||
[postcss-data-packer]: https://github.com/Ser-Gen/postcss-data-packer
|
||||
[postcss-bem-linter]: https://github.com/necolas/postcss-bem-linter
|
||||
[postcss-color-gray]: https://github.com/postcss/postcss-color-gray
|
||||
[postcss-color-hex]: https://github.com/TrySound/postcss-color-hex
|
||||
[postcss-color-hwb]: https://github.com/postcss/postcss-color-hwb
|
||||
[pleeease-filters]: https://github.com/iamvdo/pleeease-filters
|
||||
[postcss-easings]: https://github.com/postcss/postcss-easings
|
||||
[postcss-assets]: https://github.com/borodean/postcss-assets
|
||||
[postcss-import]: https://github.com/postcss/postcss-import
|
||||
[postcss-nested]: https://github.com/postcss/postcss-nested
|
||||
[postcss-mixins]: https://github.com/postcss/postcss-mixins
|
||||
[mq4-hover-shim]: https://github.com/twbs/mq4-hover-shim
|
||||
[list-selectors]: https://github.com/davidtheclark/list-selectors
|
||||
[css2modernizr]: https://github.com/vovanbo/css2modernizr
|
||||
[Autoprefixer]: https://github.com/postcss/autoprefixer
|
||||
[css-mqpacker]: https://github.com/hail2u/node-css-mqpacker
|
||||
[postcss-epub]: https://github.com/Rycochet/postcss-epub
|
||||
[postcss-calc]: https://github.com/postcss/postcss-calc
|
||||
[postcss-size]: https://github.com/postcss/postcss-size
|
||||
[postcss-host]: https://github.com/vitkarpov/postcss-host
|
||||
[postcss-url]: https://github.com/postcss/postcss-url
|
||||
[css-byebye]: https://github.com/AoDev/css-byebye
|
||||
[cssgrace]: https://github.com/cssdream/cssgrace
|
||||
[csswring]: https://github.com/hail2u/node-csswring
|
||||
[webpcss]: https://github.com/lexich/webpcss
|
||||
[rtlcss]: https://github.com/MohammadYounes/rtlcss
|
||||
[pixrem]: https://github.com/robwierzbowski/node-pixrem
|
||||
[doiuse]: https://github.com/anandthakker/doiuse
|
||||
|
||||
## Usage
|
||||
|
||||
### JavaScript API
|
||||
|
||||
```js
|
||||
var postcss = require('postcss');
|
||||
var processor = postcss([require('cssnext'), require('cssgrace')]);
|
||||
|
||||
var result = processor.process(css, { from: 'app.css', to: 'app.out.css' });
|
||||
console.log(result.css);
|
||||
```
|
||||
|
||||
Read [postcss function], [processor] and [Result] API docs for more details.
|
||||
|
||||
[postcss function]: https://github.com/postcss/postcss/blob/master/API.md#postcss-function
|
||||
[processor]: https://github.com/postcss/postcss/blob/master/API.md#postcss-class
|
||||
[Result]: https://github.com/postcss/postcss/blob/master/API.md#result-class
|
||||
|
||||
### Source Maps
|
||||
|
||||
By using [source maps], a browser’s development tools can indicate the
|
||||
original position of your styles before the css file was transformed.
|
||||
For example, an inspector will show the position in a Sass file, even if
|
||||
the file has been compiled to CSS, concatenated, and minified.
|
||||
|
||||
To ensure a correct source map is generated, every CSS processing step should
|
||||
update the map generated by the previous step. For example, a Sass compiler
|
||||
will generate the first map, a concatenation tool should update the Sass step’s
|
||||
map, and a minifier should update the map generated by the concatenation tool.
|
||||
|
||||
There are two ways to store a source map:
|
||||
|
||||
* You can place it in a separate file which contains a special annotation
|
||||
comments pointing to another file:
|
||||
|
||||
```css
|
||||
a { }
|
||||
/*# sourceMappingURL=main.out.css.map */
|
||||
```
|
||||
* Or you can inline a base64-encoded source map within a CSS comment:
|
||||
|
||||
```css
|
||||
a { }
|
||||
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5taW4uY3NzIiwic291cmNlcyI6WyJtYWluLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFLIn0= */
|
||||
```
|
||||
|
||||
PostCSS has great source map support. To ensure that you generate the correct
|
||||
source map, you must indicate the input and output CSS files
|
||||
paths (using the options `from` and `to` respectively).
|
||||
|
||||
To generate a new source map with the default options, provide `map: true`.
|
||||
This will inline sourcemap with source content. If you don’t want the map
|
||||
inlined, you can use `map.inline: false` option.
|
||||
|
||||
```js
|
||||
var result = processor.process(css, {
|
||||
from: 'main.css',
|
||||
to: 'main.out.css'
|
||||
map: { inline: false },
|
||||
});
|
||||
|
||||
result.map //=> '{"version":3,"file":"main.out.css","sources":["main.css"],"names":[],"mappings":"AAAA,KAAI"}'
|
||||
```
|
||||
|
||||
If PostCSS is handling CSS and finds source maps from previous transformations,
|
||||
it will automatically update the CSS with the same options.
|
||||
|
||||
```js
|
||||
// main.sass.css has an annotation comment with a link to main.sass.css.map
|
||||
var result = minifier.process(css, { from: 'main.sass.css', to: 'main.min.css' });
|
||||
result.map //=> Source map from main.sass to main.min.css
|
||||
```
|
||||
|
||||
If you want more control over source map generation, you can define the `map`
|
||||
option as an object with the following parameters:
|
||||
|
||||
* `inline` (boolean): indicates the source map should be inserted into the CSS
|
||||
base64 string as a comment. By default it is `true`. But if all previous map
|
||||
are in separated too, PostCSS will not inline map too.
|
||||
|
||||
If you inline a source map, `result.map` will be empty, as the source map
|
||||
will be contained within the text of `result.css`.
|
||||
|
||||
* `prev` (string, object, or boolean): map content from a previous processing
|
||||
step (for example, Sass compilation). PostCSS will try to read the previous
|
||||
source map automatically from the comment within origin CSS, but you can also
|
||||
set manually. If desired, you can omit the previous map with `prev: false`.
|
||||
|
||||
This is a source map option which can be passed to `postcss.parse(css, opts)`.
|
||||
Other options can be passed to the `toResult(opts)` or `process(css, opts)`
|
||||
methods.
|
||||
|
||||
* `sourcesContent` (boolean): indicates that we should set the origin content
|
||||
(for example, Sass source) of the source map. By default it is `true`.
|
||||
But if all previous map do not contain sources content,
|
||||
PostCSS will miss it too.
|
||||
|
||||
* `annotation` (boolean or string): indicates if we should add annotation
|
||||
comments to the CSS. By default, PostCSS will always add a comment with a path
|
||||
to the source map. But if the previous CSS does not have an annotation
|
||||
comment, PostCSS will omit it too.
|
||||
|
||||
By default, PostCSS presumes that you want to save the source map as
|
||||
`opts.to + '.map'` and will use this path in the annotation comment.
|
||||
But you can set another path by providing a string value as the `annotation`
|
||||
option.
|
||||
|
||||
If you set `inline: true`, annotation cannot be disabled.
|
||||
|
||||
[source maps]: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
|
||||
|
||||
### Safe Mode
|
||||
|
||||
If you provide a `safe: true` option to the `process` or `parse` methods,
|
||||
PostCSS will try to correct any syntax error that it finds in the CSS.
|
||||
|
||||
```js
|
||||
postcss.parse('a {'); // will throw "Unclosed block"
|
||||
postcss.parse('a {', { safe: true }); // will return CSS root for a {}
|
||||
```
|
||||
|
||||
This is useful for legacy code filled with plenty of hacks. Another use case
|
||||
is interactive tools with live input, for example,
|
||||
the [Autoprefixer demo](http://jsfiddle.net/simevidas/udyTs/show/light/).
|
||||
|
||||
## How to Develop PostCSS Plugin
|
||||
|
||||
* [PostCSS API](https://github.com/postcss/postcss/blob/master/API.md)
|
||||
* [Plugin Boilerplate](https://github.com/postcss/postcss-plugin-boilerplate)
|
||||
Generated
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Container = _interopRequire(require("./container"));
|
||||
|
||||
// CSS at-rule like “this.keyframes name { }”.
|
||||
//
|
||||
// Can contain declarations (like this.font-face or this.page) ot another rules.
|
||||
var AtRule = (function (Container) {
|
||||
function AtRule(defaults) {
|
||||
_classCallCheck(this, AtRule);
|
||||
|
||||
this.type = "atrule";
|
||||
Container.call(this, defaults);
|
||||
}
|
||||
|
||||
_inherits(AtRule, Container);
|
||||
|
||||
// Stringify at-rule
|
||||
AtRule.prototype.stringify = function stringify(builder, semicolon) {
|
||||
var name = "@" + this.name;
|
||||
var params = this.params ? this.stringifyRaw("params") : "";
|
||||
|
||||
if (typeof this.afterName != "undefined") {
|
||||
name += this.afterName;
|
||||
} else if (params) {
|
||||
name += " ";
|
||||
}
|
||||
|
||||
if (this.nodes) {
|
||||
this.stringifyBlock(builder, name + params);
|
||||
} else {
|
||||
var before = this.style("before");
|
||||
if (before) builder(before);
|
||||
var end = (this.between || "") + (semicolon ? ";" : "");
|
||||
builder(name + params + end, this);
|
||||
}
|
||||
};
|
||||
|
||||
// Hack to mark, that at-rule contains children
|
||||
AtRule.prototype.append = function append(child) {
|
||||
if (!this.nodes) this.nodes = [];
|
||||
return Container.prototype.append.call(this, child);
|
||||
};
|
||||
|
||||
// Hack to mark, that at-rule contains children
|
||||
AtRule.prototype.prepend = function prepend(child) {
|
||||
if (!this.nodes) this.nodes = [];
|
||||
return Container.prototype.prepend.call(this, child);
|
||||
};
|
||||
|
||||
// Hack to mark, that at-rule contains children
|
||||
AtRule.prototype.insertBefore = function insertBefore(exist, add) {
|
||||
if (!this.nodes) this.nodes = [];
|
||||
return Container.prototype.insertBefore.call(this, exist, add);
|
||||
};
|
||||
|
||||
// Hack to mark, that at-rule contains children
|
||||
AtRule.prototype.insertAfter = function insertAfter(exist, add) {
|
||||
if (!this.nodes) this.nodes = [];
|
||||
return Container.prototype.insertAfter.call(this, exist, add);
|
||||
};
|
||||
|
||||
return AtRule;
|
||||
})(Container);
|
||||
|
||||
module.exports = AtRule;
|
||||
Generated
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Node = _interopRequire(require("./node"));
|
||||
|
||||
// CSS comment between declarations or rules
|
||||
var Comment = (function (Node) {
|
||||
function Comment(defaults) {
|
||||
_classCallCheck(this, Comment);
|
||||
|
||||
this.type = "comment";
|
||||
Node.call(this, defaults);
|
||||
}
|
||||
|
||||
_inherits(Comment, Node);
|
||||
|
||||
// Stringify declaration
|
||||
Comment.prototype.stringify = function stringify(builder) {
|
||||
var before = this.style("before");
|
||||
if (before) builder(before);
|
||||
var left = this.style("left", "commentLeft");
|
||||
var right = this.style("right", "commentRight");
|
||||
builder("/*" + left + this.text + right + "*/", this);
|
||||
};
|
||||
|
||||
return Comment;
|
||||
})(Node);
|
||||
|
||||
module.exports = Comment;
|
||||
Generated
Vendored
+529
@@ -0,0 +1,529 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Declaration = _interopRequire(require("./declaration"));
|
||||
|
||||
var Comment = _interopRequire(require("./comment"));
|
||||
|
||||
var Node = _interopRequire(require("./node"));
|
||||
|
||||
// CSS node, that contain another nodes (like at-rules or rules with selectors)
|
||||
var Container = (function (Node) {
|
||||
function Container() {
|
||||
_classCallCheck(this, Container);
|
||||
|
||||
if (Node != null) {
|
||||
Node.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(Container, Node);
|
||||
|
||||
// Stringify container children
|
||||
Container.prototype.stringifyContent = function stringifyContent(builder) {
|
||||
if (!this.nodes) return;
|
||||
|
||||
var i,
|
||||
last = this.nodes.length - 1;
|
||||
while (last > 0) {
|
||||
if (this.nodes[last].type != "comment") break;
|
||||
last -= 1;
|
||||
}
|
||||
|
||||
var semicolon = this.style("semicolon");
|
||||
for (i = 0; i < this.nodes.length; i++) {
|
||||
this.nodes[i].stringify(builder, last != i || semicolon);
|
||||
}
|
||||
};
|
||||
|
||||
// Stringify node with start (for example, selector) and brackets block
|
||||
// with child inside
|
||||
Container.prototype.stringifyBlock = function stringifyBlock(builder, start) {
|
||||
var before = this.style("before");
|
||||
if (before) builder(before);
|
||||
|
||||
var between = this.style("between", "beforeOpen");
|
||||
builder(start + between + "{", this, "start");
|
||||
|
||||
var after;
|
||||
if (this.nodes && this.nodes.length) {
|
||||
this.stringifyContent(builder);
|
||||
after = this.style("after");
|
||||
} else {
|
||||
after = this.style("after", "emptyBody");
|
||||
}
|
||||
|
||||
if (after) builder(after);
|
||||
builder("}", this, "end");
|
||||
};
|
||||
|
||||
// Add child to end of list without any checks.
|
||||
// Please, use `append()` method, `push()` is mostly for parser.
|
||||
Container.prototype.push = function push(child) {
|
||||
child.parent = this;
|
||||
this.nodes.push(child);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Execute `callback` on every child element. First arguments will be child
|
||||
// node, second will be index.
|
||||
//
|
||||
// css.each( (rule, i) => {
|
||||
// console.log(rule.type + ' at ' + i);
|
||||
// });
|
||||
//
|
||||
// It is safe for add and remove elements to list while iterating:
|
||||
//
|
||||
// css.each( (rule) => {
|
||||
// css.insertBefore( rule, addPrefix(rule) );
|
||||
// # On next iteration will be next rule, regardless of that
|
||||
// # list size was increased
|
||||
// });
|
||||
Container.prototype.each = function each(callback) {
|
||||
if (!this.lastEach) this.lastEach = 0;
|
||||
if (!this.indexes) this.indexes = {};
|
||||
|
||||
this.lastEach += 1;
|
||||
var id = this.lastEach;
|
||||
this.indexes[id] = 0;
|
||||
|
||||
if (!this.nodes) return;
|
||||
|
||||
var index, result;
|
||||
while (this.indexes[id] < this.nodes.length) {
|
||||
index = this.indexes[id];
|
||||
result = callback(this.nodes[index], index);
|
||||
if (result === false) break;
|
||||
|
||||
this.indexes[id] += 1;
|
||||
}
|
||||
|
||||
delete this.indexes[id];
|
||||
|
||||
if (result === false) return false;
|
||||
};
|
||||
|
||||
// Execute callback on every child in all rules inside.
|
||||
//
|
||||
// First argument will be child node, second will be index inside parent.
|
||||
//
|
||||
// css.eachInside( (node, i) => {
|
||||
// console.log(node.type + ' at ' + i);
|
||||
// });
|
||||
//
|
||||
// Also as `each` it is safe of insert/remove nodes inside iterating.
|
||||
Container.prototype.eachInside = function eachInside(callback) {
|
||||
return this.each(function (child, i) {
|
||||
var result = callback(child, i);
|
||||
|
||||
if (result !== false && child.eachInside) {
|
||||
result = child.eachInside(callback);
|
||||
}
|
||||
|
||||
if (result === false) return result;
|
||||
});
|
||||
};
|
||||
|
||||
// Execute callback on every declaration in all rules inside.
|
||||
// It will goes inside at-rules recursivelly.
|
||||
//
|
||||
// First argument will be declaration node, second will be index inside
|
||||
// parent rule.
|
||||
//
|
||||
// css.eachDecl( (decl, i) => {
|
||||
// console.log(decl.prop + ' in ' + decl.parent.selector + ':' + i);
|
||||
// });
|
||||
//
|
||||
// Also as `each` it is safe of insert/remove nodes inside iterating.
|
||||
//
|
||||
// You can filter declrataion by property name:
|
||||
//
|
||||
// css.eachDecl('background', (decl) => { });
|
||||
Container.prototype.eachDecl = function eachDecl(prop, callback) {
|
||||
if (!callback) {
|
||||
callback = prop;
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "decl") {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
} else if (prop instanceof RegExp) {
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "decl" && prop.test(child.prop)) {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "decl" && child.prop == prop) {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Execute `callback` on every rule in conatiner and inside child at-rules.
|
||||
//
|
||||
// First argument will be rule node, second will be index inside parent.
|
||||
//
|
||||
// css.eachRule( (rule, i) => {
|
||||
// if ( parent.type == 'atrule' ) {
|
||||
// console.log(rule.selector + ' in ' + rule.parent.name);
|
||||
// } else {
|
||||
// console.log(rule.selector + ' at ' + i);
|
||||
// }
|
||||
// });
|
||||
Container.prototype.eachRule = function eachRule(callback) {
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "rule") {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Execute `callback` on every at-rule in conatiner and inside at-rules.
|
||||
//
|
||||
// First argument will be at-rule node, second will be index inside parent.
|
||||
//
|
||||
// css.eachAtRule( (atrule, parent, i) => {
|
||||
// if ( parent.type == 'atrule' ) {
|
||||
// console.log(atrule.name + ' in ' + atrule.parent.name);
|
||||
// } else {
|
||||
// console.log(atrule.name + ' at ' + i);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// You can filter at-rules by name:
|
||||
//
|
||||
// css.eachAtRule('keyframes', (atrule) => { });
|
||||
Container.prototype.eachAtRule = function eachAtRule(name, callback) {
|
||||
if (!callback) {
|
||||
callback = name;
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "atrule") {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
} else if (name instanceof RegExp) {
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "atrule" && name.test(child.name)) {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "atrule" && child.name == name) {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Execute callback on every block comment (only between rules
|
||||
// and declarations, not inside selectors and values) in all rules inside.
|
||||
//
|
||||
// First argument will be comment node, second will be index inside
|
||||
// parent rule.
|
||||
//
|
||||
// css.eachComment( (comment, i) => {
|
||||
// console.log(comment.content + ' at ' + i);
|
||||
// });
|
||||
//
|
||||
// Also as `each` it is safe of insert/remove nodes inside iterating.
|
||||
Container.prototype.eachComment = function eachComment(callback) {
|
||||
return this.eachInside(function (child, i) {
|
||||
if (child.type == "comment") {
|
||||
var result = callback(child, i);
|
||||
if (result === false) return result;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Add child to container.
|
||||
//
|
||||
// css.append(rule);
|
||||
//
|
||||
// You can add declaration by hash:
|
||||
//
|
||||
// rule.append({ prop: 'color', value: 'black' });
|
||||
Container.prototype.append = function append(child) {
|
||||
var nodes = this.normalize(child, this.last);
|
||||
for (var _iterator = nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
this.nodes.push(node);
|
||||
}return this;
|
||||
};
|
||||
|
||||
// Add child to beginning of container
|
||||
//
|
||||
// css.prepend(rule);
|
||||
//
|
||||
// You can add declaration by hash:
|
||||
//
|
||||
// rule.prepend({ prop: 'color', value: 'black' });
|
||||
Container.prototype.prepend = function prepend(child) {
|
||||
var nodes = this.normalize(child, this.first, "prepend").reverse();
|
||||
for (var _iterator = nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
this.nodes.unshift(node);
|
||||
}for (var id in this.indexes) {
|
||||
this.indexes[id] = this.indexes[id] + nodes.length;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Insert new `added` child before `exist`.
|
||||
// You can set node object or node index (it will be faster) in `exist`.
|
||||
//
|
||||
// css.insertAfter(1, rule);
|
||||
//
|
||||
// You can add declaration by hash:
|
||||
//
|
||||
// rule.insertBefore(1, { prop: 'color', value: 'black' });
|
||||
Container.prototype.insertBefore = function insertBefore(exist, add) {
|
||||
exist = this.index(exist);
|
||||
|
||||
var type = exist === 0 ? "prepend" : false;
|
||||
var nodes = this.normalize(add, this.nodes[exist], type).reverse();
|
||||
for (var _iterator = nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
this.nodes.splice(exist, 0, node);
|
||||
}var index;
|
||||
for (var id in this.indexes) {
|
||||
index = this.indexes[id];
|
||||
if (exist <= index) {
|
||||
this.indexes[id] = index + nodes.length;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Insert new `added` child after `exist`.
|
||||
// You can set node object or node index (it will be faster) in `exist`.
|
||||
//
|
||||
// css.insertAfter(1, rule);
|
||||
//
|
||||
// You can add declaration by hash:
|
||||
//
|
||||
// rule.insertAfter(1, { prop: 'color', value: 'black' });
|
||||
Container.prototype.insertAfter = function insertAfter(exist, add) {
|
||||
exist = this.index(exist);
|
||||
|
||||
var nodes = this.normalize(add, this.nodes[exist]).reverse();
|
||||
for (var _iterator = nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
this.nodes.splice(exist + 1, 0, node);
|
||||
}var index;
|
||||
for (var id in this.indexes) {
|
||||
index = this.indexes[id];
|
||||
if (exist < index) {
|
||||
this.indexes[id] = index + nodes.length;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Remove `child` by index or node.
|
||||
//
|
||||
// css.remove(2);
|
||||
Container.prototype.remove = function remove(child) {
|
||||
child = this.index(child);
|
||||
this.nodes[child].parent = undefined;
|
||||
this.nodes.splice(child, 1);
|
||||
|
||||
var index;
|
||||
for (var id in this.indexes) {
|
||||
index = this.indexes[id];
|
||||
if (index >= child) {
|
||||
this.indexes[id] = index - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Remove all children in node.
|
||||
//
|
||||
// css.removeAll();
|
||||
Container.prototype.removeAll = function removeAll() {
|
||||
for (var _iterator = this.nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
node.parent = undefined;
|
||||
}this.nodes = [];
|
||||
return this;
|
||||
};
|
||||
|
||||
// Recursivelly check all declarations inside node and replace
|
||||
// `regexp` by `callback`.
|
||||
//
|
||||
// css.replaceValues('black', '#000');
|
||||
//
|
||||
// Argumets `regexp` and `callback` is same as in `String#replace()`.
|
||||
//
|
||||
// You can speed up checks by `props` and `fast` options:
|
||||
//
|
||||
// css.replaceValues(/\d+rem/, { fast: 'rem', props: ['width'] },
|
||||
// function (str) {
|
||||
// return (14 * parseInt(str)) + 'px';
|
||||
// })
|
||||
Container.prototype.replaceValues = function replaceValues(regexp, opts, callback) {
|
||||
if (!callback) {
|
||||
callback = opts;
|
||||
opts = {};
|
||||
}
|
||||
|
||||
this.eachDecl(function (decl) {
|
||||
if (opts.props && opts.props.indexOf(decl.prop) == -1) return;
|
||||
if (opts.fast && decl.value.indexOf(opts.fast) == -1) return;
|
||||
|
||||
decl.value = decl.value.replace(regexp, callback);
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Return true if all nodes return true in `condition`.
|
||||
// Just shorcut for `nodes.every`.
|
||||
Container.prototype.every = function every(condition) {
|
||||
return this.nodes.every(condition);
|
||||
};
|
||||
|
||||
// Return true if one or more nodes return true in `condition`.
|
||||
// Just shorcut for `nodes.some`.
|
||||
Container.prototype.some = function some(condition) {
|
||||
return this.nodes.some(condition);
|
||||
};
|
||||
|
||||
// Return index of child
|
||||
Container.prototype.index = function index(child) {
|
||||
if (typeof child == "number") {
|
||||
return child;
|
||||
} else {
|
||||
return this.nodes.indexOf(child);
|
||||
}
|
||||
};
|
||||
|
||||
// Normalize child before insert. Copy before from `sample`.
|
||||
Container.prototype.normalize = function normalize(nodes, sample) {
|
||||
var _this = this;
|
||||
if (!Array.isArray(nodes)) {
|
||||
if (nodes.type == "root") {
|
||||
nodes = nodes.nodes;
|
||||
} else if (nodes.type) {
|
||||
nodes = [nodes];
|
||||
} else if (nodes.prop) {
|
||||
nodes = [new Declaration(nodes)];
|
||||
} else if (nodes.selector) {
|
||||
var Rule = _interopRequire(require("./rule"));
|
||||
|
||||
nodes = [new Rule(nodes)];
|
||||
} else if (nodes.name) {
|
||||
var AtRule = _interopRequire(require("./at-rule"));
|
||||
|
||||
nodes = [new AtRule(nodes)];
|
||||
} else if (nodes.text) {
|
||||
nodes = [new Comment(nodes)];
|
||||
}
|
||||
}
|
||||
|
||||
var processed = nodes.map(function (child) {
|
||||
if (child.parent) child = child.clone();
|
||||
if (typeof child.before == "undefined") {
|
||||
if (sample && typeof sample.before != "undefined") {
|
||||
child.before = sample.before.replace(/[^\s]/g, "");
|
||||
}
|
||||
}
|
||||
child.parent = _this;
|
||||
return child;
|
||||
});
|
||||
|
||||
return processed;
|
||||
};
|
||||
|
||||
_prototypeProperties(Container, null, {
|
||||
first: {
|
||||
|
||||
// Shortcut to get first child
|
||||
get: function () {
|
||||
if (!this.nodes) return undefined;
|
||||
return this.nodes[0];
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
last: {
|
||||
|
||||
// Shortcut to get first child
|
||||
get: function () {
|
||||
if (!this.nodes) return undefined;
|
||||
return this.nodes[this.nodes.length - 1];
|
||||
},
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
return Container;
|
||||
})(Node);
|
||||
|
||||
module.exports = Container;
|
||||
Generated
Vendored
+88
@@ -0,0 +1,88 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var PreviousMap = _interopRequire(require("./previous-map"));
|
||||
|
||||
var path = _interopRequire(require("path"));
|
||||
|
||||
// Error while CSS parsing
|
||||
var CssSyntaxError = (function (SyntaxError) {
|
||||
function CssSyntaxError(message, line, column, source, file) {
|
||||
_classCallCheck(this, CssSyntaxError);
|
||||
|
||||
this.reason = message;
|
||||
|
||||
this.message = file ? file : "<css input>";
|
||||
if (typeof line != "undefined" && typeof column != "undefined") {
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
this.message += ":" + line + ":" + column + ": " + message;
|
||||
} else {
|
||||
this.message += ": " + message;
|
||||
}
|
||||
|
||||
if (file) this.file = file;
|
||||
if (source) this.source = source;
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, CssSyntaxError);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(CssSyntaxError, SyntaxError);
|
||||
|
||||
// Return source of broken lines
|
||||
CssSyntaxError.prototype.highlight = function highlight(color) {
|
||||
var num = this.line - 1;
|
||||
var lines = this.source.split("\n");
|
||||
|
||||
var prev = num > 0 ? lines[num - 1] + "\n" : "";
|
||||
var broken = lines[num];
|
||||
var next = num < lines.length - 1 ? "\n" + lines[num + 1] : "";
|
||||
|
||||
var mark = "\n";
|
||||
for (var i = 0; i < this.column - 1; i++) {
|
||||
mark += " ";
|
||||
}
|
||||
|
||||
if (typeof color == "undefined" && typeof process != "undefined") {
|
||||
if (process.stdout && process.env) {
|
||||
color = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS;
|
||||
}
|
||||
}
|
||||
|
||||
if (color) {
|
||||
mark += "\u001b[1;31m^\u001b[0m";
|
||||
} else {
|
||||
mark += "^";
|
||||
}
|
||||
|
||||
return prev + broken + mark + next;
|
||||
};
|
||||
|
||||
CssSyntaxError.prototype.setMozillaProps = function setMozillaProps() {
|
||||
var sample = Error.call(this, message);
|
||||
if (sample.columnNumber) this.columnNumber = this.column;
|
||||
if (sample.description) this.description = this.message;
|
||||
if (sample.lineNumber) this.lineNumber = this.line;
|
||||
if (sample.fileName) this.fileName = this.file;
|
||||
};
|
||||
|
||||
CssSyntaxError.prototype.toString = function toString() {
|
||||
var text = this.message;
|
||||
if (this.source) text += "\n" + this.highlight();
|
||||
return this.name + ": " + text;
|
||||
};
|
||||
|
||||
return CssSyntaxError;
|
||||
})(SyntaxError);
|
||||
|
||||
module.exports = CssSyntaxError;
|
||||
|
||||
|
||||
CssSyntaxError.prototype.name = "CssSyntaxError";
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var vendor = _interopRequire(require("./vendor"));
|
||||
|
||||
var Node = _interopRequire(require("./node"));
|
||||
|
||||
// CSS declaration like “color: black” in rules
|
||||
var Declaration = (function (Node) {
|
||||
function Declaration(defaults) {
|
||||
_classCallCheck(this, Declaration);
|
||||
|
||||
this.type = "decl";
|
||||
Node.call(this, defaults);
|
||||
}
|
||||
|
||||
_inherits(Declaration, Node);
|
||||
|
||||
// Stringify declaration
|
||||
Declaration.prototype.stringify = function stringify(builder, semicolon) {
|
||||
var before = this.style("before");
|
||||
if (before) builder(before);
|
||||
|
||||
var between = this.style("between", "colon");
|
||||
var string = this.prop + between + this.stringifyRaw("value");
|
||||
|
||||
if (this.important) {
|
||||
string += this._important || " !important";
|
||||
}
|
||||
|
||||
if (semicolon) string += ";";
|
||||
builder(string, this);
|
||||
};
|
||||
|
||||
return Declaration;
|
||||
})(Node);
|
||||
|
||||
module.exports = Declaration;
|
||||
Generated
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var CssSyntaxError = _interopRequire(require("./css-syntax-error"));
|
||||
|
||||
var PreviousMap = _interopRequire(require("./previous-map"));
|
||||
|
||||
var Parser = _interopRequire(require("./parser"));
|
||||
|
||||
var path = _interopRequire(require("path"));
|
||||
|
||||
var sequence = 0;
|
||||
|
||||
var Input = (function () {
|
||||
function Input(css) {
|
||||
var opts = arguments[1] === undefined ? {} : arguments[1];
|
||||
_classCallCheck(this, Input);
|
||||
|
||||
this.css = css.toString();
|
||||
|
||||
if (this.css[0] == "" || this.css[0] == "") {
|
||||
this.css = this.css.slice(1);
|
||||
}
|
||||
|
||||
this.safe = !!opts.safe;
|
||||
|
||||
if (opts.from) this.file = path.resolve(opts.from);
|
||||
|
||||
var map = new PreviousMap(this.css, opts, this.id);
|
||||
if (map.text) {
|
||||
this.map = map;
|
||||
var file = map.consumer().file;
|
||||
if (!this.file && file) this.file = this.mapResolve(file);
|
||||
}
|
||||
|
||||
if (this.file) {
|
||||
this.from = this.file;
|
||||
} else {
|
||||
sequence += 1;
|
||||
this.id = "<input css " + sequence + ">";
|
||||
this.from = this.id;
|
||||
}
|
||||
if (this.map) this.map.file = this.from;
|
||||
}
|
||||
|
||||
// Throw syntax error from this input
|
||||
Input.prototype.error = function error(message, line, column) {
|
||||
var error = new CssSyntaxError(message);
|
||||
|
||||
var origin = this.origin(line, column);
|
||||
if (origin) {
|
||||
error = new CssSyntaxError(message, origin.line, origin.column, origin.source, origin.file);
|
||||
|
||||
error.generated = {
|
||||
line: line,
|
||||
column: column,
|
||||
source: this.css
|
||||
};
|
||||
if (this.file) error.generated.file = this.file;
|
||||
} else {
|
||||
error = new CssSyntaxError(message, line, column, this.css, this.file);
|
||||
}
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
// Get origin position of code if source map was given
|
||||
Input.prototype.origin = function origin(line, column) {
|
||||
if (!this.map) return false;
|
||||
var consumer = this.map.consumer();
|
||||
|
||||
var from = consumer.originalPositionFor({ line: line, column: column });
|
||||
if (!from.source) return false;
|
||||
|
||||
var result = {
|
||||
file: this.mapResolve(from.source),
|
||||
line: from.line,
|
||||
column: from.column
|
||||
};
|
||||
|
||||
var source = consumer.sourceContentFor(result.file);
|
||||
if (source) result.source = source;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return path relative from source map root
|
||||
Input.prototype.mapResolve = function mapResolve(file) {
|
||||
return path.resolve(this.map.consumer().sourceRoot || ".", file);
|
||||
};
|
||||
|
||||
return Input;
|
||||
})();
|
||||
|
||||
module.exports = Input;
|
||||
Generated
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
|
||||
// Methods to parse list and split it to array
|
||||
module.exports = {
|
||||
|
||||
// Split string to array by separator symbols with function and inside strings
|
||||
// cheching
|
||||
split: function (string, separators, last) {
|
||||
var array = [];
|
||||
var current = "";
|
||||
var split = false;
|
||||
|
||||
var func = 0;
|
||||
var quote = false;
|
||||
var escape = false;
|
||||
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
var letter = string[i];
|
||||
|
||||
if (quote) {
|
||||
if (escape) {
|
||||
escape = false;
|
||||
} else if (letter == "\\") {
|
||||
escape = true;
|
||||
} else if (letter == quote) {
|
||||
quote = false;
|
||||
}
|
||||
} else if (letter == "\"" || letter == "'") {
|
||||
quote = letter;
|
||||
} else if (letter == "(") {
|
||||
func += 1;
|
||||
} else if (letter == ")") {
|
||||
if (func > 0) func -= 1;
|
||||
} else if (func === 0) {
|
||||
for (var j = 0; j < separators.length; j++) {
|
||||
if (letter == separators[j]) split = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (split) {
|
||||
if (current !== "") array.push(current.trim());
|
||||
current = "";
|
||||
split = false;
|
||||
} else {
|
||||
current += letter;
|
||||
}
|
||||
}
|
||||
|
||||
if (last || current !== "") array.push(current.trim());
|
||||
return array;
|
||||
},
|
||||
|
||||
// Split list devided by space:
|
||||
//
|
||||
// list.space('a b') #=> ['a', 'b']
|
||||
//
|
||||
// It check for fuction and strings:
|
||||
//
|
||||
// list.space('calc(1px + 1em) "b c"') #=> ['calc(1px + 1em)', '"b c"']
|
||||
space: function (string) {
|
||||
return this.split(string, [" ", "\n", "\t"]);
|
||||
},
|
||||
|
||||
// Split list devided by comma
|
||||
//
|
||||
// list.comma('a, b') #=> ['a', 'b']
|
||||
//
|
||||
// It check for fuction and strings:
|
||||
//
|
||||
// list.comma('rgba(0, 0, 0, 0) white') #=> ['rgba(0, 0, 0, 0)', '"white"']
|
||||
comma: function (string) {
|
||||
return this.split(string, [","], true);
|
||||
}
|
||||
|
||||
};
|
||||
Generated
Vendored
+290
@@ -0,0 +1,290 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Result = _interopRequire(require("./result"));
|
||||
|
||||
var Base64 = require("js-base64").Base64;
|
||||
var mozilla = _interopRequire(require("source-map"));
|
||||
|
||||
var path = _interopRequire(require("path"));
|
||||
|
||||
// All tools to generate source maps
|
||||
var MapGenerator = (function () {
|
||||
function MapGenerator(root, opts) {
|
||||
_classCallCheck(this, MapGenerator);
|
||||
|
||||
this.root = root;
|
||||
this.opts = opts;
|
||||
this.mapOpts = opts.map || {};
|
||||
}
|
||||
|
||||
// Should map be generated
|
||||
MapGenerator.prototype.isMap = function isMap() {
|
||||
if (typeof this.opts.map != "undefined") {
|
||||
return !!this.opts.map;
|
||||
} else {
|
||||
return this.previous().length > 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Return source map arrays from previous compilation step (like Sass)
|
||||
MapGenerator.prototype.previous = function previous() {
|
||||
var _this = this;
|
||||
if (!this.previousMaps) {
|
||||
this.previousMaps = [];
|
||||
this.root.eachInside(function (node) {
|
||||
if (node.source && node.source.input.map) {
|
||||
var map = node.source.input.map;
|
||||
if (_this.previousMaps.indexOf(map) == -1) {
|
||||
_this.previousMaps.push(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this.previousMaps;
|
||||
};
|
||||
|
||||
// Should we inline source map to annotation comment
|
||||
MapGenerator.prototype.isInline = function isInline() {
|
||||
if (typeof this.mapOpts.inline != "undefined") {
|
||||
return this.mapOpts.inline;
|
||||
}
|
||||
|
||||
var annotation = this.mapOpts.annotation;
|
||||
if (typeof annotation != "undefined" && annotation !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.previous().length) {
|
||||
return this.previous().some(function (i) {
|
||||
return i.inline;
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Should we set sourcesContent
|
||||
MapGenerator.prototype.isSourcesContent = function isSourcesContent() {
|
||||
if (typeof this.mapOpts.sourcesContent != "undefined") {
|
||||
return this.mapOpts.sourcesContent;
|
||||
}
|
||||
if (this.previous().length) {
|
||||
return this.previous().some(function (i) {
|
||||
return i.withContent();
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Clear source map annotation comment
|
||||
MapGenerator.prototype.clearAnnotation = function clearAnnotation() {
|
||||
if (this.mapOpts.annotation === false) return;
|
||||
|
||||
var node;
|
||||
for (var i = this.root.nodes.length - 1; i >= 0; i--) {
|
||||
node = this.root.nodes[i];
|
||||
if (node.type != "comment") continue;
|
||||
if (node.text.match(/^# sourceMappingURL=/)) {
|
||||
this.root.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Set origin CSS content
|
||||
MapGenerator.prototype.setSourcesContent = function setSourcesContent() {
|
||||
var _this = this;
|
||||
var already = {};
|
||||
this.root.eachInside(function (node) {
|
||||
if (node.source) {
|
||||
var from = node.source.input.from;
|
||||
if (from && !already[from]) {
|
||||
already[from] = true;
|
||||
var relative = _this.relative(from);
|
||||
_this.map.setSourceContent(relative, node.source.input.css);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Apply source map from previous compilation step (like Sass)
|
||||
MapGenerator.prototype.applyPrevMaps = function applyPrevMaps() {
|
||||
for (var _iterator = this.previous(), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var prev = _ref;
|
||||
var from = this.relative(prev.file);
|
||||
var root = prev.root || path.dirname(prev.file);
|
||||
var map;
|
||||
|
||||
if (this.mapOpts.sourcesContent === false) {
|
||||
map = new mozilla.SourceMapConsumer(prev.text);
|
||||
map.sourcesContent = map.sourcesContent.map(function (i) {
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
map = prev.consumer();
|
||||
}
|
||||
|
||||
this.map.applySourceMap(map, from, this.relative(root));
|
||||
}
|
||||
};
|
||||
|
||||
// Should we add annotation comment
|
||||
MapGenerator.prototype.isAnnotation = function isAnnotation() {
|
||||
if (this.isInline()) {
|
||||
return true;
|
||||
} else if (typeof this.mapOpts.annotation != "undefined") {
|
||||
return this.mapOpts.annotation;
|
||||
} else if (this.previous().length) {
|
||||
return this.previous().some(function (i) {
|
||||
return i.annotation;
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Add source map annotation comment if it is needed
|
||||
MapGenerator.prototype.addAnnotation = function addAnnotation() {
|
||||
var content;
|
||||
|
||||
if (this.isInline()) {
|
||||
content = "data:application/json;base64," + Base64.encode(this.map.toString());
|
||||
} else if (typeof this.mapOpts.annotation == "string") {
|
||||
content = this.mapOpts.annotation;
|
||||
} else {
|
||||
content = this.outputFile() + ".map";
|
||||
}
|
||||
|
||||
this.css += "\n/*# sourceMappingURL=" + content + " */";
|
||||
};
|
||||
|
||||
// Return output CSS file path
|
||||
MapGenerator.prototype.outputFile = function outputFile() {
|
||||
if (this.opts.to) {
|
||||
return this.relative(this.opts.to);
|
||||
} else if (this.opts.from) {
|
||||
return this.relative(this.opts.from);
|
||||
} else {
|
||||
return "to.css";
|
||||
}
|
||||
};
|
||||
|
||||
// Return Result object with map
|
||||
MapGenerator.prototype.generateMap = function generateMap() {
|
||||
this.stringify();
|
||||
if (this.isSourcesContent()) this.setSourcesContent();
|
||||
if (this.previous().length > 0) this.applyPrevMaps();
|
||||
if (this.isAnnotation()) this.addAnnotation();
|
||||
|
||||
if (this.isInline()) {
|
||||
return [this.css];
|
||||
} else {
|
||||
return [this.css, this.map];
|
||||
}
|
||||
};
|
||||
|
||||
// Return path relative from output CSS file
|
||||
MapGenerator.prototype.relative = function relative(file) {
|
||||
var from = this.opts.to ? path.dirname(this.opts.to) : ".";
|
||||
|
||||
if (typeof this.mapOpts.annotation == "string") {
|
||||
from = path.dirname(path.resolve(from, this.mapOpts.annotation));
|
||||
}
|
||||
|
||||
file = path.relative(from, file);
|
||||
if (path.sep == "\\") {
|
||||
return file.replace(/\\/g, "/");
|
||||
} else {
|
||||
return file;
|
||||
}
|
||||
};
|
||||
|
||||
// Return path of node source for map
|
||||
MapGenerator.prototype.sourcePath = function sourcePath(node) {
|
||||
return this.relative(node.source.input.from);
|
||||
};
|
||||
|
||||
// Return CSS string and source map
|
||||
MapGenerator.prototype.stringify = function stringify() {
|
||||
var _this = this;
|
||||
this.css = "";
|
||||
this.map = new mozilla.SourceMapGenerator({ file: this.outputFile() });
|
||||
|
||||
var line = 1;
|
||||
var column = 1;
|
||||
|
||||
var lines, last;
|
||||
var builder = function (str, node, type) {
|
||||
_this.css += str;
|
||||
|
||||
if (node && node.source && node.source.start && type != "end") {
|
||||
_this.map.addMapping({
|
||||
source: _this.sourcePath(node),
|
||||
original: {
|
||||
line: node.source.start.line,
|
||||
column: node.source.start.column - 1
|
||||
},
|
||||
generated: {
|
||||
line: line,
|
||||
column: column - 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
lines = str.match(/\n/g);
|
||||
if (lines) {
|
||||
line += lines.length;
|
||||
last = str.lastIndexOf("\n");
|
||||
column = str.length - last;
|
||||
} else {
|
||||
column = column + str.length;
|
||||
}
|
||||
|
||||
if (node && node.source && node.source.end && type != "start") {
|
||||
_this.map.addMapping({
|
||||
source: _this.sourcePath(node),
|
||||
original: {
|
||||
line: node.source.end.line,
|
||||
column: node.source.end.column
|
||||
},
|
||||
generated: {
|
||||
line: line,
|
||||
column: column
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.root.stringify(builder);
|
||||
};
|
||||
|
||||
// Return Result object with or without map
|
||||
MapGenerator.prototype.generate = function generate() {
|
||||
this.clearAnnotation();
|
||||
|
||||
if (this.isMap()) {
|
||||
return this.generateMap();
|
||||
} else {
|
||||
return [this.root.toString()];
|
||||
}
|
||||
};
|
||||
|
||||
return MapGenerator;
|
||||
})();
|
||||
|
||||
module.exports = MapGenerator;
|
||||
Generated
Vendored
+462
@@ -0,0 +1,462 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var CssSyntaxError = _interopRequire(require("./css-syntax-error"));
|
||||
|
||||
// Recursivly clone objects
|
||||
var clone = function (obj, parent) {
|
||||
if (typeof obj != "object") return obj;
|
||||
var cloned = new obj.constructor();
|
||||
|
||||
for (var i in obj) {
|
||||
if (!obj.hasOwnProperty(i)) continue;
|
||||
var value = obj[i];
|
||||
|
||||
if (i == "parent" && typeof value == "object") {
|
||||
if (parent) cloned[i] = parent;
|
||||
} else if (i == "source") {
|
||||
cloned[i] = value;
|
||||
} else if (value instanceof Array) {
|
||||
cloned[i] = value.map(function (i) {
|
||||
return clone(i, cloned);
|
||||
});
|
||||
} else if (i != "before" && i != "after" && i != "between" && i != "semicolon") {
|
||||
cloned[i] = clone(value, cloned);
|
||||
}
|
||||
}
|
||||
|
||||
return cloned;
|
||||
};
|
||||
|
||||
// Some common methods for all CSS nodes
|
||||
var Node = (function () {
|
||||
function Node() {
|
||||
var defaults = arguments[0] === undefined ? {} : arguments[0];
|
||||
_classCallCheck(this, Node);
|
||||
|
||||
for (var name in defaults) {
|
||||
this[name] = defaults[name];
|
||||
}
|
||||
}
|
||||
|
||||
// Return error to mark error in your plugin syntax:
|
||||
//
|
||||
// if ( wrongVariable ) {
|
||||
// throw decl.error('Wrong variable');
|
||||
// }
|
||||
//
|
||||
// You can also get origin line and column from previous source map:
|
||||
//
|
||||
// if ( deprectedSyntax ) {
|
||||
// var error = decl.error('Deprected syntax');
|
||||
// console.warn(error.toString());
|
||||
// }
|
||||
Node.prototype.error = function error(message) {
|
||||
if (this.source) {
|
||||
var pos = this.source.start;
|
||||
return this.source.input.error(message, pos.line, pos.column);
|
||||
} else {
|
||||
return new CssSyntaxError(message);
|
||||
}
|
||||
};
|
||||
|
||||
// Remove this node from parent
|
||||
//
|
||||
// decl.removeSelf();
|
||||
//
|
||||
// Note, that removing by index is faster:
|
||||
//
|
||||
// rule.each( (decl, i) => rule.remove(i) );
|
||||
Node.prototype.removeSelf = function removeSelf() {
|
||||
if (this.parent) {
|
||||
this.parent.remove(this);
|
||||
}
|
||||
this.parent = undefined;
|
||||
return this;
|
||||
};
|
||||
|
||||
// Shortcut to insert nodes before and remove self.
|
||||
//
|
||||
// importNode.replace( loadedRoot );
|
||||
Node.prototype.replace = function replace(nodes) {
|
||||
this.parent.insertBefore(this, nodes);
|
||||
this.parent.remove(this);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Return CSS string of current node
|
||||
//
|
||||
// decl.toString(); //=> " color: black"
|
||||
Node.prototype.toString = function toString() {
|
||||
var result = "";
|
||||
var builder = function (str) {
|
||||
return result += str;
|
||||
};
|
||||
this.stringify(builder);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Clone current node
|
||||
//
|
||||
// rule.append( decl.clone() );
|
||||
//
|
||||
// You can override properties while cloning:
|
||||
//
|
||||
// rule.append( decl.clone({ value: '0' }) );
|
||||
Node.prototype.clone = (function (_clone) {
|
||||
var _cloneWrapper = function clone() {
|
||||
return _clone.apply(this, arguments);
|
||||
};
|
||||
|
||||
_cloneWrapper.toString = function () {
|
||||
return _clone.toString();
|
||||
};
|
||||
|
||||
return _cloneWrapper;
|
||||
})(function () {
|
||||
var overrides = arguments[0] === undefined ? {} : arguments[0];
|
||||
var cloned = clone(this);
|
||||
for (var name in overrides) {
|
||||
cloned[name] = overrides[name];
|
||||
}
|
||||
return cloned;
|
||||
});
|
||||
|
||||
|
||||
// Clone node and insert clone before current one.
|
||||
// It accept properties to change in clone and return new node.
|
||||
//
|
||||
// decl.cloneBefore({ prop: '-webkit-' + del.prop });
|
||||
Node.prototype.cloneBefore = function cloneBefore() {
|
||||
var overrides = arguments[0] === undefined ? {} : arguments[0];
|
||||
var cloned = this.clone(overrides);
|
||||
this.parent.insertBefore(this, cloned);
|
||||
return cloned;
|
||||
};
|
||||
|
||||
// Clone node and insert clone after current one.
|
||||
// It accept properties to change in clone and return new node.
|
||||
//
|
||||
// decl.cloneAfter({ value: convertToRem(decl.value) });
|
||||
Node.prototype.cloneAfter = function cloneAfter() {
|
||||
var overrides = arguments[0] === undefined ? {} : arguments[0];
|
||||
var cloned = this.clone(overrides);
|
||||
this.parent.insertAfter(this, cloned);
|
||||
return cloned;
|
||||
};
|
||||
|
||||
// Replace with node by another one.
|
||||
//
|
||||
// decl.replaceWith(fixedDecl);
|
||||
Node.prototype.replaceWith = function replaceWith(node) {
|
||||
this.parent.insertBefore(this, node);
|
||||
this.removeSelf();
|
||||
return this;
|
||||
};
|
||||
|
||||
// Remove node from current place and put to end of new one.
|
||||
// It will also clean node code styles, but will keep `between` if old
|
||||
// parent and new parent has same root.
|
||||
//
|
||||
// rule.moveTo(atRule);
|
||||
Node.prototype.moveTo = function moveTo(container) {
|
||||
this.cleanStyles(this.root() == container.root());
|
||||
this.removeSelf();
|
||||
container.append(this);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Remove node from current place and put to before other node.
|
||||
// It will also clean node code styles, but will keep `between` if old
|
||||
// parent and new parent has same root.
|
||||
//
|
||||
// rule.moveBefore(rule.parent);
|
||||
Node.prototype.moveBefore = function moveBefore(node) {
|
||||
this.cleanStyles(this.root() == node.root());
|
||||
this.removeSelf();
|
||||
node.parent.insertBefore(node, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Remove node from current place and put to after other node.
|
||||
// It will also clean node code styles, but will keep `between` if old
|
||||
// parent and new parent has same root.
|
||||
//
|
||||
// rule.moveAfter(rule.parent);
|
||||
Node.prototype.moveAfter = function moveAfter(node) {
|
||||
this.cleanStyles(this.root() == node.root());
|
||||
this.removeSelf();
|
||||
node.parent.insertAfter(node, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Return next node in parent. If current node is last one,
|
||||
// method will return `undefined`.
|
||||
//
|
||||
// var next = decl.next();
|
||||
// if ( next && next.prop == removePrefix(decl.prop) ) {
|
||||
// decl.removeSelf();
|
||||
// }
|
||||
Node.prototype.next = function next() {
|
||||
var index = this.parent.index(this);
|
||||
return this.parent.nodes[index + 1];
|
||||
};
|
||||
|
||||
// Return previous node in parent. If current node is first one,
|
||||
// method will return `undefined`.
|
||||
//
|
||||
// var prev = decl.prev();
|
||||
// if ( prev && removePrefix(prev.prop) == decl.prop) ) {
|
||||
// prev.removeSelf();
|
||||
// }
|
||||
Node.prototype.prev = function prev() {
|
||||
var index = this.parent.index(this);
|
||||
return this.parent.nodes[index - 1];
|
||||
};
|
||||
|
||||
// Remove `parent` node on cloning to fix circular structures
|
||||
Node.prototype.toJSON = function toJSON() {
|
||||
var fixed = {};
|
||||
|
||||
for (var name in this) {
|
||||
if (!this.hasOwnProperty(name)) continue;
|
||||
if (name == "parent") continue;
|
||||
var value = this[name];
|
||||
|
||||
if (value instanceof Array) {
|
||||
fixed[name] = value.map(function (i) {
|
||||
return typeof i == "object" && i.toJSON ? i.toJSON() : i;
|
||||
});
|
||||
} else if (typeof value == "object" && value.toJSON) {
|
||||
fixed[name] = value.toJSON();
|
||||
} else {
|
||||
fixed[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return fixed;
|
||||
};
|
||||
|
||||
// Copy code style from first node with same type
|
||||
Node.prototype.style = function style(own, detect) {
|
||||
var value;
|
||||
if (!detect) detect = own;
|
||||
|
||||
// Already had
|
||||
if (own) {
|
||||
value = this[own];
|
||||
if (typeof value != "undefined") return value;
|
||||
}
|
||||
|
||||
var parent = this.parent;
|
||||
|
||||
// Hack for first rule in CSS
|
||||
if (detect == "before") {
|
||||
if (!parent || parent.type == "root" && parent.first == this) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// Floating child without parent
|
||||
if (!parent) return this.defaultStyle[detect];
|
||||
|
||||
// Detect style by other nodes
|
||||
var root = this.root();
|
||||
if (!root.styleCache) root.styleCache = {};
|
||||
if (typeof root.styleCache[detect] != "undefined") {
|
||||
return root.styleCache[detect];
|
||||
}
|
||||
|
||||
if (detect == "semicolon") {
|
||||
root.eachInside(function (i) {
|
||||
if (i.nodes && i.nodes.length && i.last.type == "decl") {
|
||||
value = i.semicolon;
|
||||
if (typeof value != "undefined") return false;
|
||||
}
|
||||
});
|
||||
} else if (detect == "emptyBody") {
|
||||
root.eachInside(function (i) {
|
||||
if (i.nodes && i.nodes.length === 0) {
|
||||
value = i.after;
|
||||
if (typeof value != "undefined") return false;
|
||||
}
|
||||
});
|
||||
} else if (detect == "indent") {
|
||||
root.eachInside(function (i) {
|
||||
var p = i.parent;
|
||||
if (p && p != root && p.parent && p.parent == root) {
|
||||
if (typeof i.before != "undefined") {
|
||||
var parts = i.before.split("\n");
|
||||
value = parts[parts.length - 1];
|
||||
value = value.replace(/[^\s]/g, "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (detect == "beforeComment") {
|
||||
root.eachComment(function (i) {
|
||||
if (typeof i.before != "undefined") {
|
||||
value = i.before;
|
||||
if (value.indexOf("\n") != -1) {
|
||||
value = value.replace(/[^\n]+$/, "");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (typeof value == "undefined") {
|
||||
value = this.style(null, "beforeDecl");
|
||||
}
|
||||
} else if (detect == "beforeDecl") {
|
||||
root.eachDecl(function (i) {
|
||||
if (typeof i.before != "undefined") {
|
||||
value = i.before;
|
||||
if (value.indexOf("\n") != -1) {
|
||||
value = value.replace(/[^\n]+$/, "");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (typeof value == "undefined") {
|
||||
value = this.style(null, "beforeRule");
|
||||
}
|
||||
} else if (detect == "beforeRule") {
|
||||
root.eachInside(function (i) {
|
||||
if (i.nodes && (i.parent != root || root.first != i)) {
|
||||
if (typeof i.before != "undefined") {
|
||||
value = i.before;
|
||||
if (value.indexOf("\n") != -1) {
|
||||
value = value.replace(/[^\n]+$/, "");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (detect == "beforeClose") {
|
||||
root.eachInside(function (i) {
|
||||
if (i.nodes && i.nodes.length > 0) {
|
||||
if (typeof i.after != "undefined") {
|
||||
value = i.after;
|
||||
if (value.indexOf("\n") != -1) {
|
||||
value = value.replace(/[^\n]+$/, "");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (detect == "before" || detect == "after") {
|
||||
if (this.type == "decl") {
|
||||
value = this.style(null, "beforeDecl");
|
||||
} else if (this.type == "comment") {
|
||||
value = this.style(null, "beforeComment");
|
||||
} else if (detect == "before") {
|
||||
value = this.style(null, "beforeRule");
|
||||
} else {
|
||||
value = this.style(null, "beforeClose");
|
||||
}
|
||||
|
||||
var node = this.parent;
|
||||
var depth = 0;
|
||||
while (node && node.type != "root") {
|
||||
depth += 1;
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
if (value.indexOf("\n") != -1) {
|
||||
var indent = this.style(null, "indent");
|
||||
if (indent.length) {
|
||||
for (var step = 0; step < depth; step++) value += indent;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
} else if (detect == "colon") {
|
||||
root.eachDecl(function (i) {
|
||||
if (typeof i.between != "undefined") {
|
||||
value = i.between.replace(/[^\s:]/g, "");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else if (detect == "beforeOpen") {
|
||||
root.eachInside(function (i) {
|
||||
if (i.type != "decl") {
|
||||
value = i.between;
|
||||
if (typeof value != "undefined") return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
root.eachInside(function (i) {
|
||||
value = i[own];
|
||||
if (typeof value != "undefined") return false;
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof value == "undefined") value = this.defaultStyle[detect];
|
||||
|
||||
root.styleCache[detect] = value;
|
||||
return value;
|
||||
};
|
||||
|
||||
// Return top parent , parent of parents.
|
||||
Node.prototype.root = function root() {
|
||||
var result = this;
|
||||
while (result.parent) result = result.parent;
|
||||
return result;
|
||||
};
|
||||
|
||||
// Recursivelly remove all code style properties (`before` and `between`).
|
||||
Node.prototype.cleanStyles = function cleanStyles(keepBetween) {
|
||||
delete this.before;
|
||||
delete this.after;
|
||||
if (!keepBetween) delete this.between;
|
||||
|
||||
if (this.nodes) {
|
||||
for (var _iterator = this.nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
node.cleanStyles(keepBetween);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Use raw value if origin was not changed
|
||||
Node.prototype.stringifyRaw = function stringifyRaw(prop) {
|
||||
var value = this[prop];
|
||||
var raw = this["_" + prop];
|
||||
if (raw && raw.value === value) {
|
||||
return raw.raw;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
return Node;
|
||||
})();
|
||||
|
||||
module.exports = Node;
|
||||
|
||||
|
||||
// Default code style
|
||||
Node.prototype.defaultStyle = {
|
||||
colon: ": ",
|
||||
indent: " ",
|
||||
beforeDecl: "\n",
|
||||
beforeRule: "\n",
|
||||
beforeOpen: " ",
|
||||
beforeClose: "\n",
|
||||
beforeComment: "\n",
|
||||
after: "\n",
|
||||
emptyBody: "",
|
||||
commentLeft: " ",
|
||||
commentRight: " "
|
||||
};
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var Parser = _interopRequire(require("./parser"));
|
||||
|
||||
var Input = _interopRequire(require("./input"));
|
||||
|
||||
module.exports = function (css, opts) {
|
||||
var input = new Input(css, opts);
|
||||
|
||||
var parser = new Parser(input);
|
||||
parser.tokenize();
|
||||
parser.loop();
|
||||
|
||||
return parser.root;
|
||||
};
|
||||
Generated
Vendored
+501
@@ -0,0 +1,501 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Declaration = _interopRequire(require("./declaration"));
|
||||
|
||||
var tokenize = _interopRequire(require("./tokenize"));
|
||||
|
||||
var Comment = _interopRequire(require("./comment"));
|
||||
|
||||
var AtRule = _interopRequire(require("./at-rule"));
|
||||
|
||||
var Root = _interopRequire(require("./root"));
|
||||
|
||||
var Rule = _interopRequire(require("./rule"));
|
||||
|
||||
// CSS parser
|
||||
var Parser = (function () {
|
||||
function Parser(input) {
|
||||
_classCallCheck(this, Parser);
|
||||
|
||||
this.input = input;
|
||||
|
||||
this.pos = 0;
|
||||
this.root = new Root();
|
||||
this.current = this.root;
|
||||
this.spaces = "";
|
||||
this.semicolon = false;
|
||||
|
||||
this.root.source = { input: input };
|
||||
if (input.map) this.root.prevMap = input.map;
|
||||
}
|
||||
|
||||
Parser.prototype.tokenize = (function (_tokenize) {
|
||||
var _tokenizeWrapper = function tokenize() {
|
||||
return _tokenize.apply(this, arguments);
|
||||
};
|
||||
|
||||
_tokenizeWrapper.toString = function () {
|
||||
return _tokenize.toString();
|
||||
};
|
||||
|
||||
return _tokenizeWrapper;
|
||||
})(function () {
|
||||
this.tokens = tokenize(this.input);
|
||||
});
|
||||
Parser.prototype.loop = function loop() {
|
||||
var token;
|
||||
while (this.pos < this.tokens.length) {
|
||||
token = this.tokens[this.pos];
|
||||
|
||||
switch (token[0]) {
|
||||
case "word":
|
||||
case ":":
|
||||
this.word(token);
|
||||
break;
|
||||
|
||||
case "}":
|
||||
this.end(token);
|
||||
break;
|
||||
|
||||
case "comment":
|
||||
this.comment(token);
|
||||
break;
|
||||
|
||||
case "at-word":
|
||||
this.atrule(token);
|
||||
break;
|
||||
|
||||
case "{":
|
||||
this.emptyRule(token);
|
||||
break;
|
||||
|
||||
default:
|
||||
this.spaces += token[1];
|
||||
break;
|
||||
}
|
||||
|
||||
this.pos += 1;
|
||||
}
|
||||
this.endFile();
|
||||
};
|
||||
|
||||
Parser.prototype.comment = function comment(token) {
|
||||
var node = new Comment();
|
||||
this.init(node, token[2], token[3]);
|
||||
node.source.end = { line: token[4], column: token[5] };
|
||||
|
||||
var text = token[1].slice(2, -2);
|
||||
if (text.match(/^\s*$/)) {
|
||||
node.left = text;
|
||||
node.text = "";
|
||||
node.right = "";
|
||||
} else {
|
||||
var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/);
|
||||
node.left = match[1];
|
||||
node.text = match[2];
|
||||
node.right = match[3];
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.emptyRule = function emptyRule(token) {
|
||||
var node = new Rule();
|
||||
this.init(node, token[2], token[3]);
|
||||
node.between = "";
|
||||
node.selector = "";
|
||||
this.current = node;
|
||||
};
|
||||
|
||||
Parser.prototype.word = function word() {
|
||||
var token;
|
||||
var end = false;
|
||||
var type = null;
|
||||
var colon = false;
|
||||
var bracket = null;
|
||||
var brackets = 0;
|
||||
|
||||
var start = this.pos;
|
||||
this.pos += 1;
|
||||
while (true) {
|
||||
token = this.tokens[this.pos];
|
||||
if (!token) {
|
||||
this.pos -= 1;
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
|
||||
type = token[0];
|
||||
if (type == "(") {
|
||||
if (!bracket) bracket = token;
|
||||
brackets += 1;
|
||||
} else if (type == ")") {
|
||||
brackets -= 1;
|
||||
if (brackets === 0) bracket = null;
|
||||
} else if (brackets === 0) {
|
||||
if (type == ";") {
|
||||
if (colon) {
|
||||
this.decl(this.tokens.slice(start, this.pos + 1));
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (type == "{") {
|
||||
this.rule(this.tokens.slice(start, this.pos + 1));
|
||||
return;
|
||||
} else if (type == "}") {
|
||||
this.pos -= 1;
|
||||
end = true;
|
||||
break;
|
||||
} else if (type == "at-word") {
|
||||
this.pos -= 1;
|
||||
break;
|
||||
} else {
|
||||
if (type == ":") colon = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.pos += 1;
|
||||
}
|
||||
|
||||
if (brackets > 0 && !this.input.safe) {
|
||||
throw this.input.error("Unclosed bracket", bracket[2], bracket[3]);
|
||||
}
|
||||
|
||||
if (end && colon) {
|
||||
while (this.pos > start) {
|
||||
token = this.tokens[this.pos][0];
|
||||
if (token != "space" && token != "comment") break;
|
||||
this.pos -= 1;
|
||||
}
|
||||
this.decl(this.tokens.slice(start, this.pos + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.input.safe) {
|
||||
var buffer = this.tokens.slice(start, this.pos + 1);
|
||||
this.spaces += buffer.map(function (i) {
|
||||
return i[1];
|
||||
}).join("");
|
||||
} else {
|
||||
token = this.tokens[start];
|
||||
throw this.input.error("Unknown word", token[2], token[3]);
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.rule = function rule(tokens) {
|
||||
tokens.pop();
|
||||
|
||||
var node = new Rule();
|
||||
this.init(node, tokens[0][2], tokens[0][3]);
|
||||
|
||||
node.between = this.spacesFromEnd(tokens);
|
||||
this.raw(node, "selector", tokens);
|
||||
this.current = node;
|
||||
};
|
||||
|
||||
Parser.prototype.decl = function decl(tokens) {
|
||||
var node = new Declaration();
|
||||
this.init(node);
|
||||
|
||||
var last = tokens[tokens.length - 1];
|
||||
if (last[0] == ";") {
|
||||
this.semicolon = true;
|
||||
tokens.pop();
|
||||
}
|
||||
if (last[4]) {
|
||||
node.source.end = { line: last[4], column: last[5] };
|
||||
} else {
|
||||
node.source.end = { line: last[2], column: last[3] };
|
||||
}
|
||||
|
||||
while (tokens[0][0] != "word") {
|
||||
node.before += tokens.shift()[1];
|
||||
}
|
||||
node.source.start = { line: tokens[0][2], column: tokens[0][3] };
|
||||
|
||||
node.prop = tokens.shift()[1];
|
||||
node.between = "";
|
||||
|
||||
var token;
|
||||
while (tokens.length) {
|
||||
token = tokens.shift();
|
||||
|
||||
if (token[0] == ":") {
|
||||
node.between += token[1];
|
||||
break;
|
||||
} else if (token[0] != "space" && token[0] != "comment") {
|
||||
this.unknownWord(node, token, tokens);
|
||||
} else {
|
||||
node.between += token[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (node.prop[0] == "_" || node.prop[0] == "*") {
|
||||
node.before += node.prop[0];
|
||||
node.prop = node.prop.slice(1);
|
||||
}
|
||||
node.between += this.spacesFromStart(tokens);
|
||||
|
||||
if (this.input.safe) this.checkMissedSemicolon(tokens);
|
||||
|
||||
for (var i = tokens.length - 1; i > 0; i--) {
|
||||
token = tokens[i];
|
||||
if (token[1] == "!important") {
|
||||
node.important = true;
|
||||
var string = this.stringFrom(tokens, i);
|
||||
string = this.spacesFromEnd(tokens) + string;
|
||||
if (string != " !important") node._important = string;
|
||||
break;
|
||||
} else if (token[0] != "space" && token[0] != "comment") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.raw(node, "value", tokens);
|
||||
|
||||
if (node.value.indexOf(":") != -1 && !this.input.safe) {
|
||||
this.checkMissedSemicolon(tokens);
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.atrule = function atrule(token) {
|
||||
var node = new AtRule();
|
||||
node.name = token[1].slice(1);
|
||||
if (node.name === "") {
|
||||
if (this.input.safe) {
|
||||
node.name = "";
|
||||
} else {
|
||||
throw this.input.error("At-rule without name", token[2], token[3]);
|
||||
}
|
||||
}
|
||||
this.init(node, token[2], token[3]);
|
||||
|
||||
var next;
|
||||
var last = false;
|
||||
var open = false;
|
||||
var params = [];
|
||||
while (true) {
|
||||
this.pos += 1;
|
||||
token = this.tokens[this.pos];
|
||||
|
||||
if (!token) {
|
||||
last = true;
|
||||
break;
|
||||
} else if (token[0] == ";") {
|
||||
node.source.end = { line: token[2], column: token[3] };
|
||||
this.semicolon = true;
|
||||
break;
|
||||
} else if (token[0] == "{") {
|
||||
open = true;
|
||||
break;
|
||||
} else {
|
||||
params.push(token);
|
||||
}
|
||||
}
|
||||
|
||||
node.between = this.spacesFromEnd(params);
|
||||
if (params.length) {
|
||||
node.afterName = this.spacesFromStart(params);
|
||||
this.raw(node, "params", params);
|
||||
if (last) {
|
||||
token = params[params.length - 1];
|
||||
node.source.end = { line: token[4], column: token[5] };
|
||||
this.spaces = node.between;
|
||||
node.between = "";
|
||||
}
|
||||
} else {
|
||||
node.afterName = "";
|
||||
node.params = "";
|
||||
}
|
||||
|
||||
if (open) {
|
||||
node.nodes = [];
|
||||
this.current = node;
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.end = function end(token) {
|
||||
if (this.current.nodes && this.current.nodes.length) {
|
||||
this.current.semicolon = this.semicolon;
|
||||
}
|
||||
this.semicolon = false;
|
||||
|
||||
this.current.after = (this.current.after || "") + this.spaces;
|
||||
this.spaces = "";
|
||||
|
||||
if (this.current.parent) {
|
||||
this.current.source.end = { line: token[2], column: token[3] };
|
||||
this.current = this.current.parent;
|
||||
} else if (!this.input.safe) {
|
||||
throw this.input.error("Unexpected }", token[2], token[3]);
|
||||
} else {
|
||||
this.current.after += "}";
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.endFile = function endFile() {
|
||||
if (this.current.parent && !this.input.safe) {
|
||||
var pos = this.current.source.start;
|
||||
throw this.input.error("Unclosed block", pos.line, pos.column);
|
||||
}
|
||||
|
||||
if (this.current.nodes && this.current.nodes.length) {
|
||||
this.current.semicolon = this.semicolon;
|
||||
}
|
||||
this.current.after = (this.current.after || "") + this.spaces;
|
||||
|
||||
while (this.current.parent) {
|
||||
this.current = this.current.parent;
|
||||
this.current.after = "";
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.unknownWord = function unknownWord(node, token) {
|
||||
if (this.input.safe) {
|
||||
node.source.start = { line: token[2], column: token[3] };
|
||||
node.before += node.prop + node.between;
|
||||
node.prop = token[1];
|
||||
node.between = "";
|
||||
} else {
|
||||
throw this.input.error("Unknown word", token[2], token[3]);
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.checkMissedSemicolon = function checkMissedSemicolon(tokens) {
|
||||
var prev = null;
|
||||
var colon = false;
|
||||
var brackets = 0;
|
||||
var type, token;
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
token = tokens[i];
|
||||
type = token[0];
|
||||
|
||||
if (type == "(") {
|
||||
brackets += 1;
|
||||
} else if (type == ")") {
|
||||
brackets -= 0;
|
||||
} else if (brackets === 0 && type == ":") {
|
||||
if (prev[0] == "word" && prev[1] == "progid") {
|
||||
continue;
|
||||
} else {
|
||||
colon = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prev = token;
|
||||
}
|
||||
|
||||
if (colon === false) return;
|
||||
|
||||
if (this.input.safe) {
|
||||
var split;
|
||||
for (split = colon - 1; split >= 0; split--) {
|
||||
if (tokens[split][0] == "word") break;
|
||||
}
|
||||
for (split -= 1; split >= 0; split--) {
|
||||
if (tokens[split][0] != "space") {
|
||||
split += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var other = tokens.splice(split, tokens.length - split);
|
||||
this.decl(other);
|
||||
} else {
|
||||
var founded = 0;
|
||||
for (var j = colon - 1; j >= 0; j--) {
|
||||
token = tokens[j];
|
||||
if (token[0] != "space") {
|
||||
founded += 1;
|
||||
if (founded == 2) break;
|
||||
}
|
||||
}
|
||||
throw this.input.error("Missed semicolon", token[4], token[5]);
|
||||
}
|
||||
};
|
||||
|
||||
// Helpers
|
||||
|
||||
Parser.prototype.init = function init(node, line, column) {
|
||||
this.current.push(node);
|
||||
|
||||
node.source = { start: { line: line, column: column }, input: this.input };
|
||||
node.before = this.spaces;
|
||||
this.spaces = "";
|
||||
if (node.type != "comment") this.semicolon = false;
|
||||
};
|
||||
|
||||
Parser.prototype.raw = function raw(node, prop, tokens) {
|
||||
var token;
|
||||
var value = "";
|
||||
var clean = true;
|
||||
for (var _iterator = tokens, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
token = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
token = _i.value;
|
||||
}
|
||||
if (token[0] == "comment") {
|
||||
clean = false;
|
||||
} else {
|
||||
value += token[1];
|
||||
}
|
||||
}
|
||||
if (!clean) {
|
||||
var origin = "";
|
||||
for (var _iterator2 = tokens, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
||||
if (_isArray2) {
|
||||
if (_i2 >= _iterator2.length) break;
|
||||
token = _iterator2[_i2++];
|
||||
} else {
|
||||
_i2 = _iterator2.next();
|
||||
if (_i2.done) break;
|
||||
token = _i2.value;
|
||||
}
|
||||
origin += token[1];
|
||||
}node["_" + prop] = { value: value, raw: origin };
|
||||
}
|
||||
node[prop] = value;
|
||||
};
|
||||
|
||||
Parser.prototype.spacesFromEnd = function spacesFromEnd(tokens) {
|
||||
var next;
|
||||
var spaces = "";
|
||||
while (tokens.length) {
|
||||
next = tokens[tokens.length - 1][0];
|
||||
if (next != "space" && next != "comment") break;
|
||||
spaces += tokens.pop()[1];
|
||||
}
|
||||
return spaces;
|
||||
};
|
||||
|
||||
Parser.prototype.spacesFromStart = function spacesFromStart(tokens) {
|
||||
var next;
|
||||
var spaces = "";
|
||||
while (tokens.length) {
|
||||
next = tokens[0][0];
|
||||
if (next != "space" && next != "comment") break;
|
||||
spaces += tokens.shift()[1];
|
||||
}
|
||||
return spaces;
|
||||
};
|
||||
|
||||
Parser.prototype.stringFrom = function stringFrom(tokens, from) {
|
||||
var result = "";
|
||||
for (var i = from; i < tokens.length; i++) {
|
||||
result += tokens[i][1];
|
||||
}
|
||||
tokens.splice(from, tokens.length - from);
|
||||
return result;
|
||||
};
|
||||
|
||||
return Parser;
|
||||
})();
|
||||
|
||||
module.exports = Parser;
|
||||
Generated
Vendored
+127
@@ -0,0 +1,127 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Declaration = _interopRequire(require("./declaration"));
|
||||
|
||||
var Comment = _interopRequire(require("./comment"));
|
||||
|
||||
var AtRule = _interopRequire(require("./at-rule"));
|
||||
|
||||
var Result = _interopRequire(require("./result"));
|
||||
|
||||
var parse = _interopRequire(require("./parse"));
|
||||
|
||||
var Rule = _interopRequire(require("./rule"));
|
||||
|
||||
var Root = _interopRequire(require("./root"));
|
||||
|
||||
// List of functions to process CSS
|
||||
var PostCSS = (function () {
|
||||
function PostCSS() {
|
||||
var _this = this;
|
||||
var plugins = arguments[0] === undefined ? [] : arguments[0];
|
||||
_classCallCheck(this, PostCSS);
|
||||
|
||||
this.plugins = plugins.map(function (i) {
|
||||
return _this.normalize(i);
|
||||
});
|
||||
}
|
||||
|
||||
// Add function as PostCSS plugins
|
||||
PostCSS.prototype.use = function use(plugin) {
|
||||
plugin = this.normalize(plugin);
|
||||
if (typeof plugin == "object" && Array.isArray(plugin.plugins)) {
|
||||
this.plugins = this.plugins.concat(plugin.plugins);
|
||||
} else {
|
||||
this.plugins.push(plugin);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
// Process CSS throw installed plugins
|
||||
PostCSS.prototype.process = function process(css) {
|
||||
var opts = arguments[1] === undefined ? {} : arguments[1];
|
||||
var parsed;
|
||||
if (css instanceof Root) {
|
||||
parsed = css;
|
||||
} else if (css instanceof Result) {
|
||||
parsed = css.root;
|
||||
if (css.map && typeof opts.map == "undefined") {
|
||||
opts.map = { prev: css.map };
|
||||
}
|
||||
} else {
|
||||
parsed = postcss.parse(css, opts);
|
||||
}
|
||||
|
||||
for (var _iterator = this.plugins, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var plugin = _ref;
|
||||
var returned = plugin(parsed, opts);
|
||||
if (returned instanceof Root) parsed = returned;
|
||||
}
|
||||
|
||||
return parsed.toResult(opts);
|
||||
};
|
||||
|
||||
// Return plugin function
|
||||
PostCSS.prototype.normalize = function normalize(plugin) {
|
||||
var type = typeof plugin;
|
||||
if ((type == "object" || type == "function") && plugin.postcss) {
|
||||
return plugin.postcss;
|
||||
} else {
|
||||
return plugin;
|
||||
}
|
||||
};
|
||||
|
||||
return PostCSS;
|
||||
})();
|
||||
|
||||
// Framework for CSS postprocessors
|
||||
//
|
||||
// var processor = postcss(function (css) {
|
||||
// // Change nodes in css
|
||||
// });
|
||||
// processor.process(css)
|
||||
var postcss = function () {
|
||||
for (var _len = arguments.length, plugins = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
plugins[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
if (plugins.length == 1 && Array.isArray(plugins[0])) {
|
||||
plugins = plugins[0];
|
||||
}
|
||||
return new PostCSS(plugins);
|
||||
};
|
||||
|
||||
// Compile CSS to nodes
|
||||
postcss.parse = parse;
|
||||
|
||||
// Nodes shortcuts
|
||||
postcss.comment = function (defaults) {
|
||||
return new Comment(defaults);
|
||||
};
|
||||
postcss.atRule = function (defaults) {
|
||||
return new AtRule(defaults);
|
||||
};
|
||||
postcss.decl = function (defaults) {
|
||||
return new Declaration(defaults);
|
||||
};
|
||||
postcss.rule = function (defaults) {
|
||||
return new Rule(defaults);
|
||||
};
|
||||
postcss.root = function (defaults) {
|
||||
return new Root(defaults);
|
||||
};
|
||||
|
||||
module.exports = postcss;
|
||||
Generated
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Base64 = require("js-base64").Base64;
|
||||
var mozilla = _interopRequire(require("source-map"));
|
||||
|
||||
var path = _interopRequire(require("path"));
|
||||
|
||||
var fs = _interopRequire(require("fs"));
|
||||
|
||||
// Detect previous map
|
||||
var PreviousMap = (function () {
|
||||
function PreviousMap(css, opts) {
|
||||
_classCallCheck(this, PreviousMap);
|
||||
|
||||
this.loadAnnotation(css);
|
||||
this.inline = this.startWith(this.annotation, "data:");
|
||||
|
||||
var text = this.loadMap(opts.from, opts.map ? opts.map.prev : undefined);
|
||||
if (text) this.text = text;
|
||||
}
|
||||
|
||||
// Return SourceMapConsumer object to read map
|
||||
PreviousMap.prototype.consumer = function consumer() {
|
||||
if (!this.consumerCache) {
|
||||
this.consumerCache = new mozilla.SourceMapConsumer(this.text);
|
||||
}
|
||||
return this.consumerCache;
|
||||
};
|
||||
|
||||
// Is map has sources content
|
||||
PreviousMap.prototype.withContent = function withContent() {
|
||||
return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0);
|
||||
};
|
||||
|
||||
// Is `string` is starting with `start`
|
||||
PreviousMap.prototype.startWith = function startWith(string, start) {
|
||||
if (!string) return false;
|
||||
return string.substr(0, start.length) == start;
|
||||
};
|
||||
|
||||
// Load for annotation comment from previous compilation step
|
||||
PreviousMap.prototype.loadAnnotation = function loadAnnotation(css) {
|
||||
var match = css.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//);
|
||||
if (match) this.annotation = match[1].trim();
|
||||
};
|
||||
|
||||
// Encode different type of inline
|
||||
PreviousMap.prototype.decodeInline = function decodeInline(text) {
|
||||
var uri = "data:application/json,";
|
||||
var base64 = "data:application/json;base64,";
|
||||
|
||||
if (this.startWith(text, uri)) {
|
||||
return decodeURIComponent(text.substr(uri.length));
|
||||
} else if (this.startWith(text, base64)) {
|
||||
return Base64.decode(text.substr(base64.length));
|
||||
} else {
|
||||
var encoding = text.match(/data:application\/json;([^,]+),/)[1];
|
||||
throw new Error("Unsupported source map encoding " + encoding);
|
||||
}
|
||||
};
|
||||
|
||||
// Load previous map
|
||||
PreviousMap.prototype.loadMap = function loadMap(file, prev) {
|
||||
if (prev === false) return;
|
||||
|
||||
if (prev) {
|
||||
if (typeof prev == "string") {
|
||||
return prev;
|
||||
} else if (prev instanceof mozilla.SourceMapConsumer) {
|
||||
return mozilla.SourceMapGenerator.fromSourceMap(prev).toString();
|
||||
} else if (prev instanceof mozilla.SourceMapGenerator) {
|
||||
return prev.toString();
|
||||
} else if (typeof prev == "object" && prev.mappings) {
|
||||
return JSON.stringify(prev);
|
||||
} else {
|
||||
throw new Error("Unsupported previous source map format: " + prev.toString());
|
||||
}
|
||||
} else if (this.inline) {
|
||||
return this.decodeInline(this.annotation);
|
||||
} else if (this.annotation) {
|
||||
var map = this.annotation;
|
||||
if (file) map = path.join(path.dirname(file), map);
|
||||
|
||||
this.root = path.dirname(map);
|
||||
if (fs.existsSync && fs.existsSync(map)) {
|
||||
return fs.readFileSync(map, "utf-8").toString().trim();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return PreviousMap;
|
||||
})();
|
||||
|
||||
module.exports = PreviousMap;
|
||||
Generated
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var MapGenerator = _interopRequire(require("./map-generator"));
|
||||
|
||||
// Object with processed CSS
|
||||
var Result = (function () {
|
||||
function Result(root) {
|
||||
var opts = arguments[1] === undefined ? {} : arguments[1];
|
||||
_classCallCheck(this, Result);
|
||||
|
||||
this.root = root;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
// Return CSS string on any try to print
|
||||
Result.prototype.toString = function toString() {
|
||||
return this.css;
|
||||
};
|
||||
|
||||
// Generate CSS and map
|
||||
Result.prototype.stringify = function stringify() {
|
||||
var map = new MapGenerator(this.root, this.opts);
|
||||
var generated = map.generate();
|
||||
this.cssCached = generated[0];
|
||||
this.mapCached = generated[1];
|
||||
};
|
||||
|
||||
_prototypeProperties(Result, null, {
|
||||
map: {
|
||||
|
||||
// Lazy method to return source map
|
||||
get: function () {
|
||||
if (!this.cssCached) this.stringify();
|
||||
return this.mapCached;
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
css: {
|
||||
|
||||
// Lazy method to return CSS string
|
||||
get: function () {
|
||||
if (!this.cssCached) this.stringify();
|
||||
return this.cssCached;
|
||||
},
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
return Result;
|
||||
})();
|
||||
|
||||
module.exports = Result;
|
||||
Generated
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Declaration = _interopRequire(require("./declaration"));
|
||||
|
||||
var Container = _interopRequire(require("./container"));
|
||||
|
||||
var Comment = _interopRequire(require("./comment"));
|
||||
|
||||
var AtRule = _interopRequire(require("./at-rule"));
|
||||
|
||||
var Result = _interopRequire(require("./result"));
|
||||
|
||||
var Rule = _interopRequire(require("./rule"));
|
||||
|
||||
// Root of CSS
|
||||
var Root = (function (Container) {
|
||||
function Root(defaults) {
|
||||
_classCallCheck(this, Root);
|
||||
|
||||
this.type = "root";
|
||||
this.nodes = [];
|
||||
Container.call(this, defaults);
|
||||
}
|
||||
|
||||
_inherits(Root, Container);
|
||||
|
||||
// Fix space when we remove first child
|
||||
Root.prototype.remove = function remove(child) {
|
||||
child = this.index(child);
|
||||
|
||||
if (child === 0 && this.nodes.length > 1) {
|
||||
this.nodes[1].before = this.nodes[child].before;
|
||||
}
|
||||
|
||||
return Container.prototype.remove.call(this, child);
|
||||
};
|
||||
|
||||
// Fix spaces on insert before first rule
|
||||
Root.prototype.normalize = function normalize(child, sample, type) {
|
||||
var nodes = Container.prototype.normalize.call(this, child);
|
||||
|
||||
if (sample) {
|
||||
if (type == "prepend") {
|
||||
if (this.nodes.length > 1) {
|
||||
sample.before = this.nodes[1].before;
|
||||
} else {
|
||||
delete sample.before;
|
||||
}
|
||||
} else {
|
||||
for (var _iterator = nodes, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
var node = _ref;
|
||||
if (this.first != sample) node.before = sample.before;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
// Stringify styles
|
||||
Root.prototype.stringify = function stringify(builder) {
|
||||
this.stringifyContent(builder);
|
||||
if (this.after) builder(this.after);
|
||||
};
|
||||
|
||||
// Generate processing result with optional source map
|
||||
Root.prototype.toResult = function toResult() {
|
||||
var opts = arguments[0] === undefined ? {} : arguments[0];
|
||||
return new Result(this, opts);
|
||||
};
|
||||
|
||||
return Root;
|
||||
})(Container);
|
||||
|
||||
module.exports = Root;
|
||||
Generated
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
|
||||
|
||||
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Declaration = _interopRequire(require("./declaration"));
|
||||
|
||||
var Container = _interopRequire(require("./container"));
|
||||
|
||||
var list = _interopRequire(require("./list"));
|
||||
|
||||
// CSS rule like “a { }”
|
||||
var Rule = (function (Container) {
|
||||
function Rule(defaults) {
|
||||
_classCallCheck(this, Rule);
|
||||
|
||||
this.type = "rule";
|
||||
this.nodes = [];
|
||||
Container.call(this, defaults);
|
||||
}
|
||||
|
||||
_inherits(Rule, Container);
|
||||
|
||||
// Stringify rule
|
||||
Rule.prototype.stringify = function stringify(builder) {
|
||||
this.stringifyBlock(builder, this.stringifyRaw("selector"));
|
||||
};
|
||||
|
||||
_prototypeProperties(Rule, null, {
|
||||
selectors: {
|
||||
|
||||
// Shortcut to get selectors as array
|
||||
|
||||
get: function () {
|
||||
return list.comma(this.selector);
|
||||
},
|
||||
set: function (values) {
|
||||
this.selector = values.join(", ");
|
||||
},
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
return Rule;
|
||||
})(Container);
|
||||
|
||||
module.exports = Rule;
|
||||
Generated
Vendored
+193
@@ -0,0 +1,193 @@
|
||||
"use strict";
|
||||
|
||||
var singleQuote = "'".charCodeAt(0),
|
||||
doubleQuote = "\"".charCodeAt(0),
|
||||
backslash = "\\".charCodeAt(0),
|
||||
slash = "/".charCodeAt(0),
|
||||
newline = "\n".charCodeAt(0),
|
||||
space = " ".charCodeAt(0),
|
||||
feed = "\f".charCodeAt(0),
|
||||
tab = "\t".charCodeAt(0),
|
||||
cr = "\r".charCodeAt(0),
|
||||
openBracket = "(".charCodeAt(0),
|
||||
closeBracket = ")".charCodeAt(0),
|
||||
openCurly = "{".charCodeAt(0),
|
||||
closeCurly = "}".charCodeAt(0),
|
||||
semicolon = ";".charCodeAt(0),
|
||||
asterisk = "*".charCodeAt(0),
|
||||
colon = ":".charCodeAt(0),
|
||||
at = "@".charCodeAt(0),
|
||||
atEnd = /[ \n\t\r\{\(\)'"\\/]/g,
|
||||
wordEnd = /[ \n\t\r\(\)\{\}:;@!'"\\]|\/(?=\*)/g,
|
||||
badBracket = /.[\\\/\("'\n]/;
|
||||
|
||||
module.exports = function (input) {
|
||||
var tokens = [];
|
||||
var css = input.css.valueOf();
|
||||
|
||||
var code, next, quote, lines, last, content, escape, nextLine, nextOffset, escaped, escapePos, bad;
|
||||
|
||||
var length = css.length;
|
||||
var offset = -1;
|
||||
var line = 1;
|
||||
var pos = 0;
|
||||
|
||||
var unclosed = function (what, end) {
|
||||
if (input.safe) {
|
||||
css += end;
|
||||
next = css.length - 1;
|
||||
} else {
|
||||
throw input.error("Unclosed " + what, line, pos - offset);
|
||||
}
|
||||
};
|
||||
|
||||
while (pos < length) {
|
||||
code = css.charCodeAt(pos);
|
||||
|
||||
if (code == newline) {
|
||||
offset = pos;
|
||||
line += 1;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case newline:
|
||||
case space:
|
||||
case tab:
|
||||
case cr:
|
||||
case feed:
|
||||
next = pos;
|
||||
do {
|
||||
next += 1;
|
||||
code = css.charCodeAt(next);
|
||||
if (code == newline) {
|
||||
offset = next;
|
||||
line += 1;
|
||||
}
|
||||
} while (code == space || code == newline || code == tab || code == cr || code == feed);
|
||||
|
||||
tokens.push(["space", css.slice(pos, next)]);
|
||||
pos = next - 1;
|
||||
break;
|
||||
|
||||
case openCurly:
|
||||
tokens.push(["{", "{", line, pos - offset]);
|
||||
break;
|
||||
|
||||
case closeCurly:
|
||||
tokens.push(["}", "}", line, pos - offset]);
|
||||
break;
|
||||
|
||||
case colon:
|
||||
tokens.push([":", ":", line, pos - offset]);
|
||||
break;
|
||||
|
||||
case semicolon:
|
||||
tokens.push([";", ";", line, pos - offset]);
|
||||
break;
|
||||
|
||||
case openBracket:
|
||||
next = css.indexOf(")", pos + 1);
|
||||
content = css.slice(pos, next + 1);
|
||||
|
||||
if (next == -1 || badBracket.test(content)) {
|
||||
tokens.push(["(", "(", line, pos - offset]);
|
||||
} else {
|
||||
tokens.push(["brackets", content, line, pos - offset, line, next - offset]);
|
||||
pos = next;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case closeBracket:
|
||||
tokens.push([")", ")", line, pos - offset]);
|
||||
break;
|
||||
|
||||
case singleQuote:
|
||||
case doubleQuote:
|
||||
quote = code == singleQuote ? "'" : "\"";
|
||||
next = pos;
|
||||
do {
|
||||
escaped = false;
|
||||
next = css.indexOf(quote, next + 1);
|
||||
if (next == -1) unclosed("quote", quote);
|
||||
escapePos = next;
|
||||
while (css.charCodeAt(escapePos - 1) == backslash) {
|
||||
escapePos -= 1;
|
||||
escaped = !escaped;
|
||||
}
|
||||
} while (escaped);
|
||||
|
||||
tokens.push(["string", css.slice(pos, next + 1), line, pos - offset, line, next - offset]);
|
||||
pos = next;
|
||||
break;
|
||||
|
||||
case at:
|
||||
atEnd.lastIndex = pos + 1;
|
||||
atEnd.test(css);
|
||||
if (atEnd.lastIndex === 0) {
|
||||
next = css.length - 1;
|
||||
} else {
|
||||
next = atEnd.lastIndex - 2;
|
||||
}
|
||||
tokens.push(["at-word", css.slice(pos, next + 1), line, pos - offset, line, next - offset]);
|
||||
pos = next;
|
||||
break;
|
||||
|
||||
case backslash:
|
||||
next = pos;
|
||||
escape = true;
|
||||
while (css.charCodeAt(next + 1) == backslash) {
|
||||
next += 1;
|
||||
escape = !escape;
|
||||
}
|
||||
code = css.charCodeAt(next + 1);
|
||||
if (escape && (code != slash && code != space && code != newline && code != tab && code != cr && code != feed)) {
|
||||
next += 1;
|
||||
}
|
||||
tokens.push(["word", css.slice(pos, next + 1), line, pos - offset, line, next - offset]);
|
||||
pos = next;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (code == slash && css.charCodeAt(pos + 1) == asterisk) {
|
||||
next = css.indexOf("*/", pos + 2) + 1;
|
||||
if (next === 0) unclosed("comment", "*/");
|
||||
|
||||
content = css.slice(pos, next + 1);
|
||||
lines = content.split("\n");
|
||||
last = lines.length - 1;
|
||||
|
||||
if (last > 0) {
|
||||
nextLine = line + last;
|
||||
nextOffset = next - lines[last].length;
|
||||
} else {
|
||||
nextLine = line;
|
||||
nextOffset = offset;
|
||||
}
|
||||
|
||||
tokens.push(["comment", content, line, pos - offset, nextLine, next - nextOffset]);
|
||||
|
||||
offset = nextOffset;
|
||||
line = nextLine;
|
||||
pos = next;
|
||||
} else {
|
||||
wordEnd.lastIndex = pos + 1;
|
||||
wordEnd.test(css);
|
||||
if (wordEnd.lastIndex === 0) {
|
||||
next = css.length - 1;
|
||||
} else {
|
||||
next = wordEnd.lastIndex - 2;
|
||||
}
|
||||
|
||||
tokens.push(["word", css.slice(pos, next + 1), line, pos - offset, line, next - offset]);
|
||||
pos = next;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
};
|
||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
|
||||
// Methods to work with vendor prefixes
|
||||
module.exports = {
|
||||
|
||||
// Return vendor prefix from property name, if it exists
|
||||
//
|
||||
// vendor.prefix('-moz-box-sizing') #=> '-moz-'
|
||||
// vendor.prefix('box-sizing') #=> ''
|
||||
prefix: function (prop) {
|
||||
if (prop[0] == "-") {
|
||||
var sep = prop.indexOf("-", 1);
|
||||
return prop.substr(0, sep + 1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
|
||||
// Remove prefix from property name
|
||||
//
|
||||
// vendor.prefix('-moz-box-sizing') #=> 'box-sizing'
|
||||
// vendor.prefix('box-sizing') #=> 'box-sizing'
|
||||
unprefixed: function (prop) {
|
||||
if (prop[0] == "-") {
|
||||
var sep = prop.indexOf("-", 1);
|
||||
return prop.substr(sep + 1);
|
||||
} else {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
*,v
|
||||
attic/**/*
|
||||
node_modules/**/*
|
||||
tmp/**/*
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
|
||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2014, Dan Kogai
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of {{{project}}} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Generated
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
[](http://travis-ci.org/dankogai/js-base64)
|
||||
|
||||
# base64.js
|
||||
|
||||
Yet another Base64 transcoder
|
||||
|
||||
## Usage
|
||||
|
||||
### In Browser
|
||||
````html
|
||||
<script src="base64.js"></script>
|
||||
````
|
||||
### node.js
|
||||
````javascript
|
||||
var Base64 = require('./base64.js').Base64;
|
||||
````
|
||||
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
````javascript
|
||||
Base64.encode('dankogai'); // ZGFua29nYWk=
|
||||
Base64.encode('小飼弾'); // 5bCP6aO85by+
|
||||
Base64.encodeURI('小飼弾'); // 5bCP6aO85by-
|
||||
|
||||
Base64.decode('ZGFua29nYWk='); // dankogai
|
||||
Base64.decode('5bCP6aO85by+'); // 小飼弾
|
||||
// note .decodeURI() is unnecessary since it accepts both flavors
|
||||
Base64.decode('5bCP6aO85by-'); // 小飼弾
|
||||
````
|
||||
|
||||
### String Extension for ES5
|
||||
|
||||
````javascript
|
||||
if (Base64.extendString) {
|
||||
// you have to explicitly extend String.prototype
|
||||
Base64.extendString();
|
||||
// once extended, you can do the following
|
||||
'dankogai'.toBase64(); // ZGFua29nYWk=
|
||||
'小飼弾'.toBase64(); // 5bCP6aO85by+
|
||||
'小飼弾'.toBase64(true); // 5bCP6aO85by-
|
||||
'小飼弾'.toBase64URI(); // 5bCP6aO85by-
|
||||
'ZGFua29nYWk='.fromBase64(); // dankogai
|
||||
'5bCP6aO85by+'.fromBase64(); // 小飼弾
|
||||
'5bCP6aO85by-'.fromBase64(); // 小飼弾
|
||||
}
|
||||
````
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
+ http://en.wikipedia.org/wiki/Base64
|
||||
Generated
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!-- $Id: base64.html,v 1.1 2009/03/01 22:00:28 dankogai Exp dankogai $ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Test for base64.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test for base64.js</h1>
|
||||
<p>$Id: base64.html,v 1.1 2009/03/01 22:00:28 dankogai Exp dankogai $</p>
|
||||
<table width="640"><tbody>
|
||||
<tr><th width="50%">Text</th><th>Base64
|
||||
(URL Safe <input id="encodeURI" type="checkbox" onclick="doit()">)</th></tr>
|
||||
<tr>
|
||||
<th><textarea id="srctxt" cols="32" rows="4" onkeyup="doit()">
|
||||
</textarea></th>
|
||||
<th><textarea id="base64" cols=32" rows="4" onkeyup="
|
||||
$('srctxt').value = Base64.decode(this.value);
|
||||
doit();
|
||||
if (1 /*@cc_on -1 @*/) $('data').src = 'data:text/plain;base64,' + this.value;
|
||||
"></textarea></th>
|
||||
</tr>
|
||||
<tr><th width="50%">Roundtrip</th><th>iframe w/ data: (no IE)</th></tr>
|
||||
<tr>
|
||||
<th><textarea id="roundtrip" cols=32" rows="4" disabled></textarea></th>
|
||||
<th><iframe id="data" width="80%" height="64"></iframe></th>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
|
||||
<script src="./base64.js"></script>
|
||||
<script>
|
||||
$ = function(id){ return document.getElementById(id) };
|
||||
function doit(){
|
||||
var encoded = Base64[
|
||||
'encode' + ($('encodeURI').checked ? 'URI' : '')
|
||||
]($('srctxt').value);
|
||||
$('base64').value = encoded;
|
||||
if (1 /*@cc_on -1 @*/) {
|
||||
$('data').src = 'data:text/plain;base64,'
|
||||
+ Base64.encode(Base64.decode(encoded));
|
||||
}
|
||||
$('roundtrip').value = Base64.decode(encoded);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
Vendored
+193
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* $Id: base64.js,v 2.15 2014/04/05 12:58:57 dankogai Exp dankogai $
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* http://opensource.org/licenses/mit-license
|
||||
*
|
||||
* References:
|
||||
* http://en.wikipedia.org/wiki/Base64
|
||||
*/
|
||||
|
||||
(function(global) {
|
||||
'use strict';
|
||||
// existing version for noConflict()
|
||||
var _Base64 = global.Base64;
|
||||
var version = "2.1.7";
|
||||
// if node.js, we use Buffer
|
||||
var buffer;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
buffer = require('buffer').Buffer;
|
||||
}
|
||||
// constants
|
||||
var b64chars
|
||||
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
var b64tab = function(bin) {
|
||||
var t = {};
|
||||
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
|
||||
return t;
|
||||
}(b64chars);
|
||||
var fromCharCode = String.fromCharCode;
|
||||
// encoder stuff
|
||||
var cb_utob = function(c) {
|
||||
if (c.length < 2) {
|
||||
var cc = c.charCodeAt(0);
|
||||
return cc < 0x80 ? c
|
||||
: cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
|
||||
+ fromCharCode(0x80 | (cc & 0x3f)))
|
||||
: (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
|
||||
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
|
||||
+ fromCharCode(0x80 | ( cc & 0x3f)));
|
||||
} else {
|
||||
var cc = 0x10000
|
||||
+ (c.charCodeAt(0) - 0xD800) * 0x400
|
||||
+ (c.charCodeAt(1) - 0xDC00);
|
||||
return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
|
||||
+ fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
|
||||
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
|
||||
+ fromCharCode(0x80 | ( cc & 0x3f)));
|
||||
}
|
||||
};
|
||||
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
|
||||
var utob = function(u) {
|
||||
return u.replace(re_utob, cb_utob);
|
||||
};
|
||||
var cb_encode = function(ccc) {
|
||||
var padlen = [0, 2, 1][ccc.length % 3],
|
||||
ord = ccc.charCodeAt(0) << 16
|
||||
| ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
|
||||
| ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
|
||||
chars = [
|
||||
b64chars.charAt( ord >>> 18),
|
||||
b64chars.charAt((ord >>> 12) & 63),
|
||||
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
|
||||
padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
|
||||
];
|
||||
return chars.join('');
|
||||
};
|
||||
var btoa = global.btoa ? function(b) {
|
||||
return global.btoa(b);
|
||||
} : function(b) {
|
||||
return b.replace(/[\s\S]{1,3}/g, cb_encode);
|
||||
};
|
||||
var _encode = buffer ? function (u) {
|
||||
return (u.constructor === buffer.constructor ? u : new buffer(u))
|
||||
.toString('base64')
|
||||
}
|
||||
: function (u) { return btoa(utob(u)) }
|
||||
;
|
||||
var encode = function(u, urisafe) {
|
||||
return !urisafe
|
||||
? _encode(String(u))
|
||||
: _encode(String(u)).replace(/[+\/]/g, function(m0) {
|
||||
return m0 == '+' ? '-' : '_';
|
||||
}).replace(/=/g, '');
|
||||
};
|
||||
var encodeURI = function(u) { return encode(u, true) };
|
||||
// decoder stuff
|
||||
var re_btou = new RegExp([
|
||||
'[\xC0-\xDF][\x80-\xBF]',
|
||||
'[\xE0-\xEF][\x80-\xBF]{2}',
|
||||
'[\xF0-\xF7][\x80-\xBF]{3}'
|
||||
].join('|'), 'g');
|
||||
var cb_btou = function(cccc) {
|
||||
switch(cccc.length) {
|
||||
case 4:
|
||||
var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
|
||||
| ((0x3f & cccc.charCodeAt(1)) << 12)
|
||||
| ((0x3f & cccc.charCodeAt(2)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(3)),
|
||||
offset = cp - 0x10000;
|
||||
return (fromCharCode((offset >>> 10) + 0xD800)
|
||||
+ fromCharCode((offset & 0x3FF) + 0xDC00));
|
||||
case 3:
|
||||
return fromCharCode(
|
||||
((0x0f & cccc.charCodeAt(0)) << 12)
|
||||
| ((0x3f & cccc.charCodeAt(1)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(2))
|
||||
);
|
||||
default:
|
||||
return fromCharCode(
|
||||
((0x1f & cccc.charCodeAt(0)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(1))
|
||||
);
|
||||
}
|
||||
};
|
||||
var btou = function(b) {
|
||||
return b.replace(re_btou, cb_btou);
|
||||
};
|
||||
var cb_decode = function(cccc) {
|
||||
var len = cccc.length,
|
||||
padlen = len % 4,
|
||||
n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
|
||||
| (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
|
||||
| (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
|
||||
| (len > 3 ? b64tab[cccc.charAt(3)] : 0),
|
||||
chars = [
|
||||
fromCharCode( n >>> 16),
|
||||
fromCharCode((n >>> 8) & 0xff),
|
||||
fromCharCode( n & 0xff)
|
||||
];
|
||||
chars.length -= [0, 0, 2, 1][padlen];
|
||||
return chars.join('');
|
||||
};
|
||||
var atob = global.atob ? function(a) {
|
||||
return global.atob(a);
|
||||
} : function(a){
|
||||
return a.replace(/[\s\S]{1,4}/g, cb_decode);
|
||||
};
|
||||
var _decode = buffer ? function(a) {
|
||||
return (a.constructor === buffer.constructor
|
||||
? a : new buffer(a, 'base64')).toString();
|
||||
}
|
||||
: function(a) { return btou(atob(a)) };
|
||||
var decode = function(a){
|
||||
return _decode(
|
||||
String(a).replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })
|
||||
.replace(/[^A-Za-z0-9\+\/]/g, '')
|
||||
);
|
||||
};
|
||||
var noConflict = function() {
|
||||
var Base64 = global.Base64;
|
||||
global.Base64 = _Base64;
|
||||
return Base64;
|
||||
};
|
||||
// export Base64
|
||||
global.Base64 = {
|
||||
VERSION: version,
|
||||
atob: atob,
|
||||
btoa: btoa,
|
||||
fromBase64: decode,
|
||||
toBase64: encode,
|
||||
utob: utob,
|
||||
encode: encode,
|
||||
encodeURI: encodeURI,
|
||||
btou: btou,
|
||||
decode: decode,
|
||||
noConflict: noConflict
|
||||
};
|
||||
// if ES5 is available, make Base64.extendString() available
|
||||
if (typeof Object.defineProperty === 'function') {
|
||||
var noEnum = function(v){
|
||||
return {value:v,enumerable:false,writable:true,configurable:true};
|
||||
};
|
||||
global.Base64.extendString = function () {
|
||||
Object.defineProperty(
|
||||
String.prototype, 'fromBase64', noEnum(function () {
|
||||
return decode(this)
|
||||
}));
|
||||
Object.defineProperty(
|
||||
String.prototype, 'toBase64', noEnum(function (urisafe) {
|
||||
return encode(this, urisafe)
|
||||
}));
|
||||
Object.defineProperty(
|
||||
String.prototype, 'toBase64URI', noEnum(function () {
|
||||
return encode(this, true)
|
||||
}));
|
||||
};
|
||||
}
|
||||
// that's it!
|
||||
})(this);
|
||||
|
||||
if (this['Meteor']) {
|
||||
Base64 = global.Base64; // for normal export in Meteor.js
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
(function(global){"use strict";var _Base64=global.Base64;var version="2.1.7";var buffer;if(typeof module!=="undefined"&&module.exports){buffer=require("buffer").Buffer}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i<l;i++)t[bin.charAt(i)]=i;return t}(b64chars);var fromCharCode=String.fromCharCode;var cb_utob=function(c){if(c.length<2){var cc=c.charCodeAt(0);return cc<128?c:cc<2048?fromCharCode(192|cc>>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][-¿]","[à-ï][-¿]{2}","[ð-÷][-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/[\s\S]{1,4}/g,cb_decode)};var _decode=buffer?function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}})(this);if(this["Meteor"]){Base64=global.Base64}
|
||||
Generated
Vendored
+219
@@ -0,0 +1,219 @@
|
||||
(function(global) {
|
||||
'use strict';
|
||||
if (global.Base64) return;
|
||||
var version = "2.1.1";
|
||||
// if node.js, we use Buffer
|
||||
var buffer;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
buffer = require('buffer').Buffer;
|
||||
}
|
||||
// constants
|
||||
var b64chars
|
||||
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
var b64tab = function(bin) {
|
||||
var t = {};
|
||||
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
|
||||
return t;
|
||||
}(b64chars);
|
||||
var fromCharCode = String.fromCharCode;
|
||||
// encoder stuff
|
||||
var cb_utob = function(c) {
|
||||
if (c.length < 2) {
|
||||
var cc = c.charCodeAt(0);
|
||||
return cc < 0x80 ? c
|
||||
: cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
|
||||
+ fromCharCode(0x80 | (cc & 0x3f)))
|
||||
: (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
|
||||
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
|
||||
+ fromCharCode(0x80 | ( cc & 0x3f)));
|
||||
} else {
|
||||
var cc = 0x10000
|
||||
+ (c.charCodeAt(0) - 0xD800) * 0x400
|
||||
+ (c.charCodeAt(1) - 0xDC00);
|
||||
return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
|
||||
+ fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
|
||||
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
|
||||
+ fromCharCode(0x80 | ( cc & 0x3f)));
|
||||
}
|
||||
};
|
||||
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
|
||||
var utob = function(u) {
|
||||
return u.replace(re_utob, cb_utob);
|
||||
};
|
||||
var cb_encode = function(ccc) {
|
||||
var padlen = [0, 2, 1][ccc.length % 3],
|
||||
ord = ccc.charCodeAt(0) << 16
|
||||
| ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
|
||||
| ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
|
||||
chars = [
|
||||
b64chars.charAt( ord >>> 18),
|
||||
b64chars.charAt((ord >>> 12) & 63),
|
||||
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
|
||||
padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
|
||||
];
|
||||
return chars.join('');
|
||||
};
|
||||
var btoa = global.btoa || function(b) {
|
||||
return b.replace(/[\s\S]{1,3}/g, cb_encode);
|
||||
};
|
||||
var _encode = buffer
|
||||
? function (u) { return _utf8_encode((new buffer(u)).toString('base64')) }
|
||||
: function (u) { return _utf8_encode(btoa(utob(u))) }
|
||||
;
|
||||
var encode = function(u, urisafe) {
|
||||
return !urisafe
|
||||
? _encode(u)
|
||||
: _encode(u).replace(/[+\/]/g, function(m0) {
|
||||
return m0 == '+' ? '-' : '_';
|
||||
}).replace(/=/g, '');
|
||||
};
|
||||
var encodeURI = function(u) { return encode(u, true) };
|
||||
// decoder stuff
|
||||
var re_btou = new RegExp([
|
||||
'[\xC0-\xDF][\x80-\xBF]',
|
||||
'[\xE0-\xEF][\x80-\xBF]{2}',
|
||||
'[\xF0-\xF7][\x80-\xBF]{3}'
|
||||
].join('|'), 'g');
|
||||
var cb_btou = function(cccc) {
|
||||
switch(cccc.length) {
|
||||
case 4:
|
||||
var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
|
||||
| ((0x3f & cccc.charCodeAt(1)) << 12)
|
||||
| ((0x3f & cccc.charCodeAt(2)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(3)),
|
||||
offset = cp - 0x10000;
|
||||
return (fromCharCode((offset >>> 10) + 0xD800)
|
||||
+ fromCharCode((offset & 0x3FF) + 0xDC00));
|
||||
case 3:
|
||||
return fromCharCode(
|
||||
((0x0f & cccc.charCodeAt(0)) << 12)
|
||||
| ((0x3f & cccc.charCodeAt(1)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(2))
|
||||
);
|
||||
default:
|
||||
return fromCharCode(
|
||||
((0x1f & cccc.charCodeAt(0)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(1))
|
||||
);
|
||||
}
|
||||
};
|
||||
var _utf8_encode = function ( string ) {
|
||||
string = string.replace(/\r\n/g,"\n");
|
||||
var utftext = "";
|
||||
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
|
||||
var c = string.charCodeAt(n);
|
||||
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
}
|
||||
else if((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return utftext;
|
||||
};
|
||||
var _utf8_decode = function (utftext) {
|
||||
var string = "";
|
||||
var i = 0;
|
||||
var c = c1 = c2 = 0;
|
||||
|
||||
while ( i < utftext.length ) {
|
||||
|
||||
c = utftext.charCodeAt(i);
|
||||
|
||||
if (c < 128) {
|
||||
string += String.fromCharCode(c);
|
||||
i++;
|
||||
}
|
||||
else if((c > 191) && (c < 224)) {
|
||||
c2 = utftext.charCodeAt(i+1);
|
||||
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
||||
i += 2;
|
||||
}
|
||||
else {
|
||||
c2 = utftext.charCodeAt(i+1);
|
||||
c3 = utftext.charCodeAt(i+2);
|
||||
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
||||
i += 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return string;
|
||||
};
|
||||
var btou = function(b) {
|
||||
return b.replace(re_btou, cb_btou);
|
||||
};
|
||||
var cb_decode = function(cccc) {
|
||||
var len = cccc.length,
|
||||
padlen = len % 4,
|
||||
n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
|
||||
| (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
|
||||
| (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
|
||||
| (len > 3 ? b64tab[cccc.charAt(3)] : 0),
|
||||
chars = [
|
||||
fromCharCode( n >>> 16),
|
||||
fromCharCode((n >>> 8) & 0xff),
|
||||
fromCharCode( n & 0xff)
|
||||
];
|
||||
chars.length -= [0, 0, 2, 1][padlen];
|
||||
return chars.join('');
|
||||
};
|
||||
var atob = global.atob || function(a){
|
||||
return a.replace(/[\s\S]{1,4}/g, cb_decode);
|
||||
};
|
||||
var _decode = buffer
|
||||
? function(a) { return (new buffer(a, 'base64')).toString() }
|
||||
: function(a) { return btou(atob(a)) };
|
||||
var decode = function(a){
|
||||
a = _utf8_decode( a );
|
||||
return _decode(
|
||||
a.replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })
|
||||
.replace(/[^A-Za-z0-9\+\/]/g, '')
|
||||
);
|
||||
};
|
||||
// export Base64
|
||||
global.Base64 = {
|
||||
VERSION: version,
|
||||
atob: atob,
|
||||
btoa: btoa,
|
||||
fromBase64: decode,
|
||||
toBase64: encode,
|
||||
utob: utob,
|
||||
encode: encode,
|
||||
encodeURI: encodeURI,
|
||||
btou: btou,
|
||||
decode: decode
|
||||
};
|
||||
// if ES5 is available, make Base64.extendString() available
|
||||
if (typeof Object.defineProperty === 'function') {
|
||||
var noEnum = function(v){
|
||||
return {value:v,enumerable:false,writable:true,configurable:true};
|
||||
};
|
||||
global.Base64.extendString = function () {
|
||||
Object.defineProperty(
|
||||
String.prototype, 'fromBase64', noEnum(function () {
|
||||
return decode(this)
|
||||
}));
|
||||
Object.defineProperty(
|
||||
String.prototype, 'toBase64', noEnum(function (urisafe) {
|
||||
return encode(this, urisafe)
|
||||
}));
|
||||
Object.defineProperty(
|
||||
String.prototype, 'toBase64URI', noEnum(function () {
|
||||
return encode(this, true)
|
||||
}));
|
||||
};
|
||||
}
|
||||
// that's it!
|
||||
})(this);
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "js-base64",
|
||||
"version": "2.1.7",
|
||||
"main": [
|
||||
"./base64.js"
|
||||
],
|
||||
"ignore": [
|
||||
"old",
|
||||
"test",
|
||||
".gitignore",
|
||||
".travis.yml",
|
||||
"base64.html",
|
||||
"package.json"
|
||||
],
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+237
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* $Id: base64.js,v 1.7 2012/08/23 10:30:18 dankogai Exp dankogai $
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* References:
|
||||
* http://en.wikipedia.org/wiki/Base64
|
||||
*/
|
||||
|
||||
(function(global){
|
||||
|
||||
var b64chars
|
||||
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
var b64charcodes = function(){
|
||||
var a = [];
|
||||
var codeA = 'A'.charCodeAt(0);
|
||||
var codea = 'a'.charCodeAt(0);
|
||||
var code0 = '0'.charCodeAt(0);
|
||||
for (var i = 0; i < 26; i ++) a.push(codeA + i);
|
||||
for (var i = 0; i < 26; i ++) a.push(codea + i);
|
||||
for (var i = 0; i < 10; i ++) a.push(code0 + i);
|
||||
a.push('+'.charCodeAt(0));
|
||||
a.push('/'.charCodeAt(0));
|
||||
return a;
|
||||
}();
|
||||
|
||||
var b64tab = function(bin){
|
||||
var t = {};
|
||||
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
|
||||
return t;
|
||||
}(b64chars);
|
||||
|
||||
var stringToArray = function(s){
|
||||
var a = [];
|
||||
for (var i = 0, l = s.length; i < l; i ++) a[i] = s.charCodeAt(i);
|
||||
return a;
|
||||
};
|
||||
|
||||
var convertUTF8ArrayToBase64 = function(bin){
|
||||
var padlen = 0;
|
||||
while (bin.length % 3){
|
||||
bin.push(0);
|
||||
padlen++;
|
||||
};
|
||||
var b64 = [];
|
||||
for (var i = 0, l = bin.length; i < l; i += 3){
|
||||
var c0 = bin[i], c1 = bin[i+1], c2 = bin[i+2];
|
||||
if (c0 >= 256 || c1 >= 256 || c2 >= 256)
|
||||
throw 'unsupported character found';
|
||||
var n = (c0 << 16) | (c1 << 8) | c2;
|
||||
b64.push(
|
||||
b64charcodes[ n >>> 18],
|
||||
b64charcodes[(n >>> 12) & 63],
|
||||
b64charcodes[(n >>> 6) & 63],
|
||||
b64charcodes[ n & 63]
|
||||
);
|
||||
}
|
||||
while (padlen--) b64[b64.length - padlen - 1] = '='.charCodeAt(0);
|
||||
return chunkStringFromCharCodeApply(b64);
|
||||
};
|
||||
|
||||
var convertBase64ToUTF8Array = function(b64){
|
||||
b64 = b64.replace(/[^A-Za-z0-9+\/]+/g, '');
|
||||
var bin = [];
|
||||
var padlen = b64.length % 4;
|
||||
for (var i = 0, l = b64.length; i < l; i += 4){
|
||||
var n = ((b64tab[b64.charAt(i )] || 0) << 18)
|
||||
| ((b64tab[b64.charAt(i+1)] || 0) << 12)
|
||||
| ((b64tab[b64.charAt(i+2)] || 0) << 6)
|
||||
| ((b64tab[b64.charAt(i+3)] || 0));
|
||||
bin.push(
|
||||
( n >> 16 ),
|
||||
( (n >> 8) & 0xff ),
|
||||
( n & 0xff )
|
||||
);
|
||||
}
|
||||
bin.length -= [0,0,2,1][padlen];
|
||||
return bin;
|
||||
};
|
||||
|
||||
var convertUTF16ArrayToUTF8Array = function(uni){
|
||||
var bin = [];
|
||||
for (var i = 0, l = uni.length; i < l; i++){
|
||||
var n = uni[i];
|
||||
if (n < 0x80)
|
||||
bin.push(n);
|
||||
else if (n < 0x800)
|
||||
bin.push(
|
||||
0xc0 | (n >>> 6),
|
||||
0x80 | (n & 0x3f));
|
||||
else
|
||||
bin.push(
|
||||
0xe0 | ((n >>> 12) & 0x0f),
|
||||
0x80 | ((n >>> 6) & 0x3f),
|
||||
0x80 | (n & 0x3f));
|
||||
}
|
||||
return bin;
|
||||
};
|
||||
|
||||
var convertUTF8ArrayToUTF16Array = function(bin){
|
||||
var uni = [];
|
||||
for (var i = 0, l = bin.length; i < l; i++){
|
||||
var c0 = bin[i];
|
||||
if (c0 < 0x80){
|
||||
uni.push(c0);
|
||||
}else{
|
||||
var c1 = bin[++i];
|
||||
if (c0 < 0xe0){
|
||||
uni.push(((c0 & 0x1f) << 6) | (c1 & 0x3f));
|
||||
}else{
|
||||
var c2 = bin[++i];
|
||||
uni.push(
|
||||
((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return uni;
|
||||
};
|
||||
|
||||
var convertUTF8StringToBase64 = function(bin){
|
||||
return convertUTF8ArrayToBase64(stringToArray(bin));
|
||||
};
|
||||
|
||||
var convertBase64ToUTF8String = function(b64){
|
||||
return chunkStringFromCharCodeApply(convertBase64ToUTF8Array(b64));
|
||||
};
|
||||
|
||||
var convertUTF8StringToUTF16Array = function(bin){
|
||||
return convertUTF8ArrayToUTF16Array(stringToArray(bin));
|
||||
};
|
||||
|
||||
var convertUTF8ArrayToUTF16String = function(bin){
|
||||
return chunkStringFromCharCodeApply(convertUTF8ArrayToUTF16Array(bin));
|
||||
};
|
||||
|
||||
var convertUTF8StringToUTF16String = function(bin){
|
||||
return chunkStringFromCharCodeApply(
|
||||
convertUTF8ArrayToUTF16Array(stringToArray(bin))
|
||||
);
|
||||
};
|
||||
|
||||
var convertUTF16StringToUTF8Array = function(uni){
|
||||
return convertUTF16ArrayToUTF8Array(stringToArray(uni));
|
||||
};
|
||||
|
||||
var convertUTF16ArrayToUTF8String = function(uni){
|
||||
return chunkStringFromCharCodeApply(convertUTF16ArrayToUTF8Array(uni));
|
||||
};
|
||||
|
||||
var convertUTF16StringToUTF8String = function(uni){
|
||||
return chunkStringFromCharCodeApply(
|
||||
convertUTF16ArrayToUTF8Array(stringToArray(uni))
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
* String.fromCharCode.apply will only handle arrays as big as 65536,
|
||||
* after that it'll return a truncated string with no warning.
|
||||
*/
|
||||
var chunkStringFromCharCodeApply = function(arr){
|
||||
var strs = [], i;
|
||||
for (i = 0; i < arr.length; i += 65536){
|
||||
strs.push(String.fromCharCode.apply(String, arr.slice(i, i+65536)));
|
||||
}
|
||||
return strs.join('');
|
||||
};
|
||||
|
||||
if (global.btoa){
|
||||
var btoa = global.btoa;
|
||||
var convertUTF16StringToBase64 = function (uni){
|
||||
return btoa(convertUTF16StringToUTF8String(uni));
|
||||
};
|
||||
}
|
||||
else {
|
||||
var btoa = convertUTF8StringToBase64;
|
||||
var convertUTF16StringToBase64 = function (uni){
|
||||
return convertUTF8ArrayToBase64(convertUTF16StringToUTF8Array(uni));
|
||||
};
|
||||
}
|
||||
|
||||
if (global.atob){
|
||||
var atob = global.atob;
|
||||
var convertBase64ToUTF16String = function (b64){
|
||||
return convertUTF8StringToUTF16String(atob(b64));
|
||||
};
|
||||
}
|
||||
else {
|
||||
var atob = convertBase64ToUTF8String;
|
||||
var convertBase64ToUTF16String = function (b64){
|
||||
return convertUTF8ArrayToUTF16String(convertBase64ToUTF8Array(b64));
|
||||
};
|
||||
}
|
||||
|
||||
global.Base64 = {
|
||||
convertUTF8ArrayToBase64:convertUTF8ArrayToBase64,
|
||||
convertByteArrayToBase64:convertUTF8ArrayToBase64,
|
||||
convertBase64ToUTF8Array:convertBase64ToUTF8Array,
|
||||
convertBase64ToByteArray:convertBase64ToUTF8Array,
|
||||
convertUTF16ArrayToUTF8Array:convertUTF16ArrayToUTF8Array,
|
||||
convertUTF16ArrayToByteArray:convertUTF16ArrayToUTF8Array,
|
||||
convertUTF8ArrayToUTF16Array:convertUTF8ArrayToUTF16Array,
|
||||
convertByteArrayToUTF16Array:convertUTF8ArrayToUTF16Array,
|
||||
convertUTF8StringToBase64:convertUTF8StringToBase64,
|
||||
convertBase64ToUTF8String:convertBase64ToUTF8String,
|
||||
convertUTF8StringToUTF16Array:convertUTF8StringToUTF16Array,
|
||||
convertUTF8ArrayToUTF16String:convertUTF8ArrayToUTF16String,
|
||||
convertByteArrayToUTF16String:convertUTF8ArrayToUTF16String,
|
||||
convertUTF8StringToUTF16String:convertUTF8StringToUTF16String,
|
||||
convertUTF16StringToUTF8Array:convertUTF16StringToUTF8Array,
|
||||
convertUTF16StringToByteArray:convertUTF16StringToUTF8Array,
|
||||
convertUTF16ArrayToUTF8String:convertUTF16ArrayToUTF8String,
|
||||
convertUTF16StringToUTF8String:convertUTF16StringToUTF8String,
|
||||
convertUTF16StringToBase64:convertUTF16StringToBase64,
|
||||
convertBase64ToUTF16String:convertBase64ToUTF16String,
|
||||
fromBase64:convertBase64ToUTF8String,
|
||||
toBase64:convertUTF8StringToBase64,
|
||||
atob:atob,
|
||||
btoa:btoa,
|
||||
utob:convertUTF16StringToUTF8String,
|
||||
btou:convertUTF8StringToUTF16String,
|
||||
encode:convertUTF16StringToBase64,
|
||||
encodeURI:function(u){
|
||||
return convertUTF16StringToBase64(u).replace(/[+\/]/g, function(m0){
|
||||
return m0 == '+' ? '-' : '_';
|
||||
}).replace(/=+$/, '');
|
||||
},
|
||||
decode:function(a){
|
||||
return convertBase64ToUTF16String(a.replace(/[-_]/g, function(m0){
|
||||
return m0 == '-' ? '+' : '/';
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
})(this);
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
Package.describe({
|
||||
summary: "Yet another Base64 transcoder"
|
||||
})
|
||||
|
||||
Package.on_use(function(api){
|
||||
api.export('Base64');
|
||||
|
||||
api.add_files(['base64.js'], 'server');
|
||||
});
|
||||
Generated
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "js-base64",
|
||||
"version": "2.1.7",
|
||||
"description": "Yet another Base64 transcoder in pure-JS",
|
||||
"main": "base64.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/dankogai/js-base64.git"
|
||||
},
|
||||
"keywords": [
|
||||
"base64"
|
||||
],
|
||||
"author": {
|
||||
"name": "Dan Kogai"
|
||||
},
|
||||
"license": "BSD",
|
||||
"gitHead": "8bfa436f733bec60c95c720e1d720c28b43ae0b2",
|
||||
"bugs": {
|
||||
"url": "https://github.com/dankogai/js-base64/issues"
|
||||
},
|
||||
"homepage": "https://github.com/dankogai/js-base64",
|
||||
"_id": "js-base64@2.1.7",
|
||||
"_shasum": "aa9c941ceff1567ea9ed8bea8319191f3541e4e8",
|
||||
"_from": "js-base64@>=2.1.7 <2.2.0",
|
||||
"_npmVersion": "2.1.18",
|
||||
"_nodeVersion": "0.10.35",
|
||||
"_npmUser": {
|
||||
"name": "dankogai",
|
||||
"email": "dankogai+github@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "dankogai",
|
||||
"email": "dankogai+github@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "aa9c941ceff1567ea9ed8bea8319191f3541e4e8",
|
||||
"tarball": "http://registry.npmjs.org/js-base64/-/js-base64-2.1.7.tgz"
|
||||
},
|
||||
"_resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.7.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Generated
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* $Id: dankogai.js,v 0.4 2012/08/24 05:23:18 dankogai Exp dankogai $
|
||||
*
|
||||
* use mocha to test me
|
||||
* http://visionmedia.github.com/mocha/
|
||||
*/
|
||||
var assert, Base64;
|
||||
if (this['window'] !== this) {
|
||||
assert = require("assert");
|
||||
Base64 = require('../base64.js').Base64;
|
||||
}
|
||||
var is = function (a, e, m) {
|
||||
return function () {
|
||||
assert.equal(a, e, m)
|
||||
}
|
||||
};
|
||||
|
||||
describe('basic', function () {
|
||||
it('d', is(Base64.encode('d'), 'ZA=='));
|
||||
it('da', is(Base64.encode('da'), 'ZGE='));
|
||||
it('dan', is(Base64.encode('dan'), 'ZGFu'));
|
||||
it('ZA==', is(Base64.decode('ZA=='), 'd' ));
|
||||
it('ZGE=', is(Base64.decode('ZGE='), 'da' ));
|
||||
it('ZGFu', is(Base64.decode('ZGFu'), 'dan' ));
|
||||
});
|
||||
|
||||
describe('whitespace', function () {
|
||||
it('Z A==', is(Base64.decode('ZA =='), 'd' ));
|
||||
it('ZG E=', is(Base64.decode('ZG E='), 'da' ));
|
||||
it('ZGF u', is(Base64.decode('ZGF u'), 'dan' ));
|
||||
});
|
||||
|
||||
describe('null', function () {
|
||||
it('\\0', is(Base64.encode('\0'), 'AA=='));
|
||||
it('\\0\\0', is(Base64.encode('\0\0'), 'AAA='));
|
||||
it('\\0\\0\\0', is(Base64.encode('\0\0\0'), 'AAAA'));
|
||||
it('AA==', is(Base64.decode('AA=='), '\0' ));
|
||||
it('AAA=', is(Base64.decode('AAA='), '\0\0' ));
|
||||
it('AAAA', is(Base64.decode('AAAA'), '\0\0\0'));
|
||||
});
|
||||
|
||||
describe('Base64', function () {
|
||||
it('.encode', is(Base64.encode('小飼弾'), '5bCP6aO85by+'));
|
||||
it('.encodeURI', is(Base64.encodeURI('小飼弾'), '5bCP6aO85by-'));
|
||||
it('.decode', is(Base64.decode('5bCP6aO85by+'), '小飼弾'));
|
||||
it('.decode', is(Base64.decode('5bCP6aO85by-'), '小飼弾'));
|
||||
});
|
||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* $Id: es5.js,v 0.1 2012/08/23 19:43:17 dankogai Exp dankogai $
|
||||
*
|
||||
* use mocha to test me
|
||||
* http://visionmedia.github.com/mocha/
|
||||
*/
|
||||
var assert, Base64;
|
||||
if (this['window'] !== this) {
|
||||
assert = require("assert");
|
||||
Base64 = require('../base64.js').Base64;
|
||||
}
|
||||
var is = function (a, e, m) {
|
||||
return function () {
|
||||
assert.equal(a, e, m)
|
||||
}
|
||||
};
|
||||
|
||||
if ('extendString' in Base64){
|
||||
Base64.extendString();
|
||||
describe('String', function () {
|
||||
it('.toBase64', is('小飼弾'.toBase64(), '5bCP6aO85by+'));
|
||||
it('.toBase64', is('小飼弾'.toBase64(true), '5bCP6aO85by-'));
|
||||
it('.toBase64URI', is('小飼弾'.toBase64URI(), '5bCP6aO85by-'));
|
||||
it('.fromBase64', is('5bCP6aO85by+'.fromBase64(), '小飼弾'));
|
||||
it('.fromBase64', is('5bCP6aO85by-'.fromBase64(), '小飼弾'));
|
||||
});
|
||||
}
|
||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="https://raw.github.com/visionmedia/mocha/master/mocha.css" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
||||
<script src="https://raw.github.com/visionmedia/mocha/master/mocha.js"></script>
|
||||
<script>
|
||||
mocha.setup('bdd');
|
||||
</script>
|
||||
<script src="../base64.js"></script>
|
||||
<script>
|
||||
var assert = function(expr, msg) {
|
||||
if (!expr) throw new Error(msg || 'failed');
|
||||
};
|
||||
assert.equal = function(a, b, msg) {
|
||||
if (a !== b) throw new Error(msg || ('failed : '+a+','+b));
|
||||
};
|
||||
</script>
|
||||
<script src="./dankogai.js"></script>
|
||||
<script src="./es5.js"></script>
|
||||
<script src="./large.js"></script>
|
||||
<script src="./yoshinoya.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
mocha.run();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
$Id: browser.html,v 0.2 2012/08/23 19:44:32 dankogai Exp dankogai $
|
||||
<div id="mocha"></div>
|
||||
</body>
|
||||
</html>
|
||||
Generated
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* $Id: large.js,v 0.3 2012/08/23 19:14:37 dankogai Exp dankogai $
|
||||
*
|
||||
* use mocha to test me
|
||||
* http://visionmedia.github.com/mocha/
|
||||
*/
|
||||
var assert, Base64;
|
||||
if (this['window'] !== this) {
|
||||
assert = require("assert");
|
||||
Base64 = require('../base64.js').Base64;
|
||||
}
|
||||
var is = function (a, e, m) {
|
||||
return function () {
|
||||
assert.equal(a, e, m)
|
||||
}
|
||||
};
|
||||
var seed = function () {
|
||||
var a, i;
|
||||
for (a = [], i = 0; i < 256; i++) {
|
||||
a.push(String.fromCharCode(i));
|
||||
}
|
||||
return a.join('');
|
||||
}();
|
||||
describe('Base64', function () {
|
||||
for (var i = 0, str = seed; i < 16; str += str, i++) {
|
||||
it(str.length, is(Base64.decode(Base64.encode(str)), str));
|
||||
}
|
||||
});
|
||||
Generated
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* use mocha to test me
|
||||
* http://visionmedia.github.com/mocha/
|
||||
*/
|
||||
var assert, Base64;
|
||||
if (this['window'] !== this) {
|
||||
assert = require("assert");
|
||||
Base64 = require('../base64.js').Base64;
|
||||
}
|
||||
var is = function (a, e, m) {
|
||||
return function () {
|
||||
assert.equal(a, e, m)
|
||||
}
|
||||
};
|
||||
|
||||
describe('Yoshinoya', function () {
|
||||
it('.encode', is(Base64.encode('𠮷野家'), '8KCut+mHjuWutg=='));
|
||||
it('.encodeURI', is(Base64.encodeURI('𠮷野家'), '8KCut-mHjuWutg'));
|
||||
it('.decode', is(Base64.decode('8KCut+mHjuWutg=='), '𠮷野家'));
|
||||
it('.decode', is(Base64.decode('8KCut-mHjuWutg'), '𠮷野家'));
|
||||
it('.decode', is(Base64.decode('7aGC7b636YeO5a62'), '𠮷野家'));
|
||||
});
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
dist/*
|
||||
node_modules/*
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
- "0.10"
|
||||
Generated
Vendored
+201
@@ -0,0 +1,201 @@
|
||||
# Change Log
|
||||
|
||||
## 0.2.0
|
||||
|
||||
* Support for consuming "indexed" source maps which do not have any remote
|
||||
sections. See pull request #127. This introduces a minor backwards
|
||||
incompatibility if you are monkey patching `SourceMapConsumer.prototype`
|
||||
methods.
|
||||
|
||||
## 0.1.43
|
||||
|
||||
* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue
|
||||
#148 for some discussion and issues #150, #151, and #152 for implementations.
|
||||
|
||||
## 0.1.42
|
||||
|
||||
* Fix an issue where `SourceNode`s from different versions of the source-map
|
||||
library couldn't be used in conjunction with each other. See issue #142.
|
||||
|
||||
## 0.1.41
|
||||
|
||||
* Fix a bug with getting the source content of relative sources with a "./"
|
||||
prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768).
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the
|
||||
column span of each mapping.
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find
|
||||
all generated positions associated with a given original source and line.
|
||||
|
||||
## 0.1.40
|
||||
|
||||
* Performance improvements for parsing source maps in SourceMapConsumer.
|
||||
|
||||
## 0.1.39
|
||||
|
||||
* Fix a bug where setting a source's contents to null before any source content
|
||||
had been set before threw a TypeError. See issue #131.
|
||||
|
||||
## 0.1.38
|
||||
|
||||
* Fix a bug where finding relative paths from an empty path were creating
|
||||
absolute paths. See issue #129.
|
||||
|
||||
## 0.1.37
|
||||
|
||||
* Fix a bug where if the source root was an empty string, relative source paths
|
||||
would turn into absolute source paths. Issue #124.
|
||||
|
||||
## 0.1.36
|
||||
|
||||
* Allow the `names` mapping property to be an empty string. Issue #121.
|
||||
|
||||
## 0.1.35
|
||||
|
||||
* A third optional parameter was added to `SourceNode.fromStringWithSourceMap`
|
||||
to specify a path that relative sources in the second parameter should be
|
||||
relative to. Issue #105.
|
||||
|
||||
* If no file property is given to a `SourceMapGenerator`, then the resulting
|
||||
source map will no longer have a `null` file property. The property will
|
||||
simply not exist. Issue #104.
|
||||
|
||||
* Fixed a bug where consecutive newlines were ignored in `SourceNode`s.
|
||||
Issue #116.
|
||||
|
||||
## 0.1.34
|
||||
|
||||
* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103.
|
||||
|
||||
* Fix bug involving source contents and the
|
||||
`SourceMapGenerator.prototype.applySourceMap`. Issue #100.
|
||||
|
||||
## 0.1.33
|
||||
|
||||
* Fix some edge cases surrounding path joining and URL resolution.
|
||||
|
||||
* Add a third parameter for relative path to
|
||||
`SourceMapGenerator.prototype.applySourceMap`.
|
||||
|
||||
* Fix issues with mappings and EOLs.
|
||||
|
||||
## 0.1.32
|
||||
|
||||
* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns
|
||||
(issue 92).
|
||||
|
||||
* Fixed test runner to actually report number of failed tests as its process
|
||||
exit code.
|
||||
|
||||
* Fixed a typo when reporting bad mappings (issue 87).
|
||||
|
||||
## 0.1.31
|
||||
|
||||
* Delay parsing the mappings in SourceMapConsumer until queried for a source
|
||||
location.
|
||||
|
||||
* Support Sass source maps (which at the time of writing deviate from the spec
|
||||
in small ways) in SourceMapConsumer.
|
||||
|
||||
## 0.1.30
|
||||
|
||||
* Do not join source root with a source, when the source is a data URI.
|
||||
|
||||
* Extend the test runner to allow running single specific test files at a time.
|
||||
|
||||
* Performance improvements in `SourceNode.prototype.walk` and
|
||||
`SourceMapConsumer.prototype.eachMapping`.
|
||||
|
||||
* Source map browser builds will now work inside Workers.
|
||||
|
||||
* Better error messages when attempting to add an invalid mapping to a
|
||||
`SourceMapGenerator`.
|
||||
|
||||
## 0.1.29
|
||||
|
||||
* Allow duplicate entries in the `names` and `sources` arrays of source maps
|
||||
(usually from TypeScript) we are parsing. Fixes github issue 72.
|
||||
|
||||
## 0.1.28
|
||||
|
||||
* Skip duplicate mappings when creating source maps from SourceNode; github
|
||||
issue 75.
|
||||
|
||||
## 0.1.27
|
||||
|
||||
* Don't throw an error when the `file` property is missing in SourceMapConsumer,
|
||||
we don't use it anyway.
|
||||
|
||||
## 0.1.26
|
||||
|
||||
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70.
|
||||
|
||||
## 0.1.25
|
||||
|
||||
* Make compatible with browserify
|
||||
|
||||
## 0.1.24
|
||||
|
||||
* Fix issue with absolute paths and `file://` URIs. See
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=885597
|
||||
|
||||
## 0.1.23
|
||||
|
||||
* Fix issue with absolute paths and sourcesContent, github issue 64.
|
||||
|
||||
## 0.1.22
|
||||
|
||||
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21.
|
||||
|
||||
## 0.1.21
|
||||
|
||||
* Fixed handling of sources that start with a slash so that they are relative to
|
||||
the source root's host.
|
||||
|
||||
## 0.1.20
|
||||
|
||||
* Fixed github issue #43: absolute URLs aren't joined with the source root
|
||||
anymore.
|
||||
|
||||
## 0.1.19
|
||||
|
||||
* Using Travis CI to run tests.
|
||||
|
||||
## 0.1.18
|
||||
|
||||
* Fixed a bug in the handling of sourceRoot.
|
||||
|
||||
## 0.1.17
|
||||
|
||||
* Added SourceNode.fromStringWithSourceMap.
|
||||
|
||||
## 0.1.16
|
||||
|
||||
* Added missing documentation.
|
||||
|
||||
* Fixed the generating of empty mappings in SourceNode.
|
||||
|
||||
## 0.1.15
|
||||
|
||||
* Added SourceMapGenerator.applySourceMap.
|
||||
|
||||
## 0.1.14
|
||||
|
||||
* The sourceRoot is now handled consistently.
|
||||
|
||||
## 0.1.13
|
||||
|
||||
* Added SourceMapGenerator.fromSourceMap.
|
||||
|
||||
## 0.1.12
|
||||
|
||||
* SourceNode now generates empty mappings too.
|
||||
|
||||
## 0.1.11
|
||||
|
||||
* Added name support to SourceNode.
|
||||
|
||||
## 0.1.10
|
||||
|
||||
* Added sourcesContent support to the customer and generator.
|
||||
Generated
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
Copyright (c) 2009-2011, Mozilla Foundation and contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the Mozilla Foundation nor the names of project
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Generated
Vendored
+166
@@ -0,0 +1,166 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var copy = require('dryice').copy;
|
||||
|
||||
function removeAmdefine(src) {
|
||||
src = String(src).replace(
|
||||
/if\s*\(typeof\s*define\s*!==\s*'function'\)\s*{\s*var\s*define\s*=\s*require\('amdefine'\)\(module,\s*require\);\s*}\s*/g,
|
||||
'');
|
||||
src = src.replace(
|
||||
/\b(define\(.*)('amdefine',?)/gm,
|
||||
'$1');
|
||||
return src;
|
||||
}
|
||||
removeAmdefine.onRead = true;
|
||||
|
||||
function makeNonRelative(src) {
|
||||
return src
|
||||
.replace(/require\('.\//g, 'require(\'source-map/')
|
||||
.replace(/\.\.\/\.\.\/lib\//g, '');
|
||||
}
|
||||
makeNonRelative.onRead = true;
|
||||
|
||||
function buildBrowser() {
|
||||
console.log('\nCreating dist/source-map.js');
|
||||
|
||||
var project = copy.createCommonJsProject({
|
||||
roots: [ path.join(__dirname, 'lib') ]
|
||||
});
|
||||
|
||||
copy({
|
||||
source: [
|
||||
'build/mini-require.js',
|
||||
{
|
||||
project: project,
|
||||
require: [ 'source-map/source-map-generator',
|
||||
'source-map/source-map-consumer',
|
||||
'source-map/source-node']
|
||||
},
|
||||
'build/suffix-browser.js'
|
||||
],
|
||||
filter: [
|
||||
copy.filter.moduleDefines,
|
||||
removeAmdefine
|
||||
],
|
||||
dest: 'dist/source-map.js'
|
||||
});
|
||||
}
|
||||
|
||||
function buildBrowserMin() {
|
||||
console.log('\nCreating dist/source-map.min.js');
|
||||
|
||||
copy({
|
||||
source: 'dist/source-map.js',
|
||||
filter: copy.filter.uglifyjs,
|
||||
dest: 'dist/source-map.min.js'
|
||||
});
|
||||
}
|
||||
|
||||
function buildFirefox() {
|
||||
console.log('\nCreating dist/SourceMap.jsm');
|
||||
|
||||
var project = copy.createCommonJsProject({
|
||||
roots: [ path.join(__dirname, 'lib') ]
|
||||
});
|
||||
|
||||
copy({
|
||||
source: [
|
||||
'build/prefix-source-map.jsm',
|
||||
{
|
||||
project: project,
|
||||
require: [ 'source-map/source-map-consumer',
|
||||
'source-map/source-map-generator',
|
||||
'source-map/source-node' ]
|
||||
},
|
||||
'build/suffix-source-map.jsm'
|
||||
],
|
||||
filter: [
|
||||
copy.filter.moduleDefines,
|
||||
removeAmdefine,
|
||||
makeNonRelative
|
||||
],
|
||||
dest: 'dist/SourceMap.jsm'
|
||||
});
|
||||
|
||||
// Create dist/test/Utils.jsm
|
||||
console.log('\nCreating dist/test/Utils.jsm');
|
||||
|
||||
project = copy.createCommonJsProject({
|
||||
roots: [ __dirname, path.join(__dirname, 'lib') ]
|
||||
});
|
||||
|
||||
copy({
|
||||
source: [
|
||||
'build/prefix-utils.jsm',
|
||||
'build/assert-shim.js',
|
||||
{
|
||||
project: project,
|
||||
require: [ 'test/source-map/util' ]
|
||||
},
|
||||
'build/suffix-utils.jsm'
|
||||
],
|
||||
filter: [
|
||||
copy.filter.moduleDefines,
|
||||
removeAmdefine,
|
||||
makeNonRelative
|
||||
],
|
||||
dest: 'dist/test/Utils.jsm'
|
||||
});
|
||||
|
||||
function isTestFile(f) {
|
||||
return /^test\-.*?\.js/.test(f);
|
||||
}
|
||||
|
||||
var testFiles = fs.readdirSync(path.join(__dirname, 'test', 'source-map')).filter(isTestFile);
|
||||
|
||||
testFiles.forEach(function (testFile) {
|
||||
console.log('\nCreating', path.join('dist', 'test', testFile.replace(/\-/g, '_')));
|
||||
|
||||
copy({
|
||||
source: [
|
||||
'build/test-prefix.js',
|
||||
path.join('test', 'source-map', testFile),
|
||||
'build/test-suffix.js'
|
||||
],
|
||||
filter: [
|
||||
removeAmdefine,
|
||||
makeNonRelative,
|
||||
function (input, source) {
|
||||
return input.replace('define(',
|
||||
'define("'
|
||||
+ path.join('test', 'source-map', testFile.replace(/\.js$/, ''))
|
||||
+ '", ["require", "exports", "module"], ');
|
||||
},
|
||||
function (input, source) {
|
||||
return input.replace('{THIS_MODULE}', function () {
|
||||
return "test/source-map/" + testFile.replace(/\.js$/, '');
|
||||
});
|
||||
}
|
||||
],
|
||||
dest: path.join('dist', 'test', testFile.replace(/\-/g, '_'))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function ensureDir(name) {
|
||||
var dirExists = false;
|
||||
try {
|
||||
dirExists = fs.statSync(name).isDirectory();
|
||||
} catch (err) {}
|
||||
|
||||
if (!dirExists) {
|
||||
fs.mkdirSync(name, 0777);
|
||||
}
|
||||
}
|
||||
|
||||
ensureDir("dist");
|
||||
ensureDir("dist/test");
|
||||
buildFirefox();
|
||||
buildBrowser();
|
||||
buildBrowserMin();
|
||||
Generated
Vendored
+479
@@ -0,0 +1,479 @@
|
||||
# Source Map
|
||||
|
||||
This is a library to generate and consume the source map format
|
||||
[described here][format].
|
||||
|
||||
This library is written in the Asynchronous Module Definition format, and works
|
||||
in the following environments:
|
||||
|
||||
* Modern Browsers supporting ECMAScript 5 (either after the build, or with an
|
||||
AMD loader such as RequireJS)
|
||||
|
||||
* Inside Firefox (as a JSM file, after the build)
|
||||
|
||||
* With NodeJS versions 0.8.X and higher
|
||||
|
||||
## Node
|
||||
|
||||
$ npm install source-map
|
||||
|
||||
## Building from Source (for everywhere else)
|
||||
|
||||
Install Node and then run
|
||||
|
||||
$ git clone https://fitzgen@github.com/mozilla/source-map.git
|
||||
$ cd source-map
|
||||
$ npm link .
|
||||
|
||||
Next, run
|
||||
|
||||
$ node Makefile.dryice.js
|
||||
|
||||
This should spew a bunch of stuff to stdout, and create the following files:
|
||||
|
||||
* `dist/source-map.js` - The unminified browser version.
|
||||
|
||||
* `dist/source-map.min.js` - The minified browser version.
|
||||
|
||||
* `dist/SourceMap.jsm` - The JavaScript Module for inclusion in Firefox source.
|
||||
|
||||
## Examples
|
||||
|
||||
### Consuming a source map
|
||||
|
||||
var rawSourceMap = {
|
||||
version: 3,
|
||||
file: 'min.js',
|
||||
names: ['bar', 'baz', 'n'],
|
||||
sources: ['one.js', 'two.js'],
|
||||
sourceRoot: 'http://example.com/www/js/',
|
||||
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
|
||||
};
|
||||
|
||||
var smc = new SourceMapConsumer(rawSourceMap);
|
||||
|
||||
console.log(smc.sources);
|
||||
// [ 'http://example.com/www/js/one.js',
|
||||
// 'http://example.com/www/js/two.js' ]
|
||||
|
||||
console.log(smc.originalPositionFor({
|
||||
line: 2,
|
||||
column: 28
|
||||
}));
|
||||
// { source: 'http://example.com/www/js/two.js',
|
||||
// line: 2,
|
||||
// column: 10,
|
||||
// name: 'n' }
|
||||
|
||||
console.log(smc.generatedPositionFor({
|
||||
source: 'http://example.com/www/js/two.js',
|
||||
line: 2,
|
||||
column: 10
|
||||
}));
|
||||
// { line: 2, column: 28 }
|
||||
|
||||
smc.eachMapping(function (m) {
|
||||
// ...
|
||||
});
|
||||
|
||||
### Generating a source map
|
||||
|
||||
In depth guide:
|
||||
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
|
||||
|
||||
#### With SourceNode (high level API)
|
||||
|
||||
function compile(ast) {
|
||||
switch (ast.type) {
|
||||
case 'BinaryExpression':
|
||||
return new SourceNode(
|
||||
ast.location.line,
|
||||
ast.location.column,
|
||||
ast.location.source,
|
||||
[compile(ast.left), " + ", compile(ast.right)]
|
||||
);
|
||||
case 'Literal':
|
||||
return new SourceNode(
|
||||
ast.location.line,
|
||||
ast.location.column,
|
||||
ast.location.source,
|
||||
String(ast.value)
|
||||
);
|
||||
// ...
|
||||
default:
|
||||
throw new Error("Bad AST");
|
||||
}
|
||||
}
|
||||
|
||||
var ast = parse("40 + 2", "add.js");
|
||||
console.log(compile(ast).toStringWithSourceMap({
|
||||
file: 'add.js'
|
||||
}));
|
||||
// { code: '40 + 2',
|
||||
// map: [object SourceMapGenerator] }
|
||||
|
||||
#### With SourceMapGenerator (low level API)
|
||||
|
||||
var map = new SourceMapGenerator({
|
||||
file: "source-mapped.js"
|
||||
});
|
||||
|
||||
map.addMapping({
|
||||
generated: {
|
||||
line: 10,
|
||||
column: 35
|
||||
},
|
||||
source: "foo.js",
|
||||
original: {
|
||||
line: 33,
|
||||
column: 2
|
||||
},
|
||||
name: "christopher"
|
||||
});
|
||||
|
||||
console.log(map.toString());
|
||||
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
|
||||
|
||||
## API
|
||||
|
||||
Get a reference to the module:
|
||||
|
||||
// NodeJS
|
||||
var sourceMap = require('source-map');
|
||||
|
||||
// Browser builds
|
||||
var sourceMap = window.sourceMap;
|
||||
|
||||
// Inside Firefox
|
||||
let sourceMap = {};
|
||||
Components.utils.import('resource:///modules/devtools/SourceMap.jsm', sourceMap);
|
||||
|
||||
### SourceMapConsumer
|
||||
|
||||
A SourceMapConsumer instance represents a parsed source map which we can query
|
||||
for information about the original file positions by giving it a file position
|
||||
in the generated source.
|
||||
|
||||
#### new SourceMapConsumer(rawSourceMap)
|
||||
|
||||
The only parameter is the raw source map (either as a string which can be
|
||||
`JSON.parse`'d, or an object). According to the spec, source maps have the
|
||||
following attributes:
|
||||
|
||||
* `version`: Which version of the source map spec this map is following.
|
||||
|
||||
* `sources`: An array of URLs to the original source files.
|
||||
|
||||
* `names`: An array of identifiers which can be referrenced by individual
|
||||
mappings.
|
||||
|
||||
* `sourceRoot`: Optional. The URL root from which all sources are relative.
|
||||
|
||||
* `sourcesContent`: Optional. An array of contents of the original source files.
|
||||
|
||||
* `mappings`: A string of base64 VLQs which contain the actual mappings.
|
||||
|
||||
* `file`: Optional. The generated filename this source map is associated with.
|
||||
|
||||
#### SourceMapConsumer.prototype.computeColumnSpans()
|
||||
|
||||
Compute the last column for each generated mapping. The last column is
|
||||
inclusive.
|
||||
|
||||
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
|
||||
|
||||
Returns the original source, line, and column information for the generated
|
||||
source's line and column positions provided. The only argument is an object with
|
||||
the following properties:
|
||||
|
||||
* `line`: The line number in the generated source.
|
||||
|
||||
* `column`: The column number in the generated source.
|
||||
|
||||
and an object is returned with the following properties:
|
||||
|
||||
* `source`: The original source file, or null if this information is not
|
||||
available.
|
||||
|
||||
* `line`: The line number in the original source, or null if this information is
|
||||
not available.
|
||||
|
||||
* `column`: The column number in the original source, or null or null if this
|
||||
information is not available.
|
||||
|
||||
* `name`: The original identifier, or null if this information is not available.
|
||||
|
||||
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
|
||||
|
||||
Returns the generated line and column information for the original source,
|
||||
line, and column positions provided. The only argument is an object with
|
||||
the following properties:
|
||||
|
||||
* `source`: The filename of the original source.
|
||||
|
||||
* `line`: The line number in the original source.
|
||||
|
||||
* `column`: The column number in the original source.
|
||||
|
||||
and an object is returned with the following properties:
|
||||
|
||||
* `line`: The line number in the generated source, or null.
|
||||
|
||||
* `column`: The column number in the generated source, or null.
|
||||
|
||||
#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
|
||||
|
||||
Returns all generated line and column information for the original source
|
||||
and line provided. The only argument is an object with the following
|
||||
properties:
|
||||
|
||||
* `source`: The filename of the original source.
|
||||
|
||||
* `line`: The line number in the original source.
|
||||
|
||||
and an array of objects is returned, each with the following properties:
|
||||
|
||||
* `line`: The line number in the generated source, or null.
|
||||
|
||||
* `column`: The column number in the generated source, or null.
|
||||
|
||||
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
|
||||
|
||||
Returns the original source content for the source provided. The only
|
||||
argument is the URL of the original source file.
|
||||
|
||||
If the source content for the given source is not found, then an error is
|
||||
thrown. Optionally, pass `true` as the second param to have `null` returned
|
||||
instead.
|
||||
|
||||
#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
|
||||
|
||||
Iterate over each mapping between an original source/line/column and a
|
||||
generated line/column in this source map.
|
||||
|
||||
* `callback`: The function that is called with each mapping. Mappings have the
|
||||
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
|
||||
name }`
|
||||
|
||||
* `context`: Optional. If specified, this object will be the value of `this`
|
||||
every time that `callback` is called.
|
||||
|
||||
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
|
||||
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
|
||||
the mappings sorted by the generated file's line/column order or the
|
||||
original's source/line/column order, respectively. Defaults to
|
||||
`SourceMapConsumer.GENERATED_ORDER`.
|
||||
|
||||
### SourceMapGenerator
|
||||
|
||||
An instance of the SourceMapGenerator represents a source map which is being
|
||||
built incrementally.
|
||||
|
||||
#### new SourceMapGenerator([startOfSourceMap])
|
||||
|
||||
You may pass an object with the following properties:
|
||||
|
||||
* `file`: The filename of the generated source that this source map is
|
||||
associated with.
|
||||
|
||||
* `sourceRoot`: A root for all relative URLs in this source map.
|
||||
|
||||
* `skipValidation`: Optional. When `true`, disables validation of mappings as
|
||||
they are added. This can improve performance but should be used with
|
||||
discretion, as a last resort. Even then, one should avoid using this flag when
|
||||
running tests, if possible.
|
||||
|
||||
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
|
||||
|
||||
Creates a new SourceMapGenerator based on a SourceMapConsumer
|
||||
|
||||
* `sourceMapConsumer` The SourceMap.
|
||||
|
||||
#### SourceMapGenerator.prototype.addMapping(mapping)
|
||||
|
||||
Add a single mapping from original source line and column to the generated
|
||||
source's line and column for this source map being created. The mapping object
|
||||
should have the following properties:
|
||||
|
||||
* `generated`: An object with the generated line and column positions.
|
||||
|
||||
* `original`: An object with the original line and column positions.
|
||||
|
||||
* `source`: The original source file (relative to the sourceRoot).
|
||||
|
||||
* `name`: An optional original token name for this mapping.
|
||||
|
||||
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
|
||||
|
||||
Set the source content for an original source file.
|
||||
|
||||
* `sourceFile` the URL of the original source file.
|
||||
|
||||
* `sourceContent` the content of the source file.
|
||||
|
||||
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
|
||||
|
||||
Applies a SourceMap for a source file to the SourceMap.
|
||||
Each mapping to the supplied source file is rewritten using the
|
||||
supplied SourceMap. Note: The resolution for the resulting mappings
|
||||
is the minimium of this map and the supplied map.
|
||||
|
||||
* `sourceMapConsumer`: The SourceMap to be applied.
|
||||
|
||||
* `sourceFile`: Optional. The filename of the source file.
|
||||
If omitted, sourceMapConsumer.file will be used, if it exists.
|
||||
Otherwise an error will be thrown.
|
||||
|
||||
* `sourceMapPath`: Optional. The dirname of the path to the SourceMap
|
||||
to be applied. If relative, it is relative to the SourceMap.
|
||||
|
||||
This parameter is needed when the two SourceMaps aren't in the same
|
||||
directory, and the SourceMap to be applied contains relative source
|
||||
paths. If so, those relative source paths need to be rewritten
|
||||
relative to the SourceMap.
|
||||
|
||||
If omitted, it is assumed that both SourceMaps are in the same directory,
|
||||
thus not needing any rewriting. (Supplying `'.'` has the same effect.)
|
||||
|
||||
#### SourceMapGenerator.prototype.toString()
|
||||
|
||||
Renders the source map being generated to a string.
|
||||
|
||||
### SourceNode
|
||||
|
||||
SourceNodes provide a way to abstract over interpolating and/or concatenating
|
||||
snippets of generated JavaScript source code, while maintaining the line and
|
||||
column information associated between those snippets and the original source
|
||||
code. This is useful as the final intermediate representation a compiler might
|
||||
use before outputting the generated JS and source map.
|
||||
|
||||
#### new SourceNode([line, column, source[, chunk[, name]]])
|
||||
|
||||
* `line`: The original line number associated with this source node, or null if
|
||||
it isn't associated with an original line.
|
||||
|
||||
* `column`: The original column number associated with this source node, or null
|
||||
if it isn't associated with an original column.
|
||||
|
||||
* `source`: The original source's filename; null if no filename is provided.
|
||||
|
||||
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
|
||||
below.
|
||||
|
||||
* `name`: Optional. The original identifier.
|
||||
|
||||
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
|
||||
|
||||
Creates a SourceNode from generated code and a SourceMapConsumer.
|
||||
|
||||
* `code`: The generated code
|
||||
|
||||
* `sourceMapConsumer` The SourceMap for the generated code
|
||||
|
||||
* `relativePath` The optional path that relative sources in `sourceMapConsumer`
|
||||
should be relative to.
|
||||
|
||||
#### SourceNode.prototype.add(chunk)
|
||||
|
||||
Add a chunk of generated JS to this source node.
|
||||
|
||||
* `chunk`: A string snippet of generated JS code, another instance of
|
||||
`SourceNode`, or an array where each member is one of those things.
|
||||
|
||||
#### SourceNode.prototype.prepend(chunk)
|
||||
|
||||
Prepend a chunk of generated JS to this source node.
|
||||
|
||||
* `chunk`: A string snippet of generated JS code, another instance of
|
||||
`SourceNode`, or an array where each member is one of those things.
|
||||
|
||||
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
|
||||
|
||||
Set the source content for a source file. This will be added to the
|
||||
`SourceMap` in the `sourcesContent` field.
|
||||
|
||||
* `sourceFile`: The filename of the source file
|
||||
|
||||
* `sourceContent`: The content of the source file
|
||||
|
||||
#### SourceNode.prototype.walk(fn)
|
||||
|
||||
Walk over the tree of JS snippets in this node and its children. The walking
|
||||
function is called once for each snippet of JS and is passed that snippet and
|
||||
the its original associated source's line/column location.
|
||||
|
||||
* `fn`: The traversal function.
|
||||
|
||||
#### SourceNode.prototype.walkSourceContents(fn)
|
||||
|
||||
Walk over the tree of SourceNodes. The walking function is called for each
|
||||
source file content and is passed the filename and source content.
|
||||
|
||||
* `fn`: The traversal function.
|
||||
|
||||
#### SourceNode.prototype.join(sep)
|
||||
|
||||
Like `Array.prototype.join` except for SourceNodes. Inserts the separator
|
||||
between each of this source node's children.
|
||||
|
||||
* `sep`: The separator.
|
||||
|
||||
#### SourceNode.prototype.replaceRight(pattern, replacement)
|
||||
|
||||
Call `String.prototype.replace` on the very right-most source snippet. Useful
|
||||
for trimming whitespace from the end of a source node, etc.
|
||||
|
||||
* `pattern`: The pattern to replace.
|
||||
|
||||
* `replacement`: The thing to replace the pattern with.
|
||||
|
||||
#### SourceNode.prototype.toString()
|
||||
|
||||
Return the string representation of this source node. Walks over the tree and
|
||||
concatenates all the various snippets together to one string.
|
||||
|
||||
#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
|
||||
|
||||
Returns the string representation of this tree of source nodes, plus a
|
||||
SourceMapGenerator which contains all the mappings between the generated and
|
||||
original sources.
|
||||
|
||||
The arguments are the same as those to `new SourceMapGenerator`.
|
||||
|
||||
## Tests
|
||||
|
||||
[](https://travis-ci.org/mozilla/source-map)
|
||||
|
||||
Install NodeJS version 0.8.0 or greater, then run `node test/run-tests.js`.
|
||||
|
||||
To add new tests, create a new file named `test/test-<your new test name>.js`
|
||||
and export your test functions with names that start with "test", for example
|
||||
|
||||
exports["test doing the foo bar"] = function (assert, util) {
|
||||
...
|
||||
};
|
||||
|
||||
The new test will be located automatically when you run the suite.
|
||||
|
||||
The `util` argument is the test utility module located at `test/source-map/util`.
|
||||
|
||||
The `assert` argument is a cut down version of node's assert module. You have
|
||||
access to the following assertion functions:
|
||||
|
||||
* `doesNotThrow`
|
||||
|
||||
* `equal`
|
||||
|
||||
* `ok`
|
||||
|
||||
* `strictEqual`
|
||||
|
||||
* `throws`
|
||||
|
||||
(The reason for the restricted set of test functions is because we need the
|
||||
tests to run inside Firefox's test suite as well and so the assert module is
|
||||
shimmed in that environment. See `build/assert-shim.js`.)
|
||||
|
||||
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
|
||||
[feature]: https://wiki.mozilla.org/DevTools/Features/SourceMap
|
||||
[Dryice]: https://github.com/mozilla/dryice
|
||||
Generated
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
define('test/source-map/assert', ['exports'], function (exports) {
|
||||
|
||||
let do_throw = function (msg) {
|
||||
throw new Error(msg);
|
||||
};
|
||||
|
||||
exports.init = function (throw_fn) {
|
||||
do_throw = throw_fn;
|
||||
};
|
||||
|
||||
exports.doesNotThrow = function (fn) {
|
||||
try {
|
||||
fn();
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
exports.equal = function (actual, expected, msg) {
|
||||
msg = msg || String(actual) + ' != ' + String(expected);
|
||||
if (actual != expected) {
|
||||
do_throw(msg);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ok = function (val, msg) {
|
||||
msg = msg || String(val) + ' is falsey';
|
||||
if (!Boolean(val)) {
|
||||
do_throw(msg);
|
||||
}
|
||||
};
|
||||
|
||||
exports.strictEqual = function (actual, expected, msg) {
|
||||
msg = msg || String(actual) + ' !== ' + String(expected);
|
||||
if (actual !== expected) {
|
||||
do_throw(msg);
|
||||
}
|
||||
};
|
||||
|
||||
exports.throws = function (fn) {
|
||||
try {
|
||||
fn();
|
||||
do_throw('Expected an error to be thrown, but it wasn\'t.');
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
Generated
Vendored
+152
@@ -0,0 +1,152 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define a module along with a payload.
|
||||
* @param {string} moduleName Name for the payload
|
||||
* @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec
|
||||
* @param {function} payload Function with (require, exports, module) params
|
||||
*/
|
||||
function define(moduleName, deps, payload) {
|
||||
if (typeof moduleName != "string") {
|
||||
throw new TypeError('Expected string, got: ' + moduleName);
|
||||
}
|
||||
|
||||
if (arguments.length == 2) {
|
||||
payload = deps;
|
||||
}
|
||||
|
||||
if (moduleName in define.modules) {
|
||||
throw new Error("Module already defined: " + moduleName);
|
||||
}
|
||||
define.modules[moduleName] = payload;
|
||||
};
|
||||
|
||||
/**
|
||||
* The global store of un-instantiated modules
|
||||
*/
|
||||
define.modules = {};
|
||||
|
||||
|
||||
/**
|
||||
* We invoke require() in the context of a Domain so we can have multiple
|
||||
* sets of modules running separate from each other.
|
||||
* This contrasts with JSMs which are singletons, Domains allows us to
|
||||
* optionally load a CommonJS module twice with separate data each time.
|
||||
* Perhaps you want 2 command lines with a different set of commands in each,
|
||||
* for example.
|
||||
*/
|
||||
function Domain() {
|
||||
this.modules = {};
|
||||
this._currentModule = null;
|
||||
}
|
||||
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* Lookup module names and resolve them by calling the definition function if
|
||||
* needed.
|
||||
* There are 2 ways to call this, either with an array of dependencies and a
|
||||
* callback to call when the dependencies are found (which can happen
|
||||
* asynchronously in an in-page context) or with a single string an no callback
|
||||
* where the dependency is resolved synchronously and returned.
|
||||
* The API is designed to be compatible with the CommonJS AMD spec and
|
||||
* RequireJS.
|
||||
* @param {string[]|string} deps A name, or names for the payload
|
||||
* @param {function|undefined} callback Function to call when the dependencies
|
||||
* are resolved
|
||||
* @return {undefined|object} The module required or undefined for
|
||||
* array/callback method
|
||||
*/
|
||||
Domain.prototype.require = function(deps, callback) {
|
||||
if (Array.isArray(deps)) {
|
||||
var params = deps.map(function(dep) {
|
||||
return this.lookup(dep);
|
||||
}, this);
|
||||
if (callback) {
|
||||
callback.apply(null, params);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
return this.lookup(deps);
|
||||
}
|
||||
};
|
||||
|
||||
function normalize(path) {
|
||||
var bits = path.split('/');
|
||||
var i = 1;
|
||||
while (i < bits.length) {
|
||||
if (bits[i] === '..') {
|
||||
bits.splice(i-1, 1);
|
||||
} else if (bits[i] === '.') {
|
||||
bits.splice(i, 1);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return bits.join('/');
|
||||
}
|
||||
|
||||
function join(a, b) {
|
||||
a = a.trim();
|
||||
b = b.trim();
|
||||
if (/^\//.test(b)) {
|
||||
return b;
|
||||
} else {
|
||||
return a.replace(/\/*$/, '/') + b;
|
||||
}
|
||||
}
|
||||
|
||||
function dirname(path) {
|
||||
var bits = path.split('/');
|
||||
bits.pop();
|
||||
return bits.join('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup module names and resolve them by calling the definition function if
|
||||
* needed.
|
||||
* @param {string} moduleName A name for the payload to lookup
|
||||
* @return {object} The module specified by aModuleName or null if not found.
|
||||
*/
|
||||
Domain.prototype.lookup = function(moduleName) {
|
||||
if (/^\./.test(moduleName)) {
|
||||
moduleName = normalize(join(dirname(this._currentModule), moduleName));
|
||||
}
|
||||
|
||||
if (moduleName in this.modules) {
|
||||
var module = this.modules[moduleName];
|
||||
return module;
|
||||
}
|
||||
|
||||
if (!(moduleName in define.modules)) {
|
||||
throw new Error("Module not defined: " + moduleName);
|
||||
}
|
||||
|
||||
var module = define.modules[moduleName];
|
||||
|
||||
if (typeof module == "function") {
|
||||
var exports = {};
|
||||
var previousModule = this._currentModule;
|
||||
this._currentModule = moduleName;
|
||||
module(this.require.bind(this), exports, { id: moduleName, uri: "" });
|
||||
this._currentModule = previousModule;
|
||||
module = exports;
|
||||
}
|
||||
|
||||
// cache the resulting module object for next time
|
||||
this.modules[moduleName] = module;
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
define.Domain = Domain;
|
||||
define.globalDomain = new Domain();
|
||||
var require = define.globalDomain.require.bind(define.globalDomain);
|
||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* WARNING!
|
||||
*
|
||||
* Do not edit this file directly, it is built from the sources at
|
||||
* https://github.com/mozilla/source-map/
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "SourceMapConsumer", "SourceMapGenerator", "SourceNode" ];
|
||||
|
||||
Components.utils.import('resource://gre/modules/devtools/Require.jsm');
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* WARNING!
|
||||
*
|
||||
* Do not edit this file directly, it is built from the sources at
|
||||
* https://github.com/mozilla/source-map/
|
||||
*/
|
||||
|
||||
Components.utils.import('resource://gre/modules/devtools/Require.jsm');
|
||||
Components.utils.import('resource://gre/modules/devtools/SourceMap.jsm');
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "define", "runSourceMapTests" ];
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
this.sourceMap = {
|
||||
SourceMapConsumer: require('source-map/source-map-consumer').SourceMapConsumer,
|
||||
SourceMapGenerator: require('source-map/source-map-generator').SourceMapGenerator,
|
||||
SourceNode: require('source-map/source-node').SourceNode
|
||||
};
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
this.SourceMapConsumer = require('source-map/source-map-consumer').SourceMapConsumer;
|
||||
this.SourceMapGenerator = require('source-map/source-map-generator').SourceMapGenerator;
|
||||
this.SourceNode = require('source-map/source-node').SourceNode;
|
||||
Generated
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
function runSourceMapTests(modName, do_throw) {
|
||||
let mod = require(modName);
|
||||
let assert = require('test/source-map/assert');
|
||||
let util = require('test/source-map/util');
|
||||
|
||||
assert.init(do_throw);
|
||||
|
||||
for (let k in mod) {
|
||||
if (/^test/.test(k)) {
|
||||
mod[k](assert, util);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.runSourceMapTests = runSourceMapTests;
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* WARNING!
|
||||
*
|
||||
* Do not edit this file directly, it is built from the sources at
|
||||
* https://github.com/mozilla/source-map/
|
||||
*/
|
||||
|
||||
Components.utils.import('resource://test/Utils.jsm');
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
function run_test() {
|
||||
runSourceMapTests('{THIS_MODULE}', do_throw);
|
||||
}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
exports.SourceMapGenerator = require('./source-map/source-map-generator').SourceMapGenerator;
|
||||
exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
|
||||
exports.SourceNode = require('./source-map/source-node').SourceNode;
|
||||
Generated
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* A data structure which is a combination of an array and a set. Adding a new
|
||||
* member is O(1), testing for membership is O(1), and finding the index of an
|
||||
* element is O(1). Removing elements from the set is not supported. Only
|
||||
* strings are supported for membership.
|
||||
*/
|
||||
function ArraySet() {
|
||||
this._array = [];
|
||||
this._set = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for creating ArraySet instances from an existing array.
|
||||
*/
|
||||
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
|
||||
var set = new ArraySet();
|
||||
for (var i = 0, len = aArray.length; i < len; i++) {
|
||||
set.add(aArray[i], aAllowDuplicates);
|
||||
}
|
||||
return set;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given string to this set.
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
|
||||
var isDuplicate = this.has(aStr);
|
||||
var idx = this._array.length;
|
||||
if (!isDuplicate || aAllowDuplicates) {
|
||||
this._array.push(aStr);
|
||||
}
|
||||
if (!isDuplicate) {
|
||||
this._set[util.toSetString(aStr)] = idx;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Is the given string a member of this set?
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.has = function ArraySet_has(aStr) {
|
||||
return Object.prototype.hasOwnProperty.call(this._set,
|
||||
util.toSetString(aStr));
|
||||
};
|
||||
|
||||
/**
|
||||
* What is the index of the given string in the array?
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
|
||||
if (this.has(aStr)) {
|
||||
return this._set[util.toSetString(aStr)];
|
||||
}
|
||||
throw new Error('"' + aStr + '" is not in the set.');
|
||||
};
|
||||
|
||||
/**
|
||||
* What is the element at the given index?
|
||||
*
|
||||
* @param Number aIdx
|
||||
*/
|
||||
ArraySet.prototype.at = function ArraySet_at(aIdx) {
|
||||
if (aIdx >= 0 && aIdx < this._array.length) {
|
||||
return this._array[aIdx];
|
||||
}
|
||||
throw new Error('No element indexed by ' + aIdx);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the array representation of this set (which has the proper indices
|
||||
* indicated by indexOf). Note that this is a copy of the internal array used
|
||||
* for storing the members so that no one can mess with internal state.
|
||||
*/
|
||||
ArraySet.prototype.toArray = function ArraySet_toArray() {
|
||||
return this._array.slice();
|
||||
};
|
||||
|
||||
exports.ArraySet = ArraySet;
|
||||
|
||||
});
|
||||
Generated
Vendored
+142
@@ -0,0 +1,142 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Based on the Base 64 VLQ implementation in Closure Compiler:
|
||||
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
|
||||
*
|
||||
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var base64 = require('./base64');
|
||||
|
||||
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
|
||||
// length quantities we use in the source map spec, the first bit is the sign,
|
||||
// the next four bits are the actual value, and the 6th bit is the
|
||||
// continuation bit. The continuation bit tells us whether there are more
|
||||
// digits in this value following this digit.
|
||||
//
|
||||
// Continuation
|
||||
// | Sign
|
||||
// | |
|
||||
// V V
|
||||
// 101011
|
||||
|
||||
var VLQ_BASE_SHIFT = 5;
|
||||
|
||||
// binary: 100000
|
||||
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
||||
|
||||
// binary: 011111
|
||||
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
||||
|
||||
// binary: 100000
|
||||
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
||||
|
||||
/**
|
||||
* Converts from a two-complement value to a value where the sign bit is
|
||||
* placed in the least significant bit. For example, as decimals:
|
||||
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
|
||||
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
|
||||
*/
|
||||
function toVLQSigned(aValue) {
|
||||
return aValue < 0
|
||||
? ((-aValue) << 1) + 1
|
||||
: (aValue << 1) + 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to a two-complement value from a value where the sign bit is
|
||||
* placed in the least significant bit. For example, as decimals:
|
||||
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
|
||||
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
|
||||
*/
|
||||
function fromVLQSigned(aValue) {
|
||||
var isNegative = (aValue & 1) === 1;
|
||||
var shifted = aValue >> 1;
|
||||
return isNegative
|
||||
? -shifted
|
||||
: shifted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base 64 VLQ encoded value.
|
||||
*/
|
||||
exports.encode = function base64VLQ_encode(aValue) {
|
||||
var encoded = "";
|
||||
var digit;
|
||||
|
||||
var vlq = toVLQSigned(aValue);
|
||||
|
||||
do {
|
||||
digit = vlq & VLQ_BASE_MASK;
|
||||
vlq >>>= VLQ_BASE_SHIFT;
|
||||
if (vlq > 0) {
|
||||
// There are still more digits in this value, so we must make sure the
|
||||
// continuation bit is marked.
|
||||
digit |= VLQ_CONTINUATION_BIT;
|
||||
}
|
||||
encoded += base64.encode(digit);
|
||||
} while (vlq > 0);
|
||||
|
||||
return encoded;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes the next base 64 VLQ value from the given string and returns the
|
||||
* value and the rest of the string via the out parameter.
|
||||
*/
|
||||
exports.decode = function base64VLQ_decode(aStr, aOutParam) {
|
||||
var i = 0;
|
||||
var strLen = aStr.length;
|
||||
var result = 0;
|
||||
var shift = 0;
|
||||
var continuation, digit;
|
||||
|
||||
do {
|
||||
if (i >= strLen) {
|
||||
throw new Error("Expected more digits in base 64 VLQ value.");
|
||||
}
|
||||
digit = base64.decode(aStr.charAt(i++));
|
||||
continuation = !!(digit & VLQ_CONTINUATION_BIT);
|
||||
digit &= VLQ_BASE_MASK;
|
||||
result = result + (digit << shift);
|
||||
shift += VLQ_BASE_SHIFT;
|
||||
} while (continuation);
|
||||
|
||||
aOutParam.value = fromVLQSigned(result);
|
||||
aOutParam.rest = aStr.slice(i);
|
||||
};
|
||||
|
||||
});
|
||||
Generated
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var charToIntMap = {};
|
||||
var intToCharMap = {};
|
||||
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
.split('')
|
||||
.forEach(function (ch, index) {
|
||||
charToIntMap[ch] = index;
|
||||
intToCharMap[index] = ch;
|
||||
});
|
||||
|
||||
/**
|
||||
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
|
||||
*/
|
||||
exports.encode = function base64_encode(aNumber) {
|
||||
if (aNumber in intToCharMap) {
|
||||
return intToCharMap[aNumber];
|
||||
}
|
||||
throw new TypeError("Must be between 0 and 63: " + aNumber);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode a single base 64 digit to an integer.
|
||||
*/
|
||||
exports.decode = function base64_decode(aChar) {
|
||||
if (aChar in charToIntMap) {
|
||||
return charToIntMap[aChar];
|
||||
}
|
||||
throw new TypeError("Not a valid base 64 digit: " + aChar);
|
||||
};
|
||||
|
||||
});
|
||||
Generated
Vendored
+420
@@ -0,0 +1,420 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var util = require('./util');
|
||||
var binarySearch = require('./binary-search');
|
||||
var ArraySet = require('./array-set').ArraySet;
|
||||
var base64VLQ = require('./base64-vlq');
|
||||
var SourceMapConsumer = require('./source-map-consumer').SourceMapConsumer;
|
||||
|
||||
/**
|
||||
* A BasicSourceMapConsumer instance represents a parsed source map which we can
|
||||
* query for information about the original file positions by giving it a file
|
||||
* position in the generated source.
|
||||
*
|
||||
* The only parameter is the raw source map (either as a JSON string, or
|
||||
* already parsed to an object). According to the spec, source maps have the
|
||||
* following attributes:
|
||||
*
|
||||
* - version: Which version of the source map spec this map is following.
|
||||
* - sources: An array of URLs to the original source files.
|
||||
* - names: An array of identifiers which can be referrenced by individual mappings.
|
||||
* - sourceRoot: Optional. The URL root from which all sources are relative.
|
||||
* - sourcesContent: Optional. An array of contents of the original source files.
|
||||
* - mappings: A string of base64 VLQs which contain the actual mappings.
|
||||
* - file: Optional. The generated file this source map is associated with.
|
||||
*
|
||||
* Here is an example source map, taken from the source map spec[0]:
|
||||
*
|
||||
* {
|
||||
* version : 3,
|
||||
* file: "out.js",
|
||||
* sourceRoot : "",
|
||||
* sources: ["foo.js", "bar.js"],
|
||||
* names: ["src", "maps", "are", "fun"],
|
||||
* mappings: "AA,AB;;ABCDE;"
|
||||
* }
|
||||
*
|
||||
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
|
||||
*/
|
||||
function BasicSourceMapConsumer(aSourceMap) {
|
||||
var sourceMap = aSourceMap;
|
||||
if (typeof aSourceMap === 'string') {
|
||||
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
|
||||
}
|
||||
|
||||
var version = util.getArg(sourceMap, 'version');
|
||||
var sources = util.getArg(sourceMap, 'sources');
|
||||
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
|
||||
// requires the array) to play nice here.
|
||||
var names = util.getArg(sourceMap, 'names', []);
|
||||
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
|
||||
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
|
||||
var mappings = util.getArg(sourceMap, 'mappings');
|
||||
var file = util.getArg(sourceMap, 'file', null);
|
||||
|
||||
// Once again, Sass deviates from the spec and supplies the version as a
|
||||
// string rather than a number, so we use loose equality checking here.
|
||||
if (version != this._version) {
|
||||
throw new Error('Unsupported version: ' + version);
|
||||
}
|
||||
|
||||
// Some source maps produce relative source paths like "./foo.js" instead of
|
||||
// "foo.js". Normalize these first so that future comparisons will succeed.
|
||||
// See bugzil.la/1090768.
|
||||
sources = sources.map(util.normalize);
|
||||
|
||||
// Pass `true` below to allow duplicate names and sources. While source maps
|
||||
// are intended to be compressed and deduplicated, the TypeScript compiler
|
||||
// sometimes generates source maps with duplicates in them. See Github issue
|
||||
// #72 and bugzil.la/889492.
|
||||
this._names = ArraySet.fromArray(names, true);
|
||||
this._sources = ArraySet.fromArray(sources, true);
|
||||
|
||||
this.sourceRoot = sourceRoot;
|
||||
this.sourcesContent = sourcesContent;
|
||||
this._mappings = mappings;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
||||
BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
|
||||
|
||||
/**
|
||||
* Create a BasicSourceMapConsumer from a SourceMapGenerator.
|
||||
*
|
||||
* @param SourceMapGenerator aSourceMap
|
||||
* The source map that will be consumed.
|
||||
* @returns BasicSourceMapConsumer
|
||||
*/
|
||||
BasicSourceMapConsumer.fromSourceMap =
|
||||
function SourceMapConsumer_fromSourceMap(aSourceMap) {
|
||||
var smc = Object.create(BasicSourceMapConsumer.prototype);
|
||||
|
||||
smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
|
||||
smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
|
||||
smc.sourceRoot = aSourceMap._sourceRoot;
|
||||
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
|
||||
smc.sourceRoot);
|
||||
smc.file = aSourceMap._file;
|
||||
|
||||
smc.__generatedMappings = aSourceMap._mappings.toArray().slice();
|
||||
smc.__originalMappings = aSourceMap._mappings.toArray().slice()
|
||||
.sort(util.compareByOriginalPositions);
|
||||
|
||||
return smc;
|
||||
};
|
||||
|
||||
/**
|
||||
* The version of the source mapping spec that we are consuming.
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype._version = 3;
|
||||
|
||||
/**
|
||||
* The list of original sources.
|
||||
*/
|
||||
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
|
||||
get: function () {
|
||||
return this._sources.toArray().map(function (s) {
|
||||
return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse the mappings in a string in to a data structure which we can easily
|
||||
* query (the ordered arrays in the `this.__generatedMappings` and
|
||||
* `this.__originalMappings` properties).
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype._parseMappings =
|
||||
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
||||
var generatedLine = 1;
|
||||
var previousGeneratedColumn = 0;
|
||||
var previousOriginalLine = 0;
|
||||
var previousOriginalColumn = 0;
|
||||
var previousSource = 0;
|
||||
var previousName = 0;
|
||||
var str = aStr;
|
||||
var temp = {};
|
||||
var mapping;
|
||||
|
||||
while (str.length > 0) {
|
||||
if (str.charAt(0) === ';') {
|
||||
generatedLine++;
|
||||
str = str.slice(1);
|
||||
previousGeneratedColumn = 0;
|
||||
}
|
||||
else if (str.charAt(0) === ',') {
|
||||
str = str.slice(1);
|
||||
}
|
||||
else {
|
||||
mapping = {};
|
||||
mapping.generatedLine = generatedLine;
|
||||
|
||||
// Generated column.
|
||||
base64VLQ.decode(str, temp);
|
||||
mapping.generatedColumn = previousGeneratedColumn + temp.value;
|
||||
previousGeneratedColumn = mapping.generatedColumn;
|
||||
str = temp.rest;
|
||||
|
||||
if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) {
|
||||
// Original source.
|
||||
base64VLQ.decode(str, temp);
|
||||
mapping.source = this._sources.at(previousSource + temp.value);
|
||||
previousSource += temp.value;
|
||||
str = temp.rest;
|
||||
if (str.length === 0 || this._nextCharIsMappingSeparator(str)) {
|
||||
throw new Error('Found a source, but no line and column');
|
||||
}
|
||||
|
||||
// Original line.
|
||||
base64VLQ.decode(str, temp);
|
||||
mapping.originalLine = previousOriginalLine + temp.value;
|
||||
previousOriginalLine = mapping.originalLine;
|
||||
// Lines are stored 0-based
|
||||
mapping.originalLine += 1;
|
||||
str = temp.rest;
|
||||
if (str.length === 0 || this._nextCharIsMappingSeparator(str)) {
|
||||
throw new Error('Found a source and line, but no column');
|
||||
}
|
||||
|
||||
// Original column.
|
||||
base64VLQ.decode(str, temp);
|
||||
mapping.originalColumn = previousOriginalColumn + temp.value;
|
||||
previousOriginalColumn = mapping.originalColumn;
|
||||
str = temp.rest;
|
||||
|
||||
if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) {
|
||||
// Original name.
|
||||
base64VLQ.decode(str, temp);
|
||||
mapping.name = this._names.at(previousName + temp.value);
|
||||
previousName += temp.value;
|
||||
str = temp.rest;
|
||||
}
|
||||
}
|
||||
|
||||
this.__generatedMappings.push(mapping);
|
||||
if (typeof mapping.originalLine === 'number') {
|
||||
this.__originalMappings.push(mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.__generatedMappings.sort(util.compareByGeneratedPositions);
|
||||
this.__originalMappings.sort(util.compareByOriginalPositions);
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the mapping that best matches the hypothetical "needle" mapping that
|
||||
* we are searching for in the given "haystack" of mappings.
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype._findMapping =
|
||||
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
|
||||
aColumnName, aComparator) {
|
||||
// To return the position we are searching for, we must first find the
|
||||
// mapping for the given position and then return the opposite position it
|
||||
// points to. Because the mappings are sorted, we can use binary search to
|
||||
// find the best mapping.
|
||||
|
||||
if (aNeedle[aLineName] <= 0) {
|
||||
throw new TypeError('Line must be greater than or equal to 1, got '
|
||||
+ aNeedle[aLineName]);
|
||||
}
|
||||
if (aNeedle[aColumnName] < 0) {
|
||||
throw new TypeError('Column must be greater than or equal to 0, got '
|
||||
+ aNeedle[aColumnName]);
|
||||
}
|
||||
|
||||
return binarySearch.search(aNeedle, aMappings, aComparator);
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the last column for each generated mapping. The last column is
|
||||
* inclusive.
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype.computeColumnSpans =
|
||||
function SourceMapConsumer_computeColumnSpans() {
|
||||
for (var index = 0; index < this._generatedMappings.length; ++index) {
|
||||
var mapping = this._generatedMappings[index];
|
||||
|
||||
// Mappings do not contain a field for the last generated columnt. We
|
||||
// can come up with an optimistic estimate, however, by assuming that
|
||||
// mappings are contiguous (i.e. given two consecutive mappings, the
|
||||
// first mapping ends where the second one starts).
|
||||
if (index + 1 < this._generatedMappings.length) {
|
||||
var nextMapping = this._generatedMappings[index + 1];
|
||||
|
||||
if (mapping.generatedLine === nextMapping.generatedLine) {
|
||||
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The last mapping for each line spans the entire line.
|
||||
mapping.lastGeneratedColumn = Infinity;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the original source, line, and column information for the generated
|
||||
* source's line and column positions provided. The only argument is an object
|
||||
* with the following properties:
|
||||
*
|
||||
* - line: The line number in the generated source.
|
||||
* - column: The column number in the generated source.
|
||||
*
|
||||
* and an object is returned with the following properties:
|
||||
*
|
||||
* - source: The original source file, or null.
|
||||
* - line: The line number in the original source, or null.
|
||||
* - column: The column number in the original source, or null.
|
||||
* - name: The original identifier, or null.
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype.originalPositionFor =
|
||||
function SourceMapConsumer_originalPositionFor(aArgs) {
|
||||
var needle = {
|
||||
generatedLine: util.getArg(aArgs, 'line'),
|
||||
generatedColumn: util.getArg(aArgs, 'column')
|
||||
};
|
||||
|
||||
var index = this._findMapping(needle,
|
||||
this._generatedMappings,
|
||||
"generatedLine",
|
||||
"generatedColumn",
|
||||
util.compareByGeneratedPositions);
|
||||
|
||||
if (index >= 0) {
|
||||
var mapping = this._generatedMappings[index];
|
||||
|
||||
if (mapping.generatedLine === needle.generatedLine) {
|
||||
var source = util.getArg(mapping, 'source', null);
|
||||
if (source != null && this.sourceRoot != null) {
|
||||
source = util.join(this.sourceRoot, source);
|
||||
}
|
||||
return {
|
||||
source: source,
|
||||
line: util.getArg(mapping, 'originalLine', null),
|
||||
column: util.getArg(mapping, 'originalColumn', null),
|
||||
name: util.getArg(mapping, 'name', null)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
source: null,
|
||||
line: null,
|
||||
column: null,
|
||||
name: null
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the original source content. The only argument is the url of the
|
||||
* original source file. Returns null if no original source content is
|
||||
* availible.
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype.sourceContentFor =
|
||||
function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
||||
if (!this.sourcesContent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.sourceRoot != null) {
|
||||
aSource = util.relative(this.sourceRoot, aSource);
|
||||
}
|
||||
|
||||
if (this._sources.has(aSource)) {
|
||||
return this.sourcesContent[this._sources.indexOf(aSource)];
|
||||
}
|
||||
|
||||
var url;
|
||||
if (this.sourceRoot != null
|
||||
&& (url = util.urlParse(this.sourceRoot))) {
|
||||
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
|
||||
// many users. We can help them out when they expect file:// URIs to
|
||||
// behave like it would if they were running a local HTTP server. See
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
|
||||
var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
|
||||
if (url.scheme == "file"
|
||||
&& this._sources.has(fileUriAbsPath)) {
|
||||
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
|
||||
}
|
||||
|
||||
if ((!url.path || url.path == "/")
|
||||
&& this._sources.has("/" + aSource)) {
|
||||
return this.sourcesContent[this._sources.indexOf("/" + aSource)];
|
||||
}
|
||||
}
|
||||
|
||||
// This function is used recursively from
|
||||
// IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
|
||||
// don't want to throw if we can't find the source - we just want to
|
||||
// return null, so we provide a flag to exit gracefully.
|
||||
if (nullOnMissing) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw new Error('"' + aSource + '" is not in the SourceMap.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the generated line and column information for the original source,
|
||||
* line, and column positions provided. The only argument is an object with
|
||||
* the following properties:
|
||||
*
|
||||
* - source: The filename of the original source.
|
||||
* - line: The line number in the original source.
|
||||
* - column: The column number in the original source.
|
||||
*
|
||||
* and an object is returned with the following properties:
|
||||
*
|
||||
* - line: The line number in the generated source, or null.
|
||||
* - column: The column number in the generated source, or null.
|
||||
*/
|
||||
BasicSourceMapConsumer.prototype.generatedPositionFor =
|
||||
function SourceMapConsumer_generatedPositionFor(aArgs) {
|
||||
var needle = {
|
||||
source: util.getArg(aArgs, 'source'),
|
||||
originalLine: util.getArg(aArgs, 'line'),
|
||||
originalColumn: util.getArg(aArgs, 'column')
|
||||
};
|
||||
|
||||
if (this.sourceRoot != null) {
|
||||
needle.source = util.relative(this.sourceRoot, needle.source);
|
||||
}
|
||||
|
||||
var index = this._findMapping(needle,
|
||||
this._originalMappings,
|
||||
"originalLine",
|
||||
"originalColumn",
|
||||
util.compareByOriginalPositions);
|
||||
|
||||
if (index >= 0) {
|
||||
var mapping = this._originalMappings[index];
|
||||
|
||||
return {
|
||||
line: util.getArg(mapping, 'generatedLine', null),
|
||||
column: util.getArg(mapping, 'generatedColumn', null),
|
||||
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
line: null,
|
||||
column: null,
|
||||
lastColumn: null
|
||||
};
|
||||
};
|
||||
|
||||
exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
|
||||
|
||||
});
|
||||
Generated
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* Recursive implementation of binary search.
|
||||
*
|
||||
* @param aLow Indices here and lower do not contain the needle.
|
||||
* @param aHigh Indices here and higher do not contain the needle.
|
||||
* @param aNeedle The element being searched for.
|
||||
* @param aHaystack The non-empty array being searched.
|
||||
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
|
||||
*/
|
||||
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
|
||||
// This function terminates when one of the following is true:
|
||||
//
|
||||
// 1. We find the exact element we are looking for.
|
||||
//
|
||||
// 2. We did not find the exact element, but we can return the index of
|
||||
// the next closest element that is less than that element.
|
||||
//
|
||||
// 3. We did not find the exact element, and there is no next-closest
|
||||
// element which is less than the one we are searching for, so we
|
||||
// return -1.
|
||||
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
|
||||
var cmp = aCompare(aNeedle, aHaystack[mid], true);
|
||||
if (cmp === 0) {
|
||||
// Found the element we are looking for.
|
||||
return mid;
|
||||
}
|
||||
else if (cmp > 0) {
|
||||
// aHaystack[mid] is greater than our needle.
|
||||
if (aHigh - mid > 1) {
|
||||
// The element is in the upper half.
|
||||
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
|
||||
}
|
||||
// We did not find an exact match, return the next closest one
|
||||
// (termination case 2).
|
||||
return mid;
|
||||
}
|
||||
else {
|
||||
// aHaystack[mid] is less than our needle.
|
||||
if (mid - aLow > 1) {
|
||||
// The element is in the lower half.
|
||||
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
|
||||
}
|
||||
// The exact needle element was not found in this haystack. Determine if
|
||||
// we are in termination case (2) or (3) and return the appropriate thing.
|
||||
return aLow < 0 ? -1 : aLow;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an implementation of binary search which will always try and return
|
||||
* the index of next lowest value checked if there is no exact hit. This is
|
||||
* because mappings between original and generated line/col pairs are single
|
||||
* points, and there is an implicit region between each of them, so a miss
|
||||
* just means that you aren't on the very start of a region.
|
||||
*
|
||||
* @param aNeedle The element you are looking for.
|
||||
* @param aHaystack The array that is being searched.
|
||||
* @param aCompare A function which takes the needle and an element in the
|
||||
* array and returns -1, 0, or 1 depending on whether the needle is less
|
||||
* than, equal to, or greater than the element, respectively.
|
||||
*/
|
||||
exports.search = function search(aNeedle, aHaystack, aCompare) {
|
||||
if (aHaystack.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
return recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
|
||||
};
|
||||
|
||||
});
|
||||
Generated
Vendored
+303
@@ -0,0 +1,303 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var util = require('./util');
|
||||
var binarySearch = require('./binary-search');
|
||||
var SourceMapConsumer = require('./source-map-consumer').SourceMapConsumer;
|
||||
var BasicSourceMapConsumer = require('./basic-source-map-consumer').BasicSourceMapConsumer;
|
||||
|
||||
/**
|
||||
* An IndexedSourceMapConsumer instance represents a parsed source map which
|
||||
* we can query for information. It differs from BasicSourceMapConsumer in
|
||||
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
|
||||
* input.
|
||||
*
|
||||
* The only parameter is a raw source map (either as a JSON string, or already
|
||||
* parsed to an object). According to the spec for indexed source maps, they
|
||||
* have the following attributes:
|
||||
*
|
||||
* - version: Which version of the source map spec this map is following.
|
||||
* - file: Optional. The generated file this source map is associated with.
|
||||
* - sections: A list of section definitions.
|
||||
*
|
||||
* Each value under the "sections" field has two fields:
|
||||
* - offset: The offset into the original specified at which this section
|
||||
* begins to apply, defined as an object with a "line" and "column"
|
||||
* field.
|
||||
* - map: A source map definition. This source map could also be indexed,
|
||||
* but doesn't have to be.
|
||||
*
|
||||
* Instead of the "map" field, it's also possible to have a "url" field
|
||||
* specifying a URL to retrieve a source map from, but that's currently
|
||||
* unsupported.
|
||||
*
|
||||
* Here's an example source map, taken from the source map spec[0], but
|
||||
* modified to omit a section which uses the "url" field.
|
||||
*
|
||||
* {
|
||||
* version : 3,
|
||||
* file: "app.js",
|
||||
* sections: [{
|
||||
* offset: {line:100, column:10},
|
||||
* map: {
|
||||
* version : 3,
|
||||
* file: "section.js",
|
||||
* sources: ["foo.js", "bar.js"],
|
||||
* names: ["src", "maps", "are", "fun"],
|
||||
* mappings: "AAAA,E;;ABCDE;"
|
||||
* }
|
||||
* }],
|
||||
* }
|
||||
*
|
||||
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
|
||||
*/
|
||||
function IndexedSourceMapConsumer(aSourceMap) {
|
||||
var sourceMap = aSourceMap;
|
||||
if (typeof aSourceMap === 'string') {
|
||||
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
|
||||
}
|
||||
|
||||
var version = util.getArg(sourceMap, 'version');
|
||||
var sections = util.getArg(sourceMap, 'sections');
|
||||
|
||||
if (version != this._version) {
|
||||
throw new Error('Unsupported version: ' + version);
|
||||
}
|
||||
|
||||
var lastOffset = {
|
||||
line: -1,
|
||||
column: 0
|
||||
};
|
||||
this._sections = sections.map(function (s) {
|
||||
if (s.url) {
|
||||
// The url field will require support for asynchronicity.
|
||||
// See https://github.com/mozilla/source-map/issues/16
|
||||
throw new Error('Support for url field in sections not implemented.');
|
||||
}
|
||||
var offset = util.getArg(s, 'offset');
|
||||
var offsetLine = util.getArg(offset, 'line');
|
||||
var offsetColumn = util.getArg(offset, 'column');
|
||||
|
||||
if (offsetLine < lastOffset.line ||
|
||||
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
|
||||
throw new Error('Section offsets must be ordered and non-overlapping.');
|
||||
}
|
||||
lastOffset = offset;
|
||||
|
||||
return {
|
||||
generatedOffset: {
|
||||
// The offset fields are 0-based, but we use 1-based indices when
|
||||
// encoding/decoding from VLQ.
|
||||
generatedLine: offsetLine + 1,
|
||||
generatedColumn: offsetColumn + 1
|
||||
},
|
||||
consumer: new SourceMapConsumer(util.getArg(s, 'map'))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
||||
IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
|
||||
|
||||
/**
|
||||
* The version of the source mapping spec that we are consuming.
|
||||
*/
|
||||
IndexedSourceMapConsumer.prototype._version = 3;
|
||||
|
||||
/**
|
||||
* The list of original sources.
|
||||
*/
|
||||
Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
|
||||
get: function () {
|
||||
var sources = [];
|
||||
for (var i = 0; i < this._sections.length; i++) {
|
||||
for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
|
||||
sources.push(this._sections[i].consumer.sources[j]);
|
||||
}
|
||||
};
|
||||
return sources;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns the original source, line, and column information for the generated
|
||||
* source's line and column positions provided. The only argument is an object
|
||||
* with the following properties:
|
||||
*
|
||||
* - line: The line number in the generated source.
|
||||
* - column: The column number in the generated source.
|
||||
*
|
||||
* and an object is returned with the following properties:
|
||||
*
|
||||
* - source: The original source file, or null.
|
||||
* - line: The line number in the original source, or null.
|
||||
* - column: The column number in the original source, or null.
|
||||
* - name: The original identifier, or null.
|
||||
*/
|
||||
IndexedSourceMapConsumer.prototype.originalPositionFor =
|
||||
function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
|
||||
var needle = {
|
||||
generatedLine: util.getArg(aArgs, 'line'),
|
||||
generatedColumn: util.getArg(aArgs, 'column')
|
||||
};
|
||||
|
||||
// Find the section containing the generated position we're trying to map
|
||||
// to an original position.
|
||||
var sectionIndex = binarySearch.search(needle, this._sections,
|
||||
function(needle, section) {
|
||||
var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
|
||||
if (cmp) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return (needle.generatedColumn -
|
||||
section.generatedOffset.generatedColumn);
|
||||
});
|
||||
var section = this._sections[sectionIndex];
|
||||
|
||||
if (!section) {
|
||||
return {
|
||||
source: null,
|
||||
line: null,
|
||||
column: null,
|
||||
name: null
|
||||
};
|
||||
}
|
||||
|
||||
return section.consumer.originalPositionFor({
|
||||
line: needle.generatedLine -
|
||||
(section.generatedOffset.generatedLine - 1),
|
||||
column: needle.generatedColumn -
|
||||
(section.generatedOffset.generatedLine === needle.generatedLine
|
||||
? section.generatedOffset.generatedColumn - 1
|
||||
: 0)
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the original source content. The only argument is the url of the
|
||||
* original source file. Returns null if no original source content is
|
||||
* available.
|
||||
*/
|
||||
IndexedSourceMapConsumer.prototype.sourceContentFor =
|
||||
function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
||||
for (var i = 0; i < this._sections.length; i++) {
|
||||
var section = this._sections[i];
|
||||
|
||||
var content = section.consumer.sourceContentFor(aSource, true);
|
||||
if (content) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
if (nullOnMissing) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw new Error('"' + aSource + '" is not in the SourceMap.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the generated line and column information for the original source,
|
||||
* line, and column positions provided. The only argument is an object with
|
||||
* the following properties:
|
||||
*
|
||||
* - source: The filename of the original source.
|
||||
* - line: The line number in the original source.
|
||||
* - column: The column number in the original source.
|
||||
*
|
||||
* and an object is returned with the following properties:
|
||||
*
|
||||
* - line: The line number in the generated source, or null.
|
||||
* - column: The column number in the generated source, or null.
|
||||
*/
|
||||
IndexedSourceMapConsumer.prototype.generatedPositionFor =
|
||||
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
|
||||
for (var i = 0; i < this._sections.length; i++) {
|
||||
var section = this._sections[i];
|
||||
|
||||
// Only consider this section if the requested source is in the list of
|
||||
// sources of the consumer.
|
||||
if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {
|
||||
continue;
|
||||
}
|
||||
var generatedPosition = section.consumer.generatedPositionFor(aArgs);
|
||||
if (generatedPosition) {
|
||||
var ret = {
|
||||
line: generatedPosition.line +
|
||||
(section.generatedOffset.generatedLine - 1),
|
||||
column: generatedPosition.column +
|
||||
(section.generatedOffset.generatedLine === generatedPosition.line
|
||||
? section.generatedOffset.generatedColumn - 1
|
||||
: 0)
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
line: null,
|
||||
column: null
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the mappings in a string in to a data structure which we can easily
|
||||
* query (the ordered arrays in the `this.__generatedMappings` and
|
||||
* `this.__originalMappings` properties).
|
||||
*/
|
||||
IndexedSourceMapConsumer.prototype._parseMappings =
|
||||
function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
||||
this.__generatedMappings = [];
|
||||
this.__originalMappings = [];
|
||||
for (var i = 0; i < this._sections.length; i++) {
|
||||
var section = this._sections[i];
|
||||
var sectionMappings = section.consumer._generatedMappings;
|
||||
for (var j = 0; j < sectionMappings.length; j++) {
|
||||
var mapping = sectionMappings[i];
|
||||
|
||||
var source = mapping.source;
|
||||
var sourceRoot = section.consumer.sourceRoot;
|
||||
|
||||
if (source != null && sourceRoot != null) {
|
||||
source = util.join(sourceRoot, source);
|
||||
}
|
||||
|
||||
// The mappings coming from the consumer for the section have
|
||||
// generated positions relative to the start of the section, so we
|
||||
// need to offset them to be relative to the start of the concatenated
|
||||
// generated file.
|
||||
var adjustedMapping = {
|
||||
source: source,
|
||||
generatedLine: mapping.generatedLine +
|
||||
(section.generatedOffset.generatedLine - 1),
|
||||
generatedColumn: mapping.column +
|
||||
(section.generatedOffset.generatedLine === mapping.generatedLine)
|
||||
? section.generatedOffset.generatedColumn - 1
|
||||
: 0,
|
||||
originalLine: mapping.originalLine,
|
||||
originalColumn: mapping.originalColumn,
|
||||
name: mapping.name
|
||||
};
|
||||
|
||||
this.__generatedMappings.push(adjustedMapping);
|
||||
if (typeof adjustedMapping.originalLine === 'number') {
|
||||
this.__originalMappings.push(adjustedMapping);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.__generatedMappings.sort(util.compareByGeneratedPositions);
|
||||
this.__originalMappings.sort(util.compareByOriginalPositions);
|
||||
};
|
||||
|
||||
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
|
||||
});
|
||||
Generated
Vendored
+86
@@ -0,0 +1,86 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2014 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Determine whether mappingB is after mappingA with respect to generated
|
||||
* position.
|
||||
*/
|
||||
function generatedPositionAfter(mappingA, mappingB) {
|
||||
// Optimized for most common case
|
||||
var lineA = mappingA.generatedLine;
|
||||
var lineB = mappingB.generatedLine;
|
||||
var columnA = mappingA.generatedColumn;
|
||||
var columnB = mappingB.generatedColumn;
|
||||
return lineB > lineA || lineB == lineA && columnB >= columnA ||
|
||||
util.compareByGeneratedPositions(mappingA, mappingB) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A data structure to provide a sorted view of accumulated mappings in a
|
||||
* performance conscious manner. It trades a neglibable overhead in general
|
||||
* case for a large speedup in case of mappings being added in order.
|
||||
*/
|
||||
function MappingList() {
|
||||
this._array = [];
|
||||
this._sorted = true;
|
||||
// Serves as infimum
|
||||
this._last = {generatedLine: -1, generatedColumn: 0};
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through internal items. This method takes the same arguments that
|
||||
* `Array.prototype.forEach` takes.
|
||||
*
|
||||
* NOTE: The order of the mappings is NOT guaranteed.
|
||||
*/
|
||||
MappingList.prototype.unsortedForEach =
|
||||
function MappingList_forEach(aCallback, aThisArg) {
|
||||
this._array.forEach(aCallback, aThisArg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given source mapping.
|
||||
*
|
||||
* @param Object aMapping
|
||||
*/
|
||||
MappingList.prototype.add = function MappingList_add(aMapping) {
|
||||
var mapping;
|
||||
if (generatedPositionAfter(this._last, aMapping)) {
|
||||
this._last = aMapping;
|
||||
this._array.push(aMapping);
|
||||
} else {
|
||||
this._sorted = false;
|
||||
this._array.push(aMapping);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the flat, sorted array of mappings. The mappings are sorted by
|
||||
* generated position.
|
||||
*
|
||||
* WARNING: This method returns internal data without copying, for
|
||||
* performance. The return value must NOT be mutated, and should be treated as
|
||||
* an immutable borrow. If you want to take ownership, you must make your own
|
||||
* copy.
|
||||
*/
|
||||
MappingList.prototype.toArray = function MappingList_toArray() {
|
||||
if (!this._sorted) {
|
||||
this._array.sort(util.compareByGeneratedPositions);
|
||||
this._sorted = true;
|
||||
}
|
||||
return this._array;
|
||||
};
|
||||
|
||||
exports.MappingList = MappingList;
|
||||
|
||||
});
|
||||
Generated
Vendored
+222
@@ -0,0 +1,222 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var util = require('./util');
|
||||
|
||||
function SourceMapConsumer(aSourceMap) {
|
||||
var sourceMap = aSourceMap;
|
||||
if (typeof aSourceMap === 'string') {
|
||||
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
|
||||
}
|
||||
|
||||
// We do late requires because the subclasses require() this file.
|
||||
if (sourceMap.sections != null) {
|
||||
var indexedSourceMapConsumer = require('./indexed-source-map-consumer');
|
||||
return new indexedSourceMapConsumer.IndexedSourceMapConsumer(sourceMap);
|
||||
} else {
|
||||
var basicSourceMapConsumer = require('./basic-source-map-consumer');
|
||||
return new basicSourceMapConsumer.BasicSourceMapConsumer(sourceMap);
|
||||
}
|
||||
}
|
||||
|
||||
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
|
||||
var basicSourceMapConsumer = require('./basic-source-map-consumer');
|
||||
return basicSourceMapConsumer.BasicSourceMapConsumer
|
||||
.fromSourceMap(aSourceMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of the source mapping spec that we are consuming.
|
||||
*/
|
||||
SourceMapConsumer.prototype._version = 3;
|
||||
|
||||
|
||||
// `__generatedMappings` and `__originalMappings` are arrays that hold the
|
||||
// parsed mapping coordinates from the source map's "mappings" attribute. They
|
||||
// are lazily instantiated, accessed via the `_generatedMappings` and
|
||||
// `_originalMappings` getters respectively, and we only parse the mappings
|
||||
// and create these arrays once queried for a source location. We jump through
|
||||
// these hoops because there can be many thousands of mappings, and parsing
|
||||
// them is expensive, so we only want to do it if we must.
|
||||
//
|
||||
// Each object in the arrays is of the form:
|
||||
//
|
||||
// {
|
||||
// generatedLine: The line number in the generated code,
|
||||
// generatedColumn: The column number in the generated code,
|
||||
// source: The path to the original source file that generated this
|
||||
// chunk of code,
|
||||
// originalLine: The line number in the original source that
|
||||
// corresponds to this chunk of generated code,
|
||||
// originalColumn: The column number in the original source that
|
||||
// corresponds to this chunk of generated code,
|
||||
// name: The name of the original symbol which generated this chunk of
|
||||
// code.
|
||||
// }
|
||||
//
|
||||
// All properties except for `generatedLine` and `generatedColumn` can be
|
||||
// `null`.
|
||||
//
|
||||
// `_generatedMappings` is ordered by the generated positions.
|
||||
//
|
||||
// `_originalMappings` is ordered by the original positions.
|
||||
|
||||
SourceMapConsumer.prototype.__generatedMappings = null;
|
||||
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
|
||||
get: function () {
|
||||
if (!this.__generatedMappings) {
|
||||
this.__generatedMappings = [];
|
||||
this.__originalMappings = [];
|
||||
this._parseMappings(this._mappings, this.sourceRoot);
|
||||
}
|
||||
|
||||
return this.__generatedMappings;
|
||||
}
|
||||
});
|
||||
|
||||
SourceMapConsumer.prototype.__originalMappings = null;
|
||||
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
|
||||
get: function () {
|
||||
if (!this.__originalMappings) {
|
||||
this.__generatedMappings = [];
|
||||
this.__originalMappings = [];
|
||||
this._parseMappings(this._mappings, this.sourceRoot);
|
||||
}
|
||||
|
||||
return this.__originalMappings;
|
||||
}
|
||||
});
|
||||
|
||||
SourceMapConsumer.prototype._nextCharIsMappingSeparator =
|
||||
function SourceMapConsumer_nextCharIsMappingSeparator(aStr) {
|
||||
var c = aStr.charAt(0);
|
||||
return c === ";" || c === ",";
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the mappings in a string in to a data structure which we can easily
|
||||
* query (the ordered arrays in the `this.__generatedMappings` and
|
||||
* `this.__originalMappings` properties).
|
||||
*/
|
||||
SourceMapConsumer.prototype._parseMappings =
|
||||
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
||||
throw new Error("Subclasses must implement _parseMappings");
|
||||
};
|
||||
|
||||
SourceMapConsumer.GENERATED_ORDER = 1;
|
||||
SourceMapConsumer.ORIGINAL_ORDER = 2;
|
||||
|
||||
/**
|
||||
* Iterate over each mapping between an original source/line/column and a
|
||||
* generated line/column in this source map.
|
||||
*
|
||||
* @param Function aCallback
|
||||
* The function that is called with each mapping.
|
||||
* @param Object aContext
|
||||
* Optional. If specified, this object will be the value of `this` every
|
||||
* time that `aCallback` is called.
|
||||
* @param aOrder
|
||||
* Either `SourceMapConsumer.GENERATED_ORDER` or
|
||||
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
|
||||
* iterate over the mappings sorted by the generated file's line/column
|
||||
* order or the original's source/line/column order, respectively. Defaults to
|
||||
* `SourceMapConsumer.GENERATED_ORDER`.
|
||||
*/
|
||||
SourceMapConsumer.prototype.eachMapping =
|
||||
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
|
||||
var context = aContext || null;
|
||||
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
|
||||
|
||||
var mappings;
|
||||
switch (order) {
|
||||
case SourceMapConsumer.GENERATED_ORDER:
|
||||
mappings = this._generatedMappings;
|
||||
break;
|
||||
case SourceMapConsumer.ORIGINAL_ORDER:
|
||||
mappings = this._originalMappings;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown order of iteration.");
|
||||
}
|
||||
|
||||
var sourceRoot = this.sourceRoot;
|
||||
mappings.map(function (mapping) {
|
||||
var source = mapping.source;
|
||||
if (source != null && sourceRoot != null) {
|
||||
source = util.join(sourceRoot, source);
|
||||
}
|
||||
return {
|
||||
source: source,
|
||||
generatedLine: mapping.generatedLine,
|
||||
generatedColumn: mapping.generatedColumn,
|
||||
originalLine: mapping.originalLine,
|
||||
originalColumn: mapping.originalColumn,
|
||||
name: mapping.name
|
||||
};
|
||||
}).forEach(aCallback, context);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all generated line and column information for the original source
|
||||
* and line provided. The only argument is an object with the following
|
||||
* properties:
|
||||
*
|
||||
* - source: The filename of the original source.
|
||||
* - line: The line number in the original source.
|
||||
*
|
||||
* and an array of objects is returned, each with the following properties:
|
||||
*
|
||||
* - line: The line number in the generated source, or null.
|
||||
* - column: The column number in the generated source, or null.
|
||||
*/
|
||||
SourceMapConsumer.prototype.allGeneratedPositionsFor =
|
||||
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
|
||||
// When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
|
||||
// returns the index of the closest mapping less than the needle. By
|
||||
// setting needle.originalColumn to Infinity, we thus find the last
|
||||
// mapping for the given line, provided such a mapping exists.
|
||||
var needle = {
|
||||
source: util.getArg(aArgs, 'source'),
|
||||
originalLine: util.getArg(aArgs, 'line'),
|
||||
originalColumn: Infinity
|
||||
};
|
||||
|
||||
if (this.sourceRoot != null) {
|
||||
needle.source = util.relative(this.sourceRoot, needle.source);
|
||||
}
|
||||
|
||||
var mappings = [];
|
||||
|
||||
var index = this._findMapping(needle,
|
||||
this._originalMappings,
|
||||
"originalLine",
|
||||
"originalColumn",
|
||||
util.compareByOriginalPositions);
|
||||
if (index >= 0) {
|
||||
var mapping = this._originalMappings[index];
|
||||
|
||||
while (mapping && mapping.originalLine === needle.originalLine) {
|
||||
mappings.push({
|
||||
line: util.getArg(mapping, 'generatedLine', null),
|
||||
column: util.getArg(mapping, 'generatedColumn', null),
|
||||
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
||||
});
|
||||
|
||||
mapping = this._originalMappings[--index];
|
||||
}
|
||||
}
|
||||
|
||||
return mappings.reverse();
|
||||
};
|
||||
|
||||
exports.SourceMapConsumer = SourceMapConsumer;
|
||||
|
||||
});
|
||||
Generated
Vendored
+400
@@ -0,0 +1,400 @@
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
if (typeof define !== 'function') {
|
||||
var define = require('amdefine')(module, require);
|
||||
}
|
||||
define(function (require, exports, module) {
|
||||
|
||||
var base64VLQ = require('./base64-vlq');
|
||||
var util = require('./util');
|
||||
var ArraySet = require('./array-set').ArraySet;
|
||||
var MappingList = require('./mapping-list').MappingList;
|
||||
|
||||
/**
|
||||
* An instance of the SourceMapGenerator represents a source map which is
|
||||
* being built incrementally. You may pass an object with the following
|
||||
* properties:
|
||||
*
|
||||
* - file: The filename of the generated source.
|
||||
* - sourceRoot: A root for all relative URLs in this source map.
|
||||
*/
|
||||
function SourceMapGenerator(aArgs) {
|
||||
if (!aArgs) {
|
||||
aArgs = {};
|
||||
}
|
||||
this._file = util.getArg(aArgs, 'file', null);
|
||||
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
|
||||
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
|
||||
this._sources = new ArraySet();
|
||||
this._names = new ArraySet();
|
||||
this._mappings = new MappingList();
|
||||
this._sourcesContents = null;
|
||||
}
|
||||
|
||||
SourceMapGenerator.prototype._version = 3;
|
||||
|
||||
/**
|
||||
* Creates a new SourceMapGenerator based on a SourceMapConsumer
|
||||
*
|
||||
* @param aSourceMapConsumer The SourceMap.
|
||||
*/
|
||||
SourceMapGenerator.fromSourceMap =
|
||||
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
|
||||
var sourceRoot = aSourceMapConsumer.sourceRoot;
|
||||
var generator = new SourceMapGenerator({
|
||||
file: aSourceMapConsumer.file,
|
||||
sourceRoot: sourceRoot
|
||||
});
|
||||
aSourceMapConsumer.eachMapping(function (mapping) {
|
||||
var newMapping = {
|
||||
generated: {
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn
|
||||
}
|
||||
};
|
||||
|
||||
if (mapping.source != null) {
|
||||
newMapping.source = mapping.source;
|
||||
if (sourceRoot != null) {
|
||||
newMapping.source = util.relative(sourceRoot, newMapping.source);
|
||||
}
|
||||
|
||||
newMapping.original = {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn
|
||||
};
|
||||
|
||||
if (mapping.name != null) {
|
||||
newMapping.name = mapping.name;
|
||||
}
|
||||
}
|
||||
|
||||
generator.addMapping(newMapping);
|
||||
});
|
||||
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||||
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||||
if (content != null) {
|
||||
generator.setSourceContent(sourceFile, content);
|
||||
}
|
||||
});
|
||||
return generator;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a single mapping from original source line and column to the generated
|
||||
* source's line and column for this source map being created. The mapping
|
||||
* object should have the following properties:
|
||||
*
|
||||
* - generated: An object with the generated line and column positions.
|
||||
* - original: An object with the original line and column positions.
|
||||
* - source: The original source file (relative to the sourceRoot).
|
||||
* - name: An optional original token name for this mapping.
|
||||
*/
|
||||
SourceMapGenerator.prototype.addMapping =
|
||||
function SourceMapGenerator_addMapping(aArgs) {
|
||||
var generated = util.getArg(aArgs, 'generated');
|
||||
var original = util.getArg(aArgs, 'original', null);
|
||||
var source = util.getArg(aArgs, 'source', null);
|
||||
var name = util.getArg(aArgs, 'name', null);
|
||||
|
||||
if (!this._skipValidation) {
|
||||
this._validateMapping(generated, original, source, name);
|
||||
}
|
||||
|
||||
if (source != null && !this._sources.has(source)) {
|
||||
this._sources.add(source);
|
||||
}
|
||||
|
||||
if (name != null && !this._names.has(name)) {
|
||||
this._names.add(name);
|
||||
}
|
||||
|
||||
this._mappings.add({
|
||||
generatedLine: generated.line,
|
||||
generatedColumn: generated.column,
|
||||
originalLine: original != null && original.line,
|
||||
originalColumn: original != null && original.column,
|
||||
source: source,
|
||||
name: name
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the source content for a source file.
|
||||
*/
|
||||
SourceMapGenerator.prototype.setSourceContent =
|
||||
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
|
||||
var source = aSourceFile;
|
||||
if (this._sourceRoot != null) {
|
||||
source = util.relative(this._sourceRoot, source);
|
||||
}
|
||||
|
||||
if (aSourceContent != null) {
|
||||
// Add the source content to the _sourcesContents map.
|
||||
// Create a new _sourcesContents map if the property is null.
|
||||
if (!this._sourcesContents) {
|
||||
this._sourcesContents = {};
|
||||
}
|
||||
this._sourcesContents[util.toSetString(source)] = aSourceContent;
|
||||
} else if (this._sourcesContents) {
|
||||
// Remove the source file from the _sourcesContents map.
|
||||
// If the _sourcesContents map is empty, set the property to null.
|
||||
delete this._sourcesContents[util.toSetString(source)];
|
||||
if (Object.keys(this._sourcesContents).length === 0) {
|
||||
this._sourcesContents = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies the mappings of a sub-source-map for a specific source file to the
|
||||
* source map being generated. Each mapping to the supplied source file is
|
||||
* rewritten using the supplied source map. Note: The resolution for the
|
||||
* resulting mappings is the minimium of this map and the supplied map.
|
||||
*
|
||||
* @param aSourceMapConsumer The source map to be applied.
|
||||
* @param aSourceFile Optional. The filename of the source file.
|
||||
* If omitted, SourceMapConsumer's file property will be used.
|
||||
* @param aSourceMapPath Optional. The dirname of the path to the source map
|
||||
* to be applied. If relative, it is relative to the SourceMapConsumer.
|
||||
* This parameter is needed when the two source maps aren't in the same
|
||||
* directory, and the source map to be applied contains relative source
|
||||
* paths. If so, those relative source paths need to be rewritten
|
||||
* relative to the SourceMapGenerator.
|
||||
*/
|
||||
SourceMapGenerator.prototype.applySourceMap =
|
||||
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
|
||||
var sourceFile = aSourceFile;
|
||||
// If aSourceFile is omitted, we will use the file property of the SourceMap
|
||||
if (aSourceFile == null) {
|
||||
if (aSourceMapConsumer.file == null) {
|
||||
throw new Error(
|
||||
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
|
||||
'or the source map\'s "file" property. Both were omitted.'
|
||||
);
|
||||
}
|
||||
sourceFile = aSourceMapConsumer.file;
|
||||
}
|
||||
var sourceRoot = this._sourceRoot;
|
||||
// Make "sourceFile" relative if an absolute Url is passed.
|
||||
if (sourceRoot != null) {
|
||||
sourceFile = util.relative(sourceRoot, sourceFile);
|
||||
}
|
||||
// Applying the SourceMap can add and remove items from the sources and
|
||||
// the names array.
|
||||
var newSources = new ArraySet();
|
||||
var newNames = new ArraySet();
|
||||
|
||||
// Find mappings for the "sourceFile"
|
||||
this._mappings.unsortedForEach(function (mapping) {
|
||||
if (mapping.source === sourceFile && mapping.originalLine != null) {
|
||||
// Check if it can be mapped by the source map, then update the mapping.
|
||||
var original = aSourceMapConsumer.originalPositionFor({
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn
|
||||
});
|
||||
if (original.source != null) {
|
||||
// Copy mapping
|
||||
mapping.source = original.source;
|
||||
if (aSourceMapPath != null) {
|
||||
mapping.source = util.join(aSourceMapPath, mapping.source)
|
||||
}
|
||||
if (sourceRoot != null) {
|
||||
mapping.source = util.relative(sourceRoot, mapping.source);
|
||||
}
|
||||
mapping.originalLine = original.line;
|
||||
mapping.originalColumn = original.column;
|
||||
if (original.name != null) {
|
||||
mapping.name = original.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var source = mapping.source;
|
||||
if (source != null && !newSources.has(source)) {
|
||||
newSources.add(source);
|
||||
}
|
||||
|
||||
var name = mapping.name;
|
||||
if (name != null && !newNames.has(name)) {
|
||||
newNames.add(name);
|
||||
}
|
||||
|
||||
}, this);
|
||||
this._sources = newSources;
|
||||
this._names = newNames;
|
||||
|
||||
// Copy sourcesContents of applied map.
|
||||
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||||
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||||
if (content != null) {
|
||||
if (aSourceMapPath != null) {
|
||||
sourceFile = util.join(aSourceMapPath, sourceFile);
|
||||
}
|
||||
if (sourceRoot != null) {
|
||||
sourceFile = util.relative(sourceRoot, sourceFile);
|
||||
}
|
||||
this.setSourceContent(sourceFile, content);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* A mapping can have one of the three levels of data:
|
||||
*
|
||||
* 1. Just the generated position.
|
||||
* 2. The Generated position, original position, and original source.
|
||||
* 3. Generated and original position, original source, as well as a name
|
||||
* token.
|
||||
*
|
||||
* To maintain consistency, we validate that any new mapping being added falls
|
||||
* in to one of these categories.
|
||||
*/
|
||||
SourceMapGenerator.prototype._validateMapping =
|
||||
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
|
||||
aName) {
|
||||
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
||||
&& aGenerated.line > 0 && aGenerated.column >= 0
|
||||
&& !aOriginal && !aSource && !aName) {
|
||||
// Case 1.
|
||||
return;
|
||||
}
|
||||
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
||||
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
|
||||
&& aGenerated.line > 0 && aGenerated.column >= 0
|
||||
&& aOriginal.line > 0 && aOriginal.column >= 0
|
||||
&& aSource) {
|
||||
// Cases 2 and 3.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error('Invalid mapping: ' + JSON.stringify({
|
||||
generated: aGenerated,
|
||||
source: aSource,
|
||||
original: aOriginal,
|
||||
name: aName
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the accumulated mappings in to the stream of base 64 VLQs
|
||||
* specified by the source map format.
|
||||
*/
|
||||
SourceMapGenerator.prototype._serializeMappings =
|
||||
function SourceMapGenerator_serializeMappings() {
|
||||
var previousGeneratedColumn = 0;
|
||||
var previousGeneratedLine = 1;
|
||||
var previousOriginalColumn = 0;
|
||||
var previousOriginalLine = 0;
|
||||
var previousName = 0;
|
||||
var previousSource = 0;
|
||||
var result = '';
|
||||
var mapping;
|
||||
|
||||
var mappings = this._mappings.toArray();
|
||||
|
||||
for (var i = 0, len = mappings.length; i < len; i++) {
|
||||
mapping = mappings[i];
|
||||
|
||||
if (mapping.generatedLine !== previousGeneratedLine) {
|
||||
previousGeneratedColumn = 0;
|
||||
while (mapping.generatedLine !== previousGeneratedLine) {
|
||||
result += ';';
|
||||
previousGeneratedLine++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i > 0) {
|
||||
if (!util.compareByGeneratedPositions(mapping, mappings[i - 1])) {
|
||||
continue;
|
||||
}
|
||||
result += ',';
|
||||
}
|
||||
}
|
||||
|
||||
result += base64VLQ.encode(mapping.generatedColumn
|
||||
- previousGeneratedColumn);
|
||||
previousGeneratedColumn = mapping.generatedColumn;
|
||||
|
||||
if (mapping.source != null) {
|
||||
result += base64VLQ.encode(this._sources.indexOf(mapping.source)
|
||||
- previousSource);
|
||||
previousSource = this._sources.indexOf(mapping.source);
|
||||
|
||||
// lines are stored 0-based in SourceMap spec version 3
|
||||
result += base64VLQ.encode(mapping.originalLine - 1
|
||||
- previousOriginalLine);
|
||||
previousOriginalLine = mapping.originalLine - 1;
|
||||
|
||||
result += base64VLQ.encode(mapping.originalColumn
|
||||
- previousOriginalColumn);
|
||||
previousOriginalColumn = mapping.originalColumn;
|
||||
|
||||
if (mapping.name != null) {
|
||||
result += base64VLQ.encode(this._names.indexOf(mapping.name)
|
||||
- previousName);
|
||||
previousName = this._names.indexOf(mapping.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
SourceMapGenerator.prototype._generateSourcesContent =
|
||||
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
|
||||
return aSources.map(function (source) {
|
||||
if (!this._sourcesContents) {
|
||||
return null;
|
||||
}
|
||||
if (aSourceRoot != null) {
|
||||
source = util.relative(aSourceRoot, source);
|
||||
}
|
||||
var key = util.toSetString(source);
|
||||
return Object.prototype.hasOwnProperty.call(this._sourcesContents,
|
||||
key)
|
||||
? this._sourcesContents[key]
|
||||
: null;
|
||||
}, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Externalize the source map.
|
||||
*/
|
||||
SourceMapGenerator.prototype.toJSON =
|
||||
function SourceMapGenerator_toJSON() {
|
||||
var map = {
|
||||
version: this._version,
|
||||
sources: this._sources.toArray(),
|
||||
names: this._names.toArray(),
|
||||
mappings: this._serializeMappings()
|
||||
};
|
||||
if (this._file != null) {
|
||||
map.file = this._file;
|
||||
}
|
||||
if (this._sourceRoot != null) {
|
||||
map.sourceRoot = this._sourceRoot;
|
||||
}
|
||||
if (this._sourcesContents) {
|
||||
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
|
||||
}
|
||||
|
||||
return map;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the source map being generated to a string.
|
||||
*/
|
||||
SourceMapGenerator.prototype.toString =
|
||||
function SourceMapGenerator_toString() {
|
||||
return JSON.stringify(this);
|
||||
};
|
||||
|
||||
exports.SourceMapGenerator = SourceMapGenerator;
|
||||
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user