165 lines
5.5 KiB
JavaScript
165 lines
5.5 KiB
JavaScript
// (C) Copyright 2015 Moodle Pty Ltd.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
const gulp = require('gulp');
|
|
const through = require('through');
|
|
const bufferFrom = require('buffer-from');
|
|
const concat = require('gulp-concat');
|
|
const pathLib = require('path');
|
|
const fs = require('fs');
|
|
|
|
/**
|
|
* Task to combine scss into a single file.
|
|
*/
|
|
class CombineScssTask {
|
|
|
|
/**
|
|
* Finds the file and returns its content.
|
|
*
|
|
* @param capture Import file path.
|
|
* @param baseDir Directory where the file was found.
|
|
* @param paths Alternative paths where to find the imports.
|
|
* @param parsedFiles Already parsed files to reduce size of the result.
|
|
* @return Partially combined scss.
|
|
*/
|
|
getReplace(capture, baseDir, paths, parsedFiles) {
|
|
let parse = pathLib.parse(pathLib.resolve(baseDir, capture + '.scss'));
|
|
let file = parse.dir + '/' + parse.name;
|
|
|
|
if (file.slice(-3) === '.wp') {
|
|
console.log('Windows Phone not supported "' + capture);
|
|
// File was already parsed, leave the import commented.
|
|
return '// @import "' + capture + '";';
|
|
}
|
|
|
|
if (!fs.existsSync(file + '.scss')) {
|
|
// File not found, might be a partial file.
|
|
file = parse.dir + '/_' + parse.name;
|
|
}
|
|
|
|
// If file still not found, try to find the file in the alternative paths.
|
|
let x = 0;
|
|
while (!fs.existsSync(file + '.scss') && paths.length > x) {
|
|
parse = pathLib.parse(pathLib.resolve(paths[x], capture + '.scss'));
|
|
file = parse.dir + '/' + parse.name;
|
|
|
|
x++;
|
|
}
|
|
|
|
file = file + '.scss';
|
|
|
|
if (!fs.existsSync(file)) {
|
|
// File not found. Leave the import there.
|
|
console.log('File "' + capture + '" not found');
|
|
return '@import "' + capture + '";';
|
|
}
|
|
|
|
if (parsedFiles.indexOf(file) >= 0) {
|
|
console.log('File "' + capture + '" already parsed');
|
|
// File was already parsed, leave the import commented.
|
|
return '// @import "' + capture + '";';
|
|
}
|
|
|
|
parsedFiles.push(file);
|
|
const text = fs.readFileSync(file);
|
|
|
|
// Recursive call.
|
|
return this.scssCombine(text, parse.dir, paths, parsedFiles);
|
|
}
|
|
|
|
/**
|
|
* Run the task.
|
|
*
|
|
* @param done Function to call when done.
|
|
*/
|
|
run(done) {
|
|
const paths = [
|
|
'node_modules/ionic-angular/themes/',
|
|
'node_modules/font-awesome/scss/',
|
|
'node_modules/ionicons/dist/scss/'
|
|
];
|
|
const parsedFiles = [];
|
|
const self = this;
|
|
|
|
gulp.src([
|
|
'./src/theme/variables.scss',
|
|
'./node_modules/ionic-angular/themes/ionic.globals.*.scss',
|
|
'./node_modules/ionic-angular/themes/ionic.components.scss',
|
|
'./src/**/*.scss',
|
|
]).pipe(through(function(file) { // Combine them based on @import and save it to stream.
|
|
if (file.isNull()) {
|
|
return;
|
|
}
|
|
|
|
parsedFiles.push(file);
|
|
file.contents = bufferFrom(self.scssCombine(
|
|
file.contents, pathLib.dirname(file.path), paths, parsedFiles));
|
|
|
|
this.emit('data', file);
|
|
})).pipe(concat('combined.scss')) // Concat the stream output in single file.
|
|
.pipe(gulp.dest('.')) // Save file to destination.
|
|
.on('end', done);
|
|
}
|
|
|
|
/**
|
|
* Combine scss files with its imports
|
|
*
|
|
* @param content Scss string to treat.
|
|
* @param baseDir Directory where the file was found.
|
|
* @param paths Alternative paths where to find the imports.
|
|
* @param parsedFiles Already parsed files to reduce size of the result.
|
|
* @return Scss string with the replaces done.
|
|
*/
|
|
scssCombine(content, baseDir, paths, parsedFiles) {
|
|
// Content is a Buffer, convert to string.
|
|
if (typeof content != "string") {
|
|
content = content.toString();
|
|
}
|
|
|
|
// Search of single imports.
|
|
let regex = /@import[ ]*['"](.*)['"][ ]*;/g;
|
|
|
|
if (regex.test(content)) {
|
|
return content.replace(regex, (m, capture) => {
|
|
if (capture == "bmma") {
|
|
return m;
|
|
}
|
|
|
|
return this.getReplace(capture, baseDir, paths, parsedFiles);
|
|
});
|
|
}
|
|
|
|
// Search of multiple imports.
|
|
regex = /@import(?:[ \n]+['"](.*)['"][,]?[ \n]*)+;/gm;
|
|
if (regex.test(content)) {
|
|
return content.replace(regex, (m, capture) => {
|
|
let text = '';
|
|
|
|
// Divide the import into multiple files.
|
|
const captures = m.match(/['"]([^'"]*)['"]/g);
|
|
|
|
for (let x in captures) {
|
|
text += this.getReplace(captures[x].replace(/['"]+/g, ''), baseDir, paths, parsedFiles) + '\n';
|
|
}
|
|
|
|
return text;
|
|
});
|
|
}
|
|
|
|
return content;
|
|
}
|
|
}
|
|
|
|
module.exports = CombineScssTask;
|