This commit is contained in:
chrosey
2017-09-13 07:52:34 +02:00
parent a1f16c37f4
commit 2340b0226b
24621 changed files with 2912161 additions and 149 deletions
+29
View File
@@ -0,0 +1,29 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
function ReplaceMany() {
this.replacements = [];
}
module.exports = ReplaceMany;
ReplaceMany.prototype.replace = function(start, length, newString) {
this.replacements.push([start, start + length, newString]);
return this;
};
ReplaceMany.prototype.run = function(string) {
this.replacements.sort(function(a, b) {
return b[0] - a[0];
});
var result = [string];
this.replacements.forEach(function(repl) {
var str = result.pop();
var done = str.substr(repl[1]);
var leftover = str.substr(0, repl[0]);
result.push(done, repl[2], leftover);
});
result.reverse();
return result.join("");
};
+50
View File
@@ -0,0 +1,50 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function() {
var list = [];
// return the list of modules as css string
list.toString = function toString() {
var result = [];
for(var i = 0; i < this.length; i++) {
var item = this[i];
if(item[2]) {
result.push("@media " + item[2] + "{" + item[1] + "}");
} else {
result.push(item[1]);
}
}
return result.join("");
};
// import a list of modules into the list
list.i = function(modules, mediaQuery) {
if(typeof modules === "string")
modules = [[null, modules, ""]];
var alreadyImportedModules = {};
for(var i = 0; i < this.length; i++) {
var id = this[i][0];
if(typeof id === "number")
alreadyImportedModules[id] = true;
}
for(i = 0; i < modules.length; i++) {
var item = modules[i];
// skip already imported module
// this implementation is not 100% perfect for weird media query combinations
// when a module is imported multiple times with different media queries.
// I hope this will never occur (Hey this way we have smaller bundles)
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
if(mediaQuery && !item[2]) {
item[2] = mediaQuery;
} else if(mediaQuery) {
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
}
list.push(item);
}
}
};
return list;
};
+38
View File
@@ -0,0 +1,38 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
module.exports = function(locals, localExtends, importedUrls, importUrlPrefix, result, importAccess) {
var localKeys = Object.keys(locals);
if(localKeys.length > 0) {
var localLines = localKeys.map(function(key, idx) {
var line = " " + JSON.stringify(key) + ": ";
function addExtend(extend) {
if(extend.from) {
var importUrl = importUrlPrefix +
(extend.fromType === "url" ? loaderUtils.urlToRequest(extend.from) : extend.from);
if(importedUrls && result && importedUrls.indexOf(importUrl) < 0) {
result.push("exports.i(require(" + loaderUtils.stringifyRequest(this, importUrl) + "), \"\");");
importedUrls.push(importUrl);
}
line += " + \" \" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ")" + importAccess + "[" + JSON.stringify(extend.name) + "]";
} else if(locals[extend.name]) {
line += " + \" \" + " + JSON.stringify(locals[extend.name]);
if(localExtends[extend.name]) {
localExtends[extend.name].forEach(addExtend, this);
}
} else if(this.emitError) {
this.emitError("Cannot extend from unknown class '" + extend.name + "'");
}
}
line += JSON.stringify(locals[key]);
if(localExtends[key]) {
localExtends[key].forEach(addExtend, this);
}
if(idx !== localKeys.length - 1) line += ",";
return line;
}, this);
return "{\n" + localLines.join("\n") + "\n}";
}
};
+15
View File
@@ -0,0 +1,15 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
module.exports = function getLocalIdent(loaderContext, localIdentName, localName, options) {
var request = loaderContext.options && typeof loaderContext.options.context === "string" ?
loaderUtils.stringifyRequest({ context: loaderContext.options.context }, loaderUtils.getRemainingRequest(loaderContext)) :
loaderContext.request;
options.content = localName + " " + request;
options.context = loaderContext.options && typeof loaderContext.options.context === "string" ? loaderContext.options.context : loaderContext.context;
localIdentName = localIdentName.replace(/\[local\]/gi, localName);
var hash = loaderUtils.interpolateName(loaderContext, localIdentName, options);
return hash.replace(/[^a-zA-Z0-9\-_]/g, "-").replace(/^([^a-zA-Z_])/, "_$1");
};
+162
View File
@@ -0,0 +1,162 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var path = require("path");
var parseSource = require("./parseSource");
var ReplaceMany = require("./ReplaceMany");
var loaderUtils = require("loader-utils");
var SourceListMap = require("source-list-map").SourceListMap;
var CleanCSS = require("clean-css");
module.exports = function(content, map) {
if(this.cacheable) this.cacheable();
var query = loaderUtils.parseQuery(this.query);
var root = query.root;
var forceMinimize = query.minimize;
var importLoaders = parseInt(query.importLoaders, 10) || 0;
var minimize = typeof forceMinimize !== "undefined" ? !!forceMinimize : (this && this.minimize);
var moduleMode = query.module;
if(typeof map !== "string") {
map = JSON.stringify(map);
}
var result = [];
// for importing CSS
var loadersRequest = this.loaders.slice(
this.loaderIndex,
this.loaderIndex + 1 + importLoaders
).map(function(x) { return x.request; }).join("!");
var importUrlPrefix = "-!" + loadersRequest + "!";
var stuff = parseSource(content);
var replacer = new ReplaceMany();
// store already imported files
var importedUrls = [];
// add @imports to result
stuff.imports.forEach(function(imp) {
replacer.replace(imp.start, imp.length, "");
if(!loaderUtils.isUrlRequest(imp.url, root)) {
result.push("exports.push([module.id, " +
JSON.stringify("@import url(" + imp.url + ");") + ", " +
JSON.stringify(imp.mediaQuery) + "]);");
} else {
var importUrl = importUrlPrefix +
(moduleMode ? imp.url : loaderUtils.urlToRequest(imp.url));
result.push("exports.i(require(" + loaderUtils.stringifyRequest(this, importUrl) + "), " + JSON.stringify(imp.mediaQuery) + ");");
if(!imp.mediaQuery)
importedUrls.push(importUrl);
}
}, this);
// replace url(...)
if(query.url !== false) {
stuff.urls.forEach(function(url, idx) {
replacer.replace(url.start, url.length, "__CSSLOADERURL_" + idx + "__");
});
}
// replace :local()
var locals = {};
var localExtends = {};
require("./processLocals").call(this, stuff.selectors, query, replacer, locals, localExtends);
// remove stuff
stuff.remove.forEach(function(rem) {
replacer.replace(rem.start, rem.length, "");
});
// pass errors from parser
if(this.emitError) {
stuff.errors.forEach(function(err) {
this.emitError(err);
}, this);
}
// generate the locals
var localsData = require("./generateLocals").call(this, locals, localExtends, importedUrls, importUrlPrefix, result, ".locals");
if(localsData) {
result.push("exports.locals = " + localsData + ";");
}
// transform the CSS
var cssContent = replacer.run(content);
// minimize CSS
if(minimize) {
var options = Object.create(query);
if(query.sourceMap && map) {
options.sourceMap = map;
}
var minimizeResult = new CleanCSS(options).minify(cssContent);
map = minimizeResult.sourceMap;
cssContent = minimizeResult.styles;
if(typeof map !== "string")
map = JSON.stringify(map);
}
function toEmbStr(str) {
return JSON.stringify(str).replace(/^"|"$/g, "");
}
// replace url(...) in the generated code
var css = JSON.stringify(cssContent);
var urlRegExp = /__CSSLOADERURL_[0-9]+__/g;
css = css.replace(urlRegExp, function(str) {
var match = /^__CSSLOADERURL_([0-9]+)__$/.exec(str);
if(!match) return str;
var idx = parseInt(match[1], 10);
if(!stuff.urls[idx]) return str;
var urlItem = stuff.urls[idx];
var url = urlItem.url;
if(!loaderUtils.isUrlRequest(url, root))
return toEmbStr(urlItem.raw);
idx = url.indexOf("?#");
if(idx < 0) idx = url.indexOf("#");
var urlRequest;
if(idx > 0) { // idx === 0 is catched by isUrlRequest
// in cases like url('webfont.eot?#iefix')
urlRequest = url.substr(0, idx);
if(!moduleMode) urlRequest = loaderUtils.urlToRequest(urlRequest, root);
return "\"+require(" + loaderUtils.stringifyRequest(this, urlRequest) + ")+\"" + url.substr(idx);
}
urlRequest = url;
if(!moduleMode) urlRequest = loaderUtils.urlToRequest(url, root);
return "\"+require(" + loaderUtils.stringifyRequest(this, urlRequest) + ")+\"";
}.bind(this));
// add a SourceMap
if(query.sourceMap && !minimize) {
var cssRequest = loaderUtils.getRemainingRequest(this);
var request = loaderUtils.getCurrentRequest(this);
if(!map) {
var sourceMap = new SourceListMap();
sourceMap.add(content, cssRequest, content);
map = sourceMap.toStringWithSourceMap({
file: request
}).map;
if(map.sources) {
map.sources = map.sources.map(function(source) {
var p = path.relative(query.context || this.options.context, source).replace(/\\/g, "/");
if(p.indexOf("../") !== 0)
p = "./" + p;
return "/" + p;
}, this);
map.sourceRoot = "webpack://";
}
map = JSON.stringify(map);
}
result.push("exports.push([module.id, " + css + ", \"\", " + map + "]);");
} else {
result.push("exports.push([module.id, " + css + ", \"\"]);");
}
// embed runtime
return "exports = module.exports = require(" + loaderUtils.stringifyRequest(this, require.resolve("./css-base.js")) + ")();\n" +
result.join("\n");
};
+32
View File
@@ -0,0 +1,32 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
var parseSource = require("./parseSource");
module.exports = function(content) {
if(this.cacheable) this.cacheable();
var query = loaderUtils.parseQuery(this.query);
var importLoaders = parseInt(query.importLoaders, 10) || 0;
// for importing CSS
var loadersRequest = this.loaders.slice(
this.loaderIndex,
this.loaderIndex + 1 + importLoaders
).map(function(x) { return x.request; }).join("!");
var importUrlPrefix = "-!" + loadersRequest + "!";
var stuff = parseSource(content);
var locals = {};
var localExtends = {};
require("./processLocals").call(this, stuff.selectors, query, null, locals, localExtends);
// generate the locals
var localsData = require("./generateLocals").call(this, locals, localExtends, null, importUrlPrefix, null, "");
return "module.exports = " + localsData + ";";
};
+419
View File
@@ -0,0 +1,419 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
var Parser = require("fastparse");
function errorMatch(message, newParserMode) {
return function(match) {
var index = arguments[arguments.length - 1];
var nextLine = this.source.indexOf("\n", index);
var splittedSource = this.source.substr(0, index).split("\n");
var line = splittedSource.length;
var lineBeforeError = splittedSource.pop();
var lineAfterError = this.source.substr(index, nextLine);
this.errors.push("Unexpected '" + match + "' in line " + (line + 1) + ", " + message + "\n" +
lineBeforeError + lineAfterError + "\n" + lineBeforeError.replace(/[^\\s]/g, " ") + "^");
return newParserMode;
};
}
function urlMatch(match, textBeforeUrl, replacedText, url, index) {
this.urls.push({
url: url,
raw: replacedText,
start: index + textBeforeUrl.length,
length: replacedText.length
});
}
function importMatch(match, url, mediaQuery, index) {
this.imports.push({
url: url,
mediaQuery: mediaQuery,
start: index,
length: match.length
});
}
function rulesStartMatch() {
this.blockMode = this.mode;
return "firstRule";
}
function rulesEndMatch() {
this.mode = null;
this.activeSelectors = [];
return "source";
}
function nextSelectorMatch() {
this.mode = null;
}
function enableLocal(match, whitespace, index) {
this.remove.push({
start: index + whitespace.length,
length: match.length - whitespace.length
});
this.mode = "local";
}
function enableGlobal(match, whitespace, index) {
this.remove.push({
start: index + whitespace.length,
length: match.length - whitespace.length
});
this.mode = "global";
}
function localStart(match, whitespace, index) {
this.remove.push({
start: index + whitespace.length,
length: match.length - whitespace.length
});
this.bracketStatus = 0;
return "local";
}
function globalStart(match, whitespace, index) {
this.remove.push({
start: index + whitespace.length,
length: match.length - whitespace.length
});
this.bracketStatus = 0;
return "global";
}
function withMode(mode, fn) {
return function() {
var oldMode = this.mode;
this.mode = mode;
var newParserMode = fn.apply(this, arguments);
this.mode = oldMode;
return newParserMode;
};
}
function jump(newParserMode, fn) {
return function() {
fn.apply(this, arguments);
return newParserMode;
};
}
function innerBracketIn() {
this.bracketStatus++;
}
function innerBracketOut(match, index) {
if(this.bracketStatus-- === 0) {
this.remove.push({
start: index,
length: match.length
});
return "source";
}
}
function selectorMatch(match, prefix, name, index) {
var selector = {
name: name,
prefix: prefix,
start: index,
length: match.length,
mode: this.mode
};
this.selectors.push(selector);
this.activeSelectors.push(selector);
}
function ruleScopedMatch() {
this.mode = this.blockMode;
return "ruleScoped";
}
function extendsStartMatch(match, index) {
this.remove.push({
start: index,
length: 0
});
this.activeExtends = [];
return "extends";
}
function extendsEndMatch(match, index) {
var lastRemove = this.remove[this.remove.length - 1];
lastRemove.length = index + match.length - lastRemove.start;
if(this.activeExtends.length === 0) {
errorMatch("expected class names")(match, index);
return "rule";
}
return "firstRule";
}
function extendsClassNameMatch(match, name, index) {
this.activeSelectors.forEach(function(selector) {
if(!selector.extends)
selector.extends = [];
var extend = {
name: name,
start: index,
length: match.length,
from: null,
fromType: null
};
selector.extends.push(extend);
this.activeExtends.push(extend);
}, this);
}
function extendsFromUrlMatch(match, request) {
this.activeExtends.forEach(function(extend) {
extend.from = request;
extend.fromType = "url";
});
}
function extendsFromMatch(match, request) {
this.activeExtends.forEach(function(extend) {
extend.from = loaderUtils.parseString(request);
extend.fromType = "module";
});
}
var parser = new Parser({
// shared stuff
comments: {
"/\\*[\\s\\S]*?\\*/": true
},
strings: {
'"([^\\\\"]|\\\\.)*"': true,
"'([^\\\\']|\\\\.)*'": true
},
urls: {
'(url\\s*\\()(\\s*"([^"]*)"\\s*)\\)': urlMatch,
"(url\\s*\\()(\\s*'([^']*)'\\s*)\\)": urlMatch,
"(url\\s*\\()(\\s*([^)]*)\\s*)\\)": urlMatch
},
scopedRules: {
"(?:-[a-z]+-)?animation(?:-name)?:": ruleScopedMatch
},
// states
source: [
"comments",
"strings",
"urls",
{
// imports
'@\\s*import\\s+"([^"]*)"\\s*([^;\\n]*);': importMatch,
"@\\s*import\\s+'([^'']*)'\\s*([^;\\n]*);": importMatch,
'@\\s*import\\s+url\\s*\\(\\s*"([^"]*)"\\s*\\)\\s*([^;\\n]*);': importMatch,
"@\\s*import\\s+url\\s*\\(\\s*'([^']*)'\\s*\\)\\s*([^;\\n]*);": importMatch,
"@\\s*import\\s+url\\s*\\(\\s*([^)]*)\\s*\\)\\s*([^;\\n]*);": importMatch,
// charset
"@charset": true,
// namespace
"@(?:-[a-z]+-)?namespace": true,
// atrule
"@(?:-[a-z]+-)?keyframes": "atruleScoped",
"@": "atrule"
},
{
// local
"(\\s*):local\\(": localStart,
"():local": enableLocal,
"(\\s+):local\\s+": enableLocal,
// global
"(\\s*):global\\(": globalStart,
"():global": enableGlobal,
"(\\s+):global\\s+": enableGlobal,
// class
"(\\.)(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)": selectorMatch,
// id
"(#)(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)": selectorMatch,
// inside
"\\{": rulesStartMatch,
",": nextSelectorMatch
}
],
atruleScoped: [
"comments",
"strings",
{
// identifier
":local\\(\\s*()([A-Za-z_\\-0-9]+)\\s*\\)": withMode("local", selectorMatch),
":global\\(\\s*()([A-Za-z_\\-0-9]+)\\s*\\)": withMode("global", selectorMatch),
"()([A-Za-z_\\-0-9]+)": selectorMatch,
// local
"():local": enableLocal,
"(\\s+):local\\s+": enableLocal,
// global
"():global": enableGlobal,
"(\\s+):global\\s+": enableGlobal,
// back to normal source
"\\{": "source"
}
],
atrule: [
"comments",
"strings",
{
// back to normal source
"\\{": "source"
}
],
ruleScoped: [
"comments",
{
// identifier
":local\\(\\s*()([A-Za-z_\\-0-9]+)\\s*\\)": jump("ruleScopedInactive", withMode("local", selectorMatch)),
":global\\(\\s*()([A-Za-z_\\-0-9]+)\\s*\\)": jump("ruleScopedInactive", withMode("global", selectorMatch)),
"()([A-Za-z_\\-0-9]+)": jump("ruleScopedInactive", selectorMatch),
// local
"():local": enableLocal,
"(\\s+):local\\s+": enableLocal,
// global
"():global": enableGlobal,
"(\\s+):global\\s+": enableGlobal,
// back to normal rule
";": "rule",
// back to normal source
"\\}": rulesEndMatch
}
],
ruleScopedInactive: [
"comments",
{
// reactivate
",": ruleScopedMatch,
// back to normal rule
";": "rule",
// back to normal source
"\\}": rulesEndMatch
}
],
rule: [
"comments",
"strings",
"urls",
"scopedRules",
{
// back to normal source
"\\}": rulesEndMatch
}
],
firstRule: [
"rule",
{
"extends\\s*:": extendsStartMatch,
// whitespace
"\\s+": true,
// url
".": "rule"
}
],
extends: [
"comments",
{
";\\s*": extendsEndMatch,
// whitespace
"\\s+": true,
// from
"from": "extendsFrom",
// class name
"([A-Za-z_\\-0-9]+)": extendsClassNameMatch,
".+[;}]": errorMatch("expected class names or 'from'", "rule"),
".": errorMatch("expected class names or 'from'", "rule")
}
],
extendsFrom: [
"comments",
{
";\\s*": extendsEndMatch,
// whitespace
"\\s+": true,
// module
'url\\s*\\(\\s*"([^"]*)"\\s*\\)': extendsFromUrlMatch,
"url\\s*\\(\\s*'([^']*)'\\s*\\)": extendsFromUrlMatch,
"url\\s*\\(\\s*([^)]*)\\s*\\)": extendsFromUrlMatch,
'("(?:[^\\\\"]|\\\\.)*")': extendsFromMatch,
"('(?:[^\\\\']|\\\\.)*')": extendsFromMatch,
".+[;}]": errorMatch("expected module identifier (a string or 'url(...)'')", "rule"),
".": errorMatch("expected module identifier (a string or 'url(...)'')", "rule")
}
],
local: [
"comments",
"strings",
{
// class
"(\\.)([A-Za-z_\\-0-9]+)": withMode("local", selectorMatch),
// id
"(#)([A-Za-z_\\-0-9]+)": withMode("local", selectorMatch),
// brackets
"\\(": innerBracketIn,
"\\)": innerBracketOut
}
],
global: [
"comments",
"strings",
{
// class
"(\\.)([A-Za-z_\\-0-9]+)": withMode("global", selectorMatch),
// id
"(#)([A-Za-z_\\-0-9]+)": withMode("global", selectorMatch),
// brackets
"\\(": innerBracketIn,
"\\)": innerBracketOut
}
]
});
module.exports = function parseSource(source) {
var context = {
source: source,
imports: [],
urls: [],
selectors: [],
remove: [],
errors: [],
activeSelectors: [],
bracketStatus: 0,
mode: null
};
return parser.parse("source", source, context);
};
+39
View File
@@ -0,0 +1,39 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var getLocalIdent = require("./getLocalIdent");
module.exports = function(parsedLocals, query, replacer, locals, localExtends) {
var localIdentName = query.localIdentName || "[hash:base64]";
var localIdentRegExp = query.localIdentRegExp;
var moduleMode = query.module;
parsedLocals.forEach(function(selector) {
if(moduleMode) {
if(selector.mode === "global")
return;
} else {
if(selector.mode !== "local")
return;
}
var ident;
var name = selector.name;
if(!locals[name]) {
ident = getLocalIdent(this, localIdentName, name, {
regExp: localIdentRegExp
});
locals[name] = ident;
} else {
ident = locals[name];
}
if(selector.extends) {
selector.extends.forEach(function(extend) {
if(!localExtends[name])
localExtends[name] = [];
localExtends[name].push(extend);
});
}
if(replacer)
replacer.replace(selector.start, selector.length, selector.prefix + ident);
}, this);
};