mirror of https://github.com/lukechilds/docs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.8 KiB
136 lines
3.8 KiB
/* eslint-env node */
|
|
const glob = require('glob');
|
|
const util = require('./util');
|
|
const argv = require('minimist')(process.argv.slice(2));
|
|
|
|
argv._.forEach(arg => {
|
|
const tokens = arg.split('=');
|
|
argv[tokens[0]] = tokens[1] || true;
|
|
});
|
|
|
|
const currentScopeRegex = /\/\* scoped: ([^*]*) \*\//;
|
|
const currentScopeLegacyRegex = new RegExp('\\.(uk-scope)');
|
|
|
|
const allFiles = [];
|
|
|
|
if (argv.h || argv.help) {
|
|
console.log(`
|
|
usage:
|
|
|
|
scope.js [-s{cope}=your_great_new_scope_name][cleanup]
|
|
|
|
example:
|
|
|
|
scope.js // will scope with uk-scope
|
|
scope.js -s "my-scope" // will replace any existing scope with my-scope
|
|
scope.js cleanup // will remove current scope
|
|
|
|
`);
|
|
} else {
|
|
readAllFiles().then(startProcess);
|
|
}
|
|
|
|
function startProcess() {
|
|
|
|
const currentScope = getCurrentScope();
|
|
|
|
if (argv.cleanup && currentScope) {
|
|
cleanUp(currentScope).then(store).catch(console.log);
|
|
} else if (currentScope) {
|
|
getNewScope().then(newScope => {
|
|
if (currentScope !== newScope) {
|
|
cleanUp(currentScope).then(() => doScope(newScope)).then(store).catch(console.log);
|
|
} else {
|
|
console.log('already scoped with:' + currentScope);
|
|
}
|
|
});
|
|
} else {
|
|
getNewScope().then(doScope).then(store).catch(console.log);
|
|
}
|
|
}
|
|
|
|
function getNewScope() {
|
|
|
|
const scopeFromInput = argv.scope || argv.s || 'uk-scope';
|
|
|
|
if (util.validClassName.test(scopeFromInput)) {
|
|
return Promise.resolve(scopeFromInput);
|
|
} else {
|
|
throw 'illegal scope-name: ' + scopeFromInput;
|
|
}
|
|
}
|
|
|
|
function isScoped(data) {
|
|
let varName = data.match(currentScopeRegex);
|
|
if (varName) {
|
|
return varName[1];
|
|
} else {
|
|
varName = data.match(currentScopeLegacyRegex);
|
|
}
|
|
return varName && varName[1];
|
|
}
|
|
|
|
function doScope(scopeFromInput) {
|
|
|
|
const scopes = [];
|
|
allFiles.forEach(store => {
|
|
|
|
scopes.push(util.renderLess(`.${scopeFromInput} {\n${store.data}\n}`)
|
|
.then(output =>
|
|
store.data = `/* scoped: ${scopeFromInput} */` +
|
|
output.replace(new RegExp(`.${scopeFromInput} ${/{(.|[\r\n])*?}/.source}`), '')
|
|
.replace(new RegExp(`.${scopeFromInput} ${/\s((\.(uk-(drag|modal-page|offcanvas-page|offcanvas-flip)))|html)/.source}`, 'g'), '$1')
|
|
)
|
|
);
|
|
});
|
|
|
|
return Promise.all(scopes);
|
|
|
|
}
|
|
|
|
function store() {
|
|
const writes = [];
|
|
allFiles.forEach(({file, data}) => writes.push(util.write(file, data).then(util.minify)));
|
|
return Promise.all(writes);
|
|
}
|
|
|
|
function cleanUp(currentScope) {
|
|
allFiles.forEach((store) => {
|
|
const string = currentScope.split(' ').map(scope => `.${scope}`).join(' ');
|
|
store.data = store.data.replace(new RegExp(/ */.source + string + / ({[\s\S]*?})?/.source, 'g'), '') // replace classes
|
|
.replace(new RegExp(currentScopeRegex.source, 'g'), ''); // remove scope comment
|
|
});
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
function getCurrentScope() {
|
|
|
|
let currentScope;
|
|
allFiles.forEach(({data}) => {
|
|
const scope = isScoped(data);
|
|
if (currentScope && scope !== currentScope) {
|
|
throw 'scopes used on current css differ from file to file.';
|
|
}
|
|
currentScope = scope;
|
|
});
|
|
|
|
return currentScope;
|
|
}
|
|
|
|
function readAllFiles() {
|
|
return new Promise(res => {
|
|
glob('dist/**/!(*.min).css', (err, files) => {
|
|
//read files, check scopes
|
|
const reads = [];
|
|
files.forEach(file => {
|
|
const promise = util.read(file, data => {
|
|
allFiles.push({file, data});
|
|
});
|
|
reads.push(promise);
|
|
});
|
|
Promise.all(reads).then(res);
|
|
});
|
|
|
|
});
|
|
}
|
|
|