Initial commit

This commit is contained in:
Patrick Marsceill
2017-03-09 13:16:08 -05:00
commit b7b0d0d7bf
4147 changed files with 401224 additions and 0 deletions

1
node_modules/style-search/.npmignore generated vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

5
node_modules/style-search/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# Changelog
## 0.1.0
- Initial extraction from [stylelint](https://github.com/stylelint/stylelint), API refactoring, and release.

13
node_modules/style-search/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright (c) 2016, David Clark
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

96
node_modules/style-search/README.md generated vendored Normal file
View File

@@ -0,0 +1,96 @@
# style-search [![CircleCI](https://circleci.com/gh/davidtheclark/style-search.svg?style=svg)](https://circleci.com/gh/davidtheclark/style-search)
Search CSS (and CSS-like) strings, with sensitivity to whether matches occur inside strings, comments, and functions.
## Usage
```js
var styleSearch = require('style-search');
styleSearch(options, callback);
```
**By default, the search ignores strings, comments, and function names.** You can use the options to change this behavior or introduce other restrictions. That is what makes this module more useful for many searches than `indexOf()` or a `RegExp`.
However, if you need more detailed parsing, you should consider using the real parsers [PostCSS](https://github.com/postcss/postcss), [`postcss-selector-parser`](https://github.com/postcss/postcss-selector-parser), and [`postcss-value-parser`](https://github.com/TrySound/postcss-value-parser).
### Example
```css
/* Here is some pink */
a { color: pink; }
a::before { content: "pink" }
b { color: shadesOfPink(7); }
```
```js
styleSearch({
source: theCssStringAbove,
target: "pink",
}, function(match, count) {
/* Only the "pink" in `color: pink` will be
reported as a match */
});
```
### Reporting matches
For every match found your `callback` is invoked. It is passed two arguments:
- A `match` object with the following properties:
- `startIndex`: where the match begins
- `endIndex`: where the match ends
- `target`: what got matched (useful if your `target` option is an array instead of a single string)
- `insideFunctionArguments`: whether the match is inside a function — *this includes the parentheses around the arguments*
- `insideComment`: whether the match is inside a comment
- `insideString`: whether the match is inside a string
- The count of how many matches have been found up to this point.
### Options
Below you'll see that syntax feature options all accept three keywords: `"skip"`, `"check"`, `"only"`. An error will be thrown if you use `"only"` more than once.
#### source
String. *Required.*
The source string to search through.
#### target
String or array of strings. *Required.*
The target of the search. Can be
- a single character
- a string with some length
- an array of strings, all of which count as matches (the `match` object passed to the `callback` will differentiate which string in the array got matched via its `target` property)
#### once
Boolean. Default: `false`.
If `true`, the search will stop after one match is found.
#### comments
`"skip"` | `"check"` | `"only"`. Default: `"skip"`.
This includes both standard `/* CSS comments */` and non-standard but widely used `// single line comments`.
#### strings
`"skip"` | `"check"` | `"only"`. Default: `"skip"`.
#### functionNames
`"skip"` | `"check"` | `"only"`. Default: `"skip"`.
#### functionArguments
`"skip"` | `"check"` | `"only"`. Default: `"check"`.
#### parentheticals
`"skip"` | `"check"` | `"only"`. Default: `"check"`.
This designates anything inside parentheses, which includes standard functions, but also Sass maps and other non-standard constructs. `parentheticals` is a broader category than `functionArguments`.

5
node_modules/style-search/circle.yml generated vendored Normal file
View File

@@ -0,0 +1,5 @@
test:
override:
- nvm use 0.10 && npm test
- nvm use 0.12 && npm test
- nvm use 4.0 && npm test

203
node_modules/style-search/index.js generated vendored Normal file
View File

@@ -0,0 +1,203 @@
var SKIP = 'skip';
var CHECK = 'check';
var ONLY = 'only';
module.exports = function (options, callback) {
var source = options.source;
var target = options.target;
var skipComments = (options.comments) ? options.comments === SKIP : true;
var skipStrings = (options.strings) ? options.strings === SKIP : true;
var skipFunctionNames = (options.functionNames) ? options.functionNames === SKIP : true;
var skipFunctionArguments = options.functionArguments === SKIP;
var skipParentheticals = options.parentheticals === SKIP;
var onceOptionUsed = false;
Object.keys(options).forEach(function(key) {
if (options[key] !== ONLY) return;
if (!onceOptionUsed) {
onceOptionUsed = true;
} else {
throw new Error('Only one syntax feature option can be the "only" one to check');
}
});
var onlyComments = options.comments === ONLY;
var onlyStrings = options.strings === ONLY;
var onlyFunctionNames = options.functionNames === ONLY;
var onlyFunctionArguments = options.functionArguments === ONLY;
var onlyParentheticals = options.parentheticals === ONLY;
var insideString = false;
var insideComment = false;
var insideSingleLineComment = false;
var insideParens = false;
var insideFunctionArguments = false;
var openingParenCount = 0;
var matchCount = 0;
var openingQuote;
var targetIsArray = Array.isArray(target);
// If the target is just a string, it is easy to check whether
// some index of the source matches it.
// If the target is an array of strings, though, we have to
// check whether some index of the source matches *any* of
// those target strings (stopping after the first match).
var getMatch = (function () {
if (!targetIsArray) {
return getMatchBase.bind(null, target);
}
return function(index) {
for (var ti = 0, tl = target.length; ti < tl; ti++) {
var checkResult = getMatchBase(target[ti], index);
if (checkResult) return checkResult;
}
return false;
}
})();
function getMatchBase(targetString, index) {
var targetStringLength = targetString.length;
// Target is a single character
if (targetStringLength === 1 && source[index] !== targetString) return false;
// Target is multiple characters
if (source.substr(index, targetStringLength) !== targetString) return false;
return {
insideParens: insideParens,
insideFunctionArguments: insideFunctionArguments,
insideComment: insideComment,
insideString: insideString,
startIndex: index,
endIndex: index + targetStringLength,
target: targetString,
};
}
for (var i = 0, l = source.length; i < l; i++) {
var currentChar = source[i];
// Register the beginning of a comment
if (
!insideString && !insideComment
&& currentChar === "/"
&& source[i - 1] !== "\\" // escaping
) {
// standard comments
if (source[i + 1] === "*") {
insideComment = true;
continue;
}
// single-line comments
if (source[i + 1] === "/") {
insideComment = true;
insideSingleLineComment = true;
continue;
}
}
if (insideComment) {
// Register the end of a standard comment
if (
!insideSingleLineComment
&& currentChar === "*"
&& source[i - 1] !== "\\" // escaping
&& source[i + 1] === "/"
&& source[i - 1] !== "/" // don't end if it's /*/
) {
insideComment = false;
continue;
}
// Register the end of a single-line comment
if (
insideSingleLineComment
&& currentChar === "\n"
) {
insideComment = false;
insideSingleLineComment = false;
}
if (skipComments) continue;
}
// Register the beginning of a string
if (!insideComment && !insideString && (currentChar === "\"" || currentChar === "'")) {
if (source[i - 1] === "\\") continue; // escaping
openingQuote = currentChar;
insideString = true;
// For string-quotes rule
if (target === currentChar) handleMatch(getMatch(i));
continue;
}
if (insideString) {
// Register the end of a string
if (currentChar === openingQuote) {
if (source[i - 1] === "\\") continue; // escaping
insideString = false;
continue;
}
if (skipStrings) continue;
}
// Register the beginning of parens/functions
if (!insideString && !insideComment && currentChar === "(") {
// Keep track of opening parentheticals so that we
// know when the outermost function (possibly
// containing nested functions) is closing
openingParenCount++;
insideParens = true;
// Only inside a function if there is a function name
// before the opening paren
if (/[a-zA-Z]/.test(source[i - 1])) {
insideFunctionArguments = true;
}
if (target === "(") handleMatch(getMatch(i));
continue;
}
if (insideParens) {
// Register the end of a function
if (currentChar === ")") {
openingParenCount--;
// Do this here so the match is still technically inside a function
if (target === ")") handleMatch(getMatch(i));
if (openingParenCount === 0) {
insideParens = false;
insideFunctionArguments = false;
}
continue;
}
}
var isFunctionName = /^[a-zA-Z]*\(/.test(source.slice(i));
if (skipFunctionNames && isFunctionName) continue;
if (onlyFunctionNames && !isFunctionName) continue;
var match = getMatch(i);
if (!match) continue;
handleMatch(match);
if (options.once) return;
}
function handleMatch(match) {
if (onlyParentheticals && !insideParens) return;
if (skipParentheticals && insideParens) return;
if (onlyFunctionArguments && !insideFunctionArguments) return;
if (skipFunctionArguments && insideFunctionArguments) return;
if (onlyStrings && !insideString) return;
if (onlyComments && !insideComment) return;
matchCount++;
callback(match, matchCount);
}
}

82
node_modules/style-search/package.json generated vendored Normal file
View File

@@ -0,0 +1,82 @@
{
"_args": [
[
"style-search@^0.1.0",
"/Users/pmarsceill/_projects/just-the-docs/node_modules/stylelint"
]
],
"_from": "style-search@>=0.1.0 <0.2.0",
"_id": "style-search@0.1.0",
"_inCache": true,
"_installable": true,
"_location": "/style-search",
"_nodeVersion": "4.4.5",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/style-search-0.1.0.tgz_1465741382107_0.05674637807533145"
},
"_npmUser": {
"email": "david.dave.clark@gmail.com",
"name": "davidtheclark"
},
"_npmVersion": "2.15.6",
"_phantomChildren": {},
"_requested": {
"name": "style-search",
"raw": "style-search@^0.1.0",
"rawSpec": "^0.1.0",
"scope": null,
"spec": ">=0.1.0 <0.2.0",
"type": "range"
},
"_requiredBy": [
"/stylelint"
],
"_resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
"_shasum": "7958c793e47e32e07d2b5cafe5c0bf8e12e77902",
"_shrinkwrap": null,
"_spec": "style-search@^0.1.0",
"_where": "/Users/pmarsceill/_projects/just-the-docs/node_modules/stylelint",
"author": {
"name": "David Clark"
},
"bugs": {
"url": "https://github.com/davidtheclark/style-search/issues"
},
"dependencies": {},
"description": "Search CSS(-like) strings",
"devDependencies": {
"tape": "^4.5.1"
},
"directories": {},
"dist": {
"shasum": "7958c793e47e32e07d2b5cafe5c0bf8e12e77902",
"tarball": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz"
},
"gitHead": "e7e02010544c9204bbbc323cf3b18ae1a0fcb39b",
"homepage": "https://github.com/davidtheclark/style-search#readme",
"keywords": [
"css",
"search",
"stylelint"
],
"license": "ISC",
"main": "index.js",
"maintainers": [
{
"name": "davidtheclark",
"email": "david.dave.clark@gmail.com"
}
],
"name": "style-search",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/davidtheclark/style-search.git"
},
"scripts": {
"test": "tape test.js"
},
"version": "0.1.0"
}

467
node_modules/style-search/test.js generated vendored Normal file
View File

@@ -0,0 +1,467 @@
var test = require("tape");
var styleSearch = require("./index");
function styleSearchResults(options) {
const results = [];
styleSearch(options, function(match) {
results.push(match.startIndex);
});
return results;
}
test("default options", function(t) {
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "c",
}), [ 2, 4 ]);
t.deepEqual(styleSearchResults({
source: "abc cb",
target: "a",
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "b",
}), [ 1, 5 ]);
t.deepEqual(styleSearchResults({
source: "abc \"var(--cba)\"",
target: "a",
}), [0]);
t.end();
});
test("once", function(t) {
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "c",
once: true,
}), [2]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "a",
once: true,
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "b",
once: false,
}), [ 1, 5 ]);
t.end();
});
test("functionArguments: 'only'", function(t) {
t.deepEqual(styleSearchResults({
source: "abc var(--cba)",
target: "c",
functionArguments: "only",
}), [10]);
t.deepEqual(styleSearchResults({
source: "abc var(--cba)",
target: "a",
functionArguments: "only",
}), [12]);
t.deepEqual(styleSearchResults({
source: "abc \"var(--cba)\"",
target: "a",
functionArguments: "only",
}), []);
t.deepEqual(styleSearchResults({
source: "translate(1px, calc(1px * 2))",
target: "1",
functionArguments: "only",
}), [ 10, 20 ]);
t.deepEqual(styleSearchResults({
source: "var(--horse)",
target: "v",
functionArguments: "only",
}), []);
t.deepEqual(styleSearchResults({
source: "abc (abc)",
target: "b",
functionArguments: "only",
}), [], "parens without function is not interpreted as a function");
t.deepEqual(styleSearchResults({
source: "de$(abc)fg",
target: "b",
functionArguments: "only",
}), [], "parens preceded by `$`, for postcss-simple-vars interpolation, not interpreted as a function");
t.deepEqual(styleSearchResults({
source: "de$(abc)fg",
target: ")",
functionArguments: "only",
}), [], "closing paren of non-function is ignored");
t.end();
});
test("functionArguments: 'skip'", function(t) {
t.deepEqual(styleSearchResults({
source: "abc var(--cba)",
target: "c",
functionArguments: "skip",
}), [2]);
t.deepEqual(styleSearchResults({
source: "abc var(--cba)",
target: "a",
functionArguments: "skip",
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc \"a var(--cba)\"",
target: "a",
functionArguments: "skip",
}), [0]);
t.deepEqual(styleSearchResults({
source: "translate(1px, calc(1px * 2))",
target: "1",
functionArguments: "skip",
}), []);
t.deepEqual(styleSearchResults({
source: "var(--horse)",
target: "v",
functionArguments: "skip",
}), []);
t.deepEqual(styleSearchResults({
source: "abc (def)",
target: "e",
functionArguments: "skip",
}), [6], "parens without function is not interpreted as a function");
t.end();
});
test("parentheticals: 'skip'", function(t) {
t.deepEqual(styleSearchResults({
source: "abc var(--cba)",
target: "c",
parentheticals: "skip",
}), [2]);
t.deepEqual(styleSearchResults({
source: "abc var(--cba)",
target: "a",
parentheticals: "skip",
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc \"a var(--cba)\"",
target: "a",
parentheticals: "skip",
}), [0]);
t.deepEqual(styleSearchResults({
source: "translate(1px, calc(1px * 2))",
target: "1",
parentheticals: "skip",
}), []);
t.deepEqual(styleSearchResults({
source: "var(--horse)",
target: "v",
parentheticals: "skip",
}), []);
t.deepEqual(styleSearchResults({
source: "abc (def)",
target: "e",
parentheticals: "skip",
}), [], "parens without function are still ignored");
t.end();
});
test("ignores matches inside single-quote strings", function(t) {
t.deepEqual(styleSearchResults({
source: "abc 'abc'",
target: "c",
}), [2]);
t.deepEqual(styleSearchResults({
source: "abc 'abc' cba",
target: "c",
}), [ 2, 10 ]);
t.end();
});
test("ignores matches inside double-quote strings", function(t) {
t.deepEqual(styleSearchResults({
source: 'abc "abc"',
target: "c",
}), [2]);
t.deepEqual(styleSearchResults({
source: 'abc "abc" cba',
target: "c",
}), [ 2, 10 ]);
t.end();
});
test("strings: 'check'", function(t) {
t.deepEqual(styleSearchResults({
source: "abc 'abc'",
target: "b",
strings: "check",
}), [ 1, 6 ]);
t.deepEqual(styleSearchResults({
source: "abc /* 'abc' */",
target: "b",
strings: "check",
}), [1], "no strings inside comments");
t.end();
});
test("strings: 'only'", function(t) {
t.deepEqual(styleSearchResults({
source: 'abc "abc"',
target: "b",
strings: "only",
}), [6]);
t.deepEqual(styleSearchResults({
source: "p[href^='https://']:before { content: \"\/*\"; \n top: 0;\n}",
target: "\n",
strings: "only",
}), [], "comments do not start inside strings");
t.end();
});
test("ignores matches inside comments", function(t) {
t.deepEqual(styleSearchResults({
source: "abc/*comment*/",
target: "m",
}), []);
t.deepEqual(styleSearchResults({
source: "abc/*command*/",
target: "a",
}), [0]);
t.end();
});
test("comments: 'check'", function(t) {
t.deepEqual(styleSearchResults({
source: "abc/*abc*/",
target: "b",
comments: "check",
}), [ 1, 6 ]);
t.end();
});
test("comments: 'only'", function(t) {
t.deepEqual(styleSearchResults({
source: "abc/*abc*/",
target: "b",
comments: "only",
}), [6]);
t.deepEqual(styleSearchResults({
source: "abc/*/abc*/",
target: "b",
comments: "only",
}), [7]);
t.deepEqual(styleSearchResults({
source: "ab'c/*abc*/c'",
target: "b",
comments: "only",
}), [], "no comments inside strings");
t.end();
});
test("ignores matches inside single-line comment", function(t) {
t.deepEqual(styleSearchResults({
source: "abc // comment",
target: "m",
}), []);
t.deepEqual(styleSearchResults({
source: "abc // command",
target: "a",
}), [0]);
// Triple-slash comments are used for sassdoc
t.deepEqual(styleSearchResults({
source: "abc /// it's all ok",
target: "a",
}), [0]);
t.end();
});
test("handles escaped double-quotes in double-quote strings", function(t) {
t.deepEqual(styleSearchResults({
source: 'abc "ab\\"c"',
target: "c",
}), [2]);
t.deepEqual(styleSearchResults({
source: 'abc "a\\"bc" foo cba',
target: "c",
}), [ 2, 16 ]);
t.end();
});
test("handles escaped double-quotes in single-quote strings", function(t) {
t.deepEqual(styleSearchResults({
source: "abc 'ab\\'c'",
target: "c",
}), [2]);
t.deepEqual(styleSearchResults({
source: "abc 'a\\'bc' foo cba",
target: "c",
}), [ 2, 16 ]);
t.end();
});
test("count", function(t) {
const endCounts = []
styleSearch({ source: "123 123 123", target: "1" }, function(index, count) {
endCounts.push(count);
});
t.deepEqual(endCounts, [ 1, 2, 3 ]);
t.end();
});
test("finds parentheses", function(t) {
t.deepEqual(styleSearchResults({
source: "a { color: rgb(0,0,0); }",
target: "(",
}), [14]);
t.deepEqual(styleSearchResults({
source: "a { color: rgb(0,0,0); }",
target: ")",
}), [20]);
t.end();
});
test("functionNames: 'check'", function(t) {
t.deepEqual(styleSearchResults({
source: "a { color: rgb(0,0,0); }",
target: "rgb",
}), []);
t.deepEqual(styleSearchResults({
source: "a { color: rgb(0,0,0); }",
target: "rgb",
functionNames: "check"
}), [11]);
t.end();
});
test("non-single-character target", function(t) {
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "abc",
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "cb",
}), [4]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: "c c",
}), [2]);
t.deepEqual(styleSearchResults({
source: "abc cba abc",
target: "abc",
}), [ 0, 8 ]);
t.deepEqual(styleSearchResults({
source: "abc cba 'abc'",
target: "abc",
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc cb",
target: "aa",
}), []);
t.end();
});
test("array target", function(t) {
t.deepEqual(styleSearchResults({
source: "abc cba",
target: [ "a", "b" ],
}), [ 0, 1, 5, 6 ]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: [ "c", "b" ],
}), [ 1, 2, 4, 5 ]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: [ "bc", "a" ],
}), [ 0, 1, 6 ]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: [ "abc", "f" ],
}), [0]);
t.deepEqual(styleSearchResults({
source: "abc cba",
target: [ 0, 1, 2 ],
}), []);
t.end();
});
test("match object", function(t) {
styleSearch({ source: "abc", target: "bc" }, function(match) {
t.equal(match.startIndex, 1);
t.equal(match.endIndex, 3);
t.equal(match.target, "bc");
t.equal(match.insideFunctionArguments, false);
t.equal(match.insideComment, false);
});
const twoMatches = []
styleSearch({ source: "abc bca", target: [ "bc ", "ca" ] }, function(match) {
twoMatches.push(match);
});
const firstMatch = twoMatches[0]
const secondMatch = twoMatches[1]
t.equal(firstMatch.startIndex, 1);
t.equal(firstMatch.endIndex, 4);
t.equal(firstMatch.target, "bc ");
t.equal(firstMatch.insideFunctionArguments, false);
t.equal(firstMatch.insideComment, false);
t.equal(secondMatch.startIndex, 5);
t.equal(secondMatch.endIndex, 7);
t.equal(secondMatch.target, "ca");
t.equal(secondMatch.insideFunctionArguments, false);
t.equal(secondMatch.insideComment, false);
t.end();
});
test("match inside a function", function(t) {
styleSearch({ source: "a { color: rgb(0, 0, 1); }", target: "1" }, function(match) {
t.equal(match.insideFunctionArguments, true);
t.equal(match.insideComment, false);
t.end();
});
});
test("match inside a comment", function(t) {
styleSearch({
source: "a { color: /* 1 */ pink; }",
target: "1",
comments: "check"
}, function(match) {
t.equal(match.insideFunctionArguments, false);
t.equal(match.insideComment, true);
t.end();
});
});
test("match inside a block comment", function(t) {
styleSearch({
source: "a { color:\n/**\n * 0\n * 1\n */\npink; }",
target: "1",
comments: "check"
}, function(match) {
t.equal(match.insideFunctionArguments, false);
t.equal(match.insideComment, true);
t.end();
});
});
test("match inside a comment inside function", function(t) {
styleSearch({
source: "a { color: rgb(0, 0, 0 /* 1 */); }",
target: "1",
comments: "check"
}, function(match) {
t.equal(match.insideFunctionArguments, true);
t.equal(match.insideComment, true);
t.end();
});
});
test("error on multiple 'only' options", function(t) {
t.throws(function() {
styleSearch({
source: "a {}",
target: "a",
comments: "only",
strings: "only",
}, function(match) {});
}, /Only one syntax/);
t.end();
});