29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-06-25 14:53:01 +00:00

[4.0] npm build tools update (#23158)

This commit is contained in:
dGrammatiko 2018-12-09 12:30:55 +01:00 committed by George Wilson
parent 1c53f86a8f
commit d5ec90d2bc
26 changed files with 3684 additions and 2519 deletions

View File

@ -1,15 +0,0 @@
{
"presets": [
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"last 1 version"
]
}
}
]
]
}

View File

@ -0,0 +1,30 @@
const Babel = require('@babel/core');
const Fs = require('fs');
/**
*
* @param fileContents the content of the file to be transpiled
* @param settings the settings for the transpiler
* @param output the full pat + filename + extension of the trnspiled file
*/
module.exports.run = (fileContents, settings, output) => {
Babel.transform(fileContents, settings, (error, result) => {
if (error) {
// eslint-disable-next-line no-console
console.error(`${error}`);
process.exit(1);
}
Fs.writeFile(
output,
result.code, // + os.EOL
(fsError) => {
if (fsError) {
// eslint-disable-next-line no-console
console.error(`${fsError}`);
process.exit(1);
}
}
);
});
};

View File

@ -1,3 +1,17 @@
const Fs = require('fs');
const Ini = require('ini');
const Recurs = require('recursive-readdir');
const UglifyCss = require('uglifycss');
const UglifyJs = require('uglify-es');
const RootPath = require('./rootpath.js')._();
const dir = `${RootPath}/installation/language`;
const srcPath = `${RootPath}/build/warning_page`;
// Set the initial template
let incomplete = 'window.errorLocale = {';
let unsupported = 'window.errorLocale = {';
/**
* Will produce 2 .html files
* Expects three files:
@ -8,32 +22,18 @@
* And also specific strings in the languages in the installation folder!
* Also the base strings are held in build/build-modules-js/settings.json
*/
const fs = require('fs');
const ini = require('ini');
const Recurs = require('recursive-readdir');
const uglifyCss = require('uglifycss');
const uglifyJs = require('uglify-es');
const rootPath = require('./rootpath.js')._();
const dir = `${rootPath}/installation/language`;
const srcPath = `${rootPath}/build/warning_page`;
// Set the initial template
let incomplete = 'window.errorLocale = {';
let unsupported = 'window.errorLocale = {';
const buildCheck = (options) => {
let initTemplate = fs.readFileSync(`${srcPath}/template.html`, 'utf-8');
let cssContent = fs.readFileSync(`${srcPath}/template.css`, 'utf-8');
let jsContent = fs.readFileSync(`${srcPath}/template.js`, 'utf-8');
let initTemplate = Fs.readFileSync(`${srcPath}/template.html`, 'utf-8');
let cssContent = Fs.readFileSync(`${srcPath}/template.css`, 'utf-8');
let jsContent = Fs.readFileSync(`${srcPath}/template.js`, 'utf-8');
cssContent = uglifyCss.processString(cssContent, { expandVars: false });
jsContent = uglifyJs.minify(jsContent);
cssContent = UglifyCss.processString(cssContent, { expandVars: false });
jsContent = UglifyJs.minify(jsContent);
Recurs(dir).then(
(files) => {
files.forEach((file) => {
const languageStrings = ini.parse(fs.readFileSync(file, 'UTF-8'));
const languageStrings = Ini.parse(Fs.readFileSync(file, 'UTF-8'));
// Build the variables into json for the unsupported page
if (languageStrings.MIN_PHP_ERROR_LANGUAGE) {
@ -69,8 +69,8 @@ const buildCheck = (options) => {
checkContent = checkContent.replace('{{jsContents}}', jsContent.code);
}
fs.writeFile(
`${rootPath}${options.settings.errorPages[name].destFile}`,
Fs.writeFile(
`${RootPath}${options.settings.errorPages[name].destFile}`,
checkContent,
(err) => {
if (err) {
@ -86,8 +86,9 @@ const buildCheck = (options) => {
}
},
(error) => {
// eslint-disable-next-line no-console
console.error('something exploded', error);
// eslint-disable-next-line no-console
console.error(`${error}`);
process.exit(1);
},
);
};

View File

@ -1,54 +1,66 @@
const fs = require('fs');
const babel = require('babel-core');
const UglifyJS = require('uglify-es');
const os = require('os');
const Babel = require('./babel.js');
const Fs = require('fs');
const MakeDir = require('./make-dir.js');
const Path = require('path');
const headerText = `PLEASE DO NOT MODIFY THIS FILE. WORK ON THE ES6 VERSION.
OTHERWISE YOUR CHANGES WILL BE REPLACED ON THE NEXT BUILD.`;
const babelOptions = {
plugins: [
['add-header-comment', { header: [headerText] }],
],
};
// Predefine some settings
const settings = [
{
presets: [
['@babel/preset-env', {
targets: {
browsers: ["ie 11"]
},
modules: false
}],
],
plugins: [
['add-header-comment', { header: [headerText] }],
['@babel/plugin-transform-classes']
],
comments: true
},
{
presets: [
['@babel/preset-env', {
targets: {
browsers: ["ie 11"]
},
modules: false
}],
"minify"
],
plugins: [
['@babel/plugin-transform-classes']
],
comments: false
}
];
/**
* Compiles es6 files to es5.
* @param filePath
*
* @param file the full path to the file + filename + extension
*/
const compileFile = (filePath) => {
babel.transformFile(filePath, babelOptions, (error, result) => {
if (error) {
// eslint-disable-next-line no-console
console.error(`${error}`);
process.exit(1);
}
const compileFile = (file) => {
const filePath = file.slice(0, -7);
const fileName = filePath.slice(0, -7);
console.log(`Compiling: ${fileName.replace('/build/media_src/', '/media/')}.js`);
fs.writeFile(
`${fileName.replace('/build/media_src/', '/media/').replace('\\build\\media_src\\', '\\media\\')}.js`,
result.code + os.EOL,
(fsError) => {
if (fsError) {
// eslint-disable-next-line no-console
console.error(`${fsError}`);
process.exit(1);
}
}
);
// Also write the minified
fs.writeFile(
`${fileName.replace('/build/media_src/', '/media/').replace('\\build\\media_src\\', '\\media\\')}.min.js`,
UglifyJS.minify(result.code).code + os.EOL,
(fsError) => {
if (fsError) {
// eslint-disable-next-line no-console
console.error(`${fsError}`);
process.exit(1);
}
}
);
const outputFiles = [
`${filePath.replace('/build/media_src/', '/media/').replace('\\build\\media_src\\', '\\media\\')}.js`,
`${filePath.replace('/build/media_src/', '/media/').replace('\\build\\media_src\\', '\\media\\')}.min.js`
];
// Ensure that the directories exist or create them
MakeDir.run(Path.dirname(file).replace('/build/media_src/', '/media/'));
// Get the contents of the ES-XXXX file
let es6File = Fs.readFileSync(file, 'utf8');
settings.forEach((setting, index) => {
Babel.run(es6File, setting, outputFiles[index])
});
};

View File

@ -1,140 +1,190 @@
const autoprefixer = require('autoprefixer');
const babelify = require('babelify');
const browserify = require('browserify');
const fs = require('fs');
const fsExtra = require('fs-extra');
const postcss = require('postcss');
const Autoprefixer = require('autoprefixer');
const Babel = require('./babel.js');
const CssNano = require('cssnano');
const Fs = require('fs');
const FsExtra = require('fs-extra');
const Postcss = require('postcss');
const Promise = require('bluebird');
const Sass = require('node-sass');
const UglyCss = require('uglifycss');
const UglifyJS = require('uglify-es');
const rootPath = require('./rootpath.js')._();
const RootPath = require('./rootpath.js')._();
const createJsFiles = (element, es6File) => {
const b = browserify();
const c = browserify();
fs.writeFileSync(`${rootPath}/media/system/webcomponents/js/joomla-${element}.js`, es6File, { encoding: 'utf8' });
// And the minified version
fs.writeFileSync(`${rootPath}/media/system/webcomponents/js/joomla-${element}.min.js`, UglifyJS.minify(es6File).code, { encoding: 'utf8' });
// Transpile a copy for ES5
fs.writeFileSync(`${rootPath}/media/system/webcomponents/js/joomla-${element}-es5.js`, '');
const bundleFs = fs.createWriteStream(`${rootPath}/media/system/webcomponents/js/joomla-${element}-es5.js`);
const bundleFsMin = fs.createWriteStream(`${rootPath}/media/system/webcomponents/js/joomla-${element}-es5.min.js`);
b.add(`${rootPath}/build/media/webcomponents/js/${element}/${element}.js`);
c.add(`${rootPath}/build/media/webcomponents/js/${element}/${element}.js`);
b.transform(babelify, { presets: ['babel-preset-es2015'] }).bundle().pipe(bundleFs);
c.transform(babelify, { presets: ['babel-preset-es2015', 'babel-preset-minify'] }).bundle().pipe(bundleFsMin);
};
const compile = (options) => {
// Make sure that the dist paths exist
if (!fs.existsSync(`${rootPath}/media/system/webcomponents`)) {
fsExtra.mkdirSync(`${rootPath}/media/system/webcomponents`);
}
if (!fs.existsSync(`${rootPath}/media/system/webcomponents/js`)) {
fsExtra.mkdirSync(`${rootPath}/media/system/webcomponents/js`);
}
if (!fs.existsSync(`${rootPath}/media/system/webcomponents/css`)) {
fs.mkdirSync(`${rootPath}/media/system/webcomponents/css`);
}
options.settings.elements.forEach((element) => {
// Copy the ES6 file
let es6File = fs.readFileSync(`${rootPath}/build/media/webcomponents/js/${element}/${element}.js`, 'utf8');
// Check if there is a css file
if (fs.existsSync(`${rootPath}/build/media/webcomponents/scss/${element}/${element}.scss`)) {
if (!fs.existsSync(`${rootPath}/build/media/webcomponents/scss/${element}/${element}.scss`)) {
return;
}
Sass.render({
file: `${rootPath}/build/media/webcomponents/scss/${element}/${element}.scss`,
}, (error, result) => {
if (error) {
// eslint-disable-next-line no-console
console.error(`${error.column}`);
// eslint-disable-next-line no-console
console.error(`${error.message}`);
// eslint-disable-next-line no-console
console.error(`${error.line}`);
} else {
// Auto prefixing
// eslint-disable-next-line no-console
console.log(`Prefixing for: ${options.settings.browsers}`);
const cleaner = postcss(
[
autoprefixer({
add: false,
browsers: options.settings.browsers
}),
// Define some settings
const settings = [
{
presets: [
['@babel/preset-env', {
"targets": {
"browsers": ["last 1 Chrome version"]
}
}],
],
);
"comments": true
},
{
presets: [
['@babel/preset-env', {
"targets": {
"browsers": ["last 1 Chrome version"]
}
}],
['minify']
],
"comments": false
},
{
presets: [
['@babel/preset-env', {
'targets': {
'browsers': ["ie 11"]
}
}],
],
plugins: [
'@babel/plugin-transform-classes'
],
'comments': true
const prefixer = postcss([autoprefixer]);
},
{
presets: [
if (typeof result === 'object' && result.css) {
cleaner.process(result.css.toString(), {from: undefined})
.then(cleaned => prefixer.process(cleaned.css, {from: undefined}))
.then((res) => {
if (/{{CSS_CONTENTS_PLACEHOLDER}}/.test(es6File)) {
if (typeof res === 'object' && res.css) {
es6File = es6File.replace('{{CSS_CONTENTS_PLACEHOLDER}}', UglyCss.processString(res.css.toString()));
['@babel/preset-env', {
targets: {
browsers: ["ie 11"]
}
}],
['minify']
],
plugins:[
['@babel/plugin-transform-classes'],
],
"comments": false
createJsFiles(element, es6File);
}
} else {
if (typeof res === 'object' && res.css) {
fs.writeFileSync(
`${rootPath}/media/system/webcomponents/css/joomla-${element}.css`,
res.css.toString(),
{ encoding: 'UTF-8' },
);
fs.writeFileSync(
`${rootPath}/media/system/webcomponents/css/joomla-${element}.min.css`,
UglyCss.processString(res.css.toString(), { expandVars: false }),
{ encoding: 'UTF-8' },
);
}
createJsFiles(element, es6File);
}
})
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`${err}`);
process.exit(-1);
});
return ;
// eslint-disable-next-line no-console
console.log(`joomla-${element} was updated.`);
}
}
});
} else {
createJsFiles(element, es6File);
}
});
};
];
const compileCEjs = (options, path) => {
Promise.resolve()
.then(() => compile(options, path))
const outputFiles = [
`${RootPath}/media/system/webcomponents/js/joomla-${element}.js`,
`${RootPath}/media/system/webcomponents/js/joomla-${element}.min.js`,
`${RootPath}/media/system/webcomponents/js/joomla-${element}-es5.js`,
`${RootPath}/media/system/webcomponents/js/joomla-${element}-es5.min.js`,
];
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`${err}`);
process.exit(-1);
settings.forEach((setting, index) => {
Babel.run(es6File, setting, outputFiles[index])
});
};
const compile = (options) => {
// Make sure that the dist paths exist
if (!Fs.existsSync(`${RootPath}/media/system/webcomponents`)) {
FsExtra.mkdirSync(`${RootPath}/media/system/webcomponents`);
}
if (!Fs.existsSync(`${RootPath}/media/system/webcomponents/js`)) {
FsExtra.mkdirSync(`${RootPath}/media/system/webcomponents/js`);
}
if (!Fs.existsSync(`${RootPath}/media/system/webcomponents/css`)) {
Fs.mkdirSync(`${RootPath}/media/system/webcomponents/css`);
}
options.settings.elements.forEach((element) => {
// Get the contents of the ES-XXXX file
let es6File = Fs.readFileSync(`${RootPath}/build/media/webcomponents/js/${element}/${element}.js`, 'utf8');
// Check if there is a css file
if (Fs.existsSync(`${RootPath}/build/media/webcomponents/scss/${element}/${element}.scss`)) {
if (!Fs.existsSync(`${RootPath}/build/media/webcomponents/scss/${element}/${element}.scss`)) {
return;
}
Sass.render({
file: `${RootPath}/build/media/webcomponents/scss/${element}/${element}.scss`,
}, (error, result) => {
if (error) {
// eslint-disable-next-line no-console
console.error(`${error.column}`);
// eslint-disable-next-line no-console
console.error(`${error.message}`);
// eslint-disable-next-line no-console
console.error(`${error.line}`);
} else {
// Auto prefixing
// eslint-disable-next-line no-console
console.log(`Creating /media/system/webcomponents/css/joomla-${element}`);
console.log(`Prefixing for: ${options.settings.browsers}`);
const cleaner = Postcss(
[
Autoprefixer({
env: {
targets: {
browsers: [options.settings.browsers]
},
}
}),
],
);
if (typeof result === 'object' && result.css) {
cleaner.process(result.css.toString(), {from: undefined})
.then((res) => {
if (/{{CSS_CONTENTS_PLACEHOLDER}}/.test(es6File)) {
if (typeof res === 'object' && res.css) {
Postcss([CssNano]).process(res.css.toString(), {from: undefined}).then(cssMin => {
es6File = es6File.replace('{{CSS_CONTENTS_PLACEHOLDER}}', cssMin.css.toString());
createJsFiles(element, es6File);
});
}
} else {
if (typeof res === 'object' && res.css) {
Fs.writeFileSync(
`${RootPath}/media/system/webcomponents/css/joomla-${element}.css`,
res.css.toString(),
{ encoding: 'UTF-8' },
);
Postcss([CssNano]).process(res.css.toString(), {from: undefined}).then(cssMin => {
Fs.writeFileSync(
`${RootPath}/media/system/webcomponents/css/joomla-${element}.min.css`,
cssMin.css.toString(),
{ encoding: 'UTF-8' },
);
});
}
createJsFiles(element, es6File);
}
})
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`${err}`);
process.exit(-1);
});
return ;
// eslint-disable-next-line no-console
console.log(`joomla-${element} was updated.`);
}
}
});
} else {
createJsFiles(element, es6File);
}
});
};
const compileCEjs = (options, path) => {
Promise.resolve()
.then(() => compile(options, path))
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`${err}`);
process.exit(-1);
});
};
module.exports.compile = compileCEjs;

View File

@ -1,47 +1,48 @@
const Debounce = require('lodash.debounce');
const Fs = require('fs');
const Promise = require('bluebird');
const fs = require('fs');
// const fsExtra = require('fs-extra');
const Recurs = require('recursive-readdir');
const RootPath = require('./rootpath.js')._();
const TranspileJs = require('./compile-es6.js');
const UglifyJS = require('uglify-es');
const transpileEs5 = require('./compile-es6.js');
const debounce = require('lodash.debounce');
const rootPath = require('./rootpath.js')._();
const watches = [
`${rootPath}/media`,
`${rootPath}/administrator/templates/atum/js`,
`${rootPath}/templates/cassiopeia/js`,
`${RootPath}/media`,
`${RootPath}/administrator/templates/atum/js`,
`${RootPath}/templates/cassiopeia/js`,
];
const uglifyJs = (options, path) => {
let folders = [];
if (path) {
const stats = fs.lstatSync(`${rootPath}/${path}`);
const stats = Fs.lstatSync(`${RootPath}/${path}`);
if (!stats.isDirectory()) {
// @todo: allow to compile single file
throw new Error(`Path should be a directory: ${path}`);
}
folders.push(`${rootPath}/${path}`);
folders.push(`${RootPath}/${path}`);
} else {
folders = [
`${rootPath}/build/media_src`,
`${rootPath}/administrator/templates/atum/js`,
`${rootPath}/templates/cassiopeia/js`,
`${RootPath}/build/media_src`,
`${RootPath}/administrator/templates/atum/js`,
`${RootPath}/templates/cassiopeia/js`,
];
}
// Loop to get some text for the packgage.json
folders.forEach((folder) => {
Recurs(folder, ['*.min.js', '*.map', '*.css', '*.svg', '*.png', '*.swf']).then(
Recurs(folder, ['*.min.js', '*.map', '*.scss', '*.css', '*.svg', '*.png', '*.swf', '*.json']).then(
(files) => {
files.forEach(
(file) => {
if (file.match(/\.es6\.js/)) {
// Transpile the file
transpileEs5.compileFile(file);
}
if (file.match(/\.es6\.js/)) {
// Transpile the file
TranspileJs.compileFile(file);
} else {
Fs.writeFileSync(file.replace('.js', '.min.js'), UglifyJS.minify(Fs.readFileSync(file, 'utf8')).code, { encoding: 'utf8' });
}
},
(error) => {
// eslint-disable-next-line no-console
@ -61,21 +62,21 @@ const watchFiles = (options, folders, compileFirst = false) => {
folderz.forEach(
(folder) => {
Recurs(folder, ['*.min.js', '*.map', '*.css', '*.svg', '*.png', '*.swf']).then(
Recurs(folder, ['*.min.js', '*.map', '*.css', 'scss', '*.svg', '*.png', '*.swf', '*.json']).then(
(files) => {
files.forEach(
(file) => {
if (file.match(/\.js/)) {
fs.watchFile(file, () => {
Fs.watchFile(file, () => {
// eslint-disable-next-line no-console
console.warn(`File: ${file} changed.`);
debounce(() => {
Debounce(() => {
if (file.match(/\.es6\.js/)) {
// Transpile the file
transpileEs5.compileFile(file);
fs.writeFileSync(file.replace('.es6.js', '.min.js'), UglifyJS.minify(fs.readFileSync(file, 'utf8')).code, { encoding: 'utf8' });
TranspileJs.compileFile(file);
} else {
Fs.writeFileSync(file.replace('.js', '.min.js'), UglifyJS.minify(Fs.readFileSync(file, 'utf8')).code, { encoding: 'utf8' });
}
fs.writeFileSync(file.replace('.js', '.min.js'), UglifyJS.minify(fs.readFileSync(file, 'utf8')).code, { encoding: 'utf8' });
}, 150)();
// eslint-disable-next-line no-console
@ -84,8 +85,9 @@ const watchFiles = (options, folders, compileFirst = false) => {
}
},
(error) => {
// eslint-disable-next-line no-console
console.error(`something exploded ${error}`);
// eslint-disable-next-line no-console
console.error(`${error}`);
process.exit(1);
},
);
}
@ -99,14 +101,12 @@ const watchFiles = (options, folders, compileFirst = false) => {
const compileJS = (options, path) => {
Promise.resolve()
// Compile the scss files
// Compile the scss files
.then(() => uglifyJs(options, path))
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err);
process.exit(-1);
// Handle errors
.catch((error) => {
throw new Error(`${error}`);
});
};

View File

@ -1,136 +1,154 @@
const Promise = require('bluebird');
const fs = require('fs');
const Autoprefixer = require('autoprefixer');
const CssNano = require('cssnano');
const Debounce = require('lodash.debounce');
const Fs = require('fs');
const MakeDir = require('./make-dir.js');
const Path = require('path');
const Postcss = require('postcss');
const Promise = require('bluebird');
const Recurs = require('recursive-readdir');
const RootPath = require('./rootpath.js')._();
const Sass = require('node-sass');
const UglyCss = require('uglifycss');
const autoprefixer = require('autoprefixer');
const postcss = require('postcss');
const debounce = require('lodash.debounce');
const rootPath = require('./rootpath.js')._();
/**
* A collection of folders to be watched
* @type {string[]}
*/
const watches = [
`${rootPath}/templates/cassiopeia/scss`,
`${rootPath}/administrator/templates/atum/scss`,
`${rootPath}/media/plg_installer_webinstaller/scss`,
`${rootPath}/build/media_src`,
`${rootPath}/installation/template/scss/template.scss`,
`${rootPath}/installation/template/scss/template-rtl.scss`,
`${RootPath}/templates/cassiopeia/scss`,
`${RootPath}/administrator/templates/atum/scss`,
`${RootPath}/build/media_src`,
`${RootPath}/installation/template/scss/template.scss`,
`${RootPath}/installation/template/scss/template-rtl.scss`,
];
const compileCSSFiles = (options, path) => {
let files = [];
let folders = [];
const compile = (file, options) => {
const cssFile = file.replace('/scss/', '/css/').replace('.scss', '.css').replace('/build/media_src/', '/media/');
if (path) {
const stats = fs.lstatSync(`${rootPath}/${path}`);
if (stats.isDirectory()) {
folders.push(`${rootPath}/${path}`);
} else if (stats.isFile()) {
files.push(`${rootPath}/${path}`);
Sass.render({
file,
}, (error, result) => {
if (error) {
// eslint-disable-next-line no-console
console.error(`something exploded ${error.column}`, error.message, error.line);
process.exit(1);
} else {
throw new Error(`Unknown path ${path}`);
}
} else {
files = [
`${rootPath}/templates/cassiopeia/scss/offline.scss`,
`${rootPath}/templates/cassiopeia/scss/template.scss`,
`${rootPath}/templates/cassiopeia/scss/template-rtl.scss`,
`${rootPath}/administrator/templates/atum/scss/bootstrap.scss`,
`${rootPath}/administrator/templates/atum/scss/font-awesome.scss`,
`${rootPath}/administrator/templates/atum/scss/template.scss`,
`${rootPath}/administrator/templates/atum/scss/template-rtl.scss`,
`${rootPath}/build/media_src/plg_installer_webinstaller/scss/client.scss`,
`${rootPath}/installation/template/scss/template.scss`,
`${rootPath}/installation/template/scss/template-rtl.scss`,
];
// Auto prefixing
// eslint-disable-next-line no-console
console.log(`Prefixing for: ${options.settings.browsers}`);
folders = [
`${rootPath}/build/media_src`,
];
}
const cleaner = Postcss(
[
Autoprefixer({
browsers: options.settings.browsers,
}),
],
);
// Loop to get the files that should be compiled via parameter
folders.forEach((folder) => {
let filesTocompile = fs.readdirSync(folder);
filesTocompile.forEach((fileTocompile) => {
if (Path.extname(fileTocompile) === ".scss" && fileTocompile.charAt(0) !== '_') {
files.push(folder + '/' + fileTocompile);
}
});
});
cleaner.process(result.css.toString(), {from: undefined})
.then((res) => {
// Ensure the folder exists or create it
MakeDir.run(Path.dirname(cssFile));
// Loop to get some text for the packgage.json
files.forEach((file) => {
const cssFile = file.replace('/scss/', '/css/').replace('.scss', '.css').replace('/build/media_src/', '/media/');
Fs.writeFileSync(
cssFile,
res.css.toString(),
{ encoding: 'UTF-8' },
);
Sass.render({
file,
}, (error, result) => {
if (error) {
// eslint-disable-next-line no-console
console.error(`something exploded ${error.column}`);
// eslint-disable-next-line no-console
console.error(`something exploded ${error.message}`);
// eslint-disable-next-line no-console
console.error(`something exploded ${error.line}`);
} else {
// Auto prefixing
// eslint-disable-next-line no-console
console.log(`Prefixing for: ${options.settings.browsers}`);
const cleaner = postcss(
[
autoprefixer({
add: false,
browsers: options.settings.browsers,
}),
],
);
const prefixer = postcss([autoprefixer]);
cleaner.process(result.css.toString(), {from: undefined})
.then(cleaned => prefixer.process(cleaned.css, {from: undefined}))
.then((res) => {
Postcss([CssNano]).process(res.css.toString(), {from: undefined}).then(cssMin => {
// Ensure the folder exists or create it
const currentDir = Path.dirname(cssFile);
try{
fs.lstatSync(currentDir).isDirectory()
}catch(e){
if(e.code === 'ENOENT'){
// Directory needs to be created
fs.mkdirSync(currentDir);
}
}
fs.writeFileSync(
cssFile,
res.css.toString(),
{ encoding: 'UTF-8' },
);
})
.then(() => {
// Uglify it now
fs.writeFileSync(
MakeDir.run(Path.dirname(cssFile.replace('.css', '.min.css')));
Fs.writeFileSync(
cssFile.replace('.css', '.min.css'),
UglyCss.processFiles([cssFile], { expandVars: false }),
cssMin.css.toString(),
{ encoding: 'UTF-8' },
);
// eslint-disable-next-line no-console
console.log(`File: ${cssFile.replace(/.+\//, '')} was updated. `);
});
}
});
});
}
});
};
/**
*
* @param {object} options the options
* @param {string} path the folder that needs to be compiled, optional
*/
const compileCSSFiles = (options, path) => {
let files = [];
let folders = [];
if (path) {
const stats = Fs.lstatSync(`${RootPath}/${path}`);
if (stats.isDirectory()) {
folders.push(`${RootPath}/${path}`);
} else if (stats.isFile()) {
files.push(`${RootPath}/${path}`);
} else {
// eslint-disable-next-line no-console
console.error(`Unknown path ${path}`);
process.exit(1);
}
} else {
files = [
`${RootPath}/templates/cassiopeia/scss/offline.scss`,
`${RootPath}/templates/cassiopeia/scss/template.scss`,
`${RootPath}/templates/cassiopeia/scss/template-rtl.scss`,
`${RootPath}/administrator/templates/atum/scss/bootstrap.scss`,
`${RootPath}/administrator/templates/atum/scss/font-awesome.scss`,
`${RootPath}/administrator/templates/atum/scss/template.scss`,
`${RootPath}/administrator/templates/atum/scss/template-rtl.scss`,
`${RootPath}/installation/template/scss/template.scss`,
`${RootPath}/installation/template/scss/template-rtl.scss`,
];
folders = [
`${RootPath}/build/media_src`,
];
}
// Loop to get the files that should be compiled via parameter
folders.forEach((folder) => {
Recurs(folder, ['*.js', '*.map', '*.css', '*.svg', '*.png', '*.swf', '*.json']).then(
(filesRc) => {
filesRc.forEach(
(filez) => {
if (filez.match(/\.scss/) && filez.charAt(0) !== '_') {
files.push(filez);
}
},
(error) => {
// eslint-disable-next-line no-console
console.error(`something exploded ${error}`);
},
);
files.forEach((file) => {
compile(file, options);
});
});
});
// Loop to get some text for the packgage.json
};
/**
* The watch method
* @param {object} options the options
* @param {array} folders an array of folders to be watched
* @param {boolean} compileFirst
*/
const watchFiles = (options, folders, compileFirst = false) => {
const folderz = folders || watches;
if (compileFirst) {
compileFiles(options);
compileCSSFiles(options, '');
}
folderz.forEach((folder) => {
@ -138,10 +156,10 @@ const watchFiles = (options, folders, compileFirst = false) => {
(files) => {
files.forEach((file) => {
if (file.match(/\.scss/)) {
fs.watchFile(file, () => {
Fs.watchFile(file, () => {
// eslint-disable-next-line no-console
console.log(`File: ${file} changed.`);
debounce(() => compileFiles(options), 150)();
Debounce(() => compileCSSFiles(options, ''), 150)();
});
}
},
@ -159,14 +177,14 @@ const watchFiles = (options, folders, compileFirst = false) => {
const compileCSS = (options, path) => {
Promise.resolve()
// Compile the scss files
// Compile the scss files
.then(() => compileCSSFiles(options, path))
// Handle errors
.catch((err) => {
.catch((error) => {
// eslint-disable-next-line no-console
console.error(err);
process.exit(-1);
console.error(`${error}`);
process.exit(1);
});
};

View File

@ -0,0 +1,38 @@
/**
* Helper fn creates dir
*
* @param targetDir
* @param isRelativeToScript
* @returns {string}
*/
const Fs = require('fs');
const Path = require('path');
module.exports.run = (targetDir, { isRelativeToScript = false } = {}) => {
const sep = Path.sep;
const initDir = Path.isAbsolute(targetDir) ? sep : '';
const baseDir = isRelativeToScript ? __dirname : '.';
return targetDir.split(sep).reduce((parentDir, childDir) => {
const curDir = Path.resolve(baseDir, parentDir, childDir);
try {
Fs.mkdirSync(curDir);
} catch (err) {
if (err.code === 'EEXIST') { // curDir already exists!
return curDir;
}
// To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
if (err.code === 'ENOENT') { // Throw the original parentDir error on curDir `ENOENT` failure.
throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`);
}
const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1;
if (!caughtErr || caughtErr && curDir === Path.resolve(targetDir)) {
throw new Error(`${err}`);
}
}
return curDir;
}, initDir);
};

View File

@ -1,38 +1,23 @@
const Fs = require('fs');
const Path = require('path');
const RootPath = require('./rootpath.js')._();
const UglifyJS = require('uglify-es');
const path = require('path');
const fs = require('fs');
const rootPath = require('./rootpath.js')._();
// List all files in a directory in Node.js recursively in a synchronous fashion
const walkSync = function(dir, filelist) {
const files = fs.readdirSync(dir);
filelist = filelist || [];
files.forEach(function(file) {
if (fs.statSync(path.join(dir, file)).isDirectory()) {
filelist = walkSync(path.join(dir, file), filelist);
}
else {
filelist.push(path.join(dir, file));
}
});
return filelist;
};
const WalkSync = require('./walk-sync.js');
const fixVendors = () => {
Promise.resolve()
.then(() => {
const folders = [
path.join(rootPath, 'media/vendor/codemirror'),
path.join(rootPath, 'media/vendor/jquery-ui/js'),
path.join(rootPath, 'media/vendor/punycode/js'),
path.join(rootPath, 'media/vendor/tinymce/langs'),
path.join(rootPath, 'media/vendor/webcomponentsjs'),
Path.join(RootPath, 'media/vendor/codemirror'),
Path.join(RootPath, 'media/vendor/jquery-ui/js'),
Path.join(RootPath, 'media/vendor/punycode/js'),
Path.join(RootPath, 'media/vendor/tinymce/langs'),
Path.join(RootPath, 'media/vendor/webcomponentsjs'),
];
// Loop to get some text for the packgage.json
folders.forEach((folder) => {
const files = walkSync(folder);
const files = WalkSync.run(folder, []);
if (files.length) {
files.forEach(
@ -40,7 +25,7 @@ const fixVendors = () => {
if (file.match(/\.js/) && !file.match(/LICENSE\.md/)) {
console.log(`Processing: ${file}`);
// Write the file
fs.writeFileSync(file.replace('.js', '.min.js'), UglifyJS.minify(fs.readFileSync(file, 'utf8')).code, {encoding: 'utf8'});
Fs.writeFileSync(file.replace('.js', '.min.js'), UglifyJS.minify(Fs.readFileSync(file, 'utf8')).code, {encoding: 'utf8'});
}
});
}
@ -48,10 +33,10 @@ const fixVendors = () => {
})
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`${err}`);
process.exit(-1);
.catch((error) => {
// eslint-disable-next-line no-console
console.error(`${error}`);
process.exit(1);
});
};

View File

@ -1,4 +1,8 @@
// Root Path
/**
* Method to get the root path
*
* @returns {string} The root path
*/
const rootPath = () => __dirname.replace('/build/build-modules-js', '').replace('\\build\\build-modules-js', '');
module.exports._ = rootPath;

View File

@ -1,53 +1,75 @@
const Promise = require('bluebird');
const fs = require('fs');
const fsExtra = require('fs-extra');
const Copydir = require('copy-dir');
const Fs = require('fs');
const FsExtra = require('fs-extra');
const Path = require('path');
const copydir = require('copy-dir');
const UglifyJS = require('uglify-es');
const Promise = require('bluebird');
const RootPath = require('./rootpath.js')._();
const UglyCss = require('uglifycss');
const rootPath = require('./rootpath.js')._();
const UglifyJS = require('uglify-es');
const WalkSync = require('./walk-sync.js');
const xmlVersionStr = /(<version>)(\d+.\d+.\d+)(<\/version>)/;
// rm -rf media/vendor
/**
* Clean the media/vendor folder
*/
const cleanVendors = () => {
// Remove the vendor folder
fsExtra.removeSync(Path.join(rootPath, 'media/vendor'));
FsExtra.removeSync(Path.join(RootPath, 'media/vendor'));
// eslint-disable-next-line no-console
console.error('/media/vendor has been removed.');
// Restore our code on the vendor folders
fsExtra.copySync(Path.join(rootPath, 'build/media/vendor/tinymce/langs'), Path.join(rootPath, 'media/vendor/tinymce/langs'));
fsExtra.copySync(Path.join(rootPath, 'build/media/vendor/tinymce/templates'), Path.join(rootPath, 'media/vendor/tinymce/templates'));
fsExtra.copySync(Path.join(rootPath, 'build/media/vendor/jquery-ui'), Path.join(rootPath, 'media/vendor/jquery-ui'));
FsExtra.copySync(Path.join(RootPath, 'build/media/vendor/tinymce/langs'), Path.join(RootPath, 'media/vendor/tinymce/langs'));
FsExtra.copySync(Path.join(RootPath, 'build/media/vendor/tinymce/templates'), Path.join(RootPath, 'media/vendor/tinymce/templates'));
FsExtra.copySync(Path.join(RootPath, 'build/media/vendor/jquery-ui'), Path.join(RootPath, 'media/vendor/jquery-ui'));
// And here some assets from a PHP package
// @todo Move it the 'right way' (tm)
fsExtra.copySync(Path.join(rootPath, 'libraries/vendor/maximebf/debugbar/src/DebugBar/Resources'), Path.join(rootPath, 'media/vendor/debugbar'));
if (Fs.existsSync(Path.join(RootPath, 'libraries/vendor/maximebf/debugbar/src/DebugBar/Resources'))) {
FsExtra.copySync(Path.join(RootPath, 'libraries/vendor/maximebf/debugbar/src/DebugBar/Resources'), Path.join(RootPath, 'media/vendor/debugbar'));
} else {
// eslint-disable-next-line no-console
console.error('You need to run `npm install` AFTER the command `composer install`!!!. The debug plugin HASN\'T install all its front end assets');
process.exit(1);
}
};
// Copies all the files from a directory
/**
* Copies all the files from a directory
*
* @param {string} dirName the name of the source folder
* @param {string} name the name of the destination folder
* @param {string} type the type of the folder, eg: js, css, fonts, images
*/
const copyAll = (dirName, name, type) => {
const folderName = dirName === '/' ? '/' : `/${dirName}`;
fsExtra.copySync(Path.join(rootPath, `node_modules/${name}/${folderName}`),
Path.join(rootPath, `media/vendor/${name.replace(/.+\//, '')}/${type}`));
FsExtra.copySync(Path.join(RootPath, `node_modules/${name}/${folderName}`),
Path.join(RootPath, `media/vendor/${name.replace(/.+\//, '')}/${type}`));
};
// Copies an array of files from a directory
/**
* Copies an array of files from a directory
*
* @param {string} dirName the name of the source folder
* @param {array} files the array of files to be be copied
* @param {string} name the name of the destination folder
* @param {string} type the type of the folder, eg: js, css, fonts, images
*/
const copyArrayFiles = (dirName, files, name, type) => {
files.forEach((file) => {
const folderName = dirName === '/' ? '/' : `/${dirName}/`;
if (fsExtra.existsSync(`node_modules/${name}${folderName}${file}`)) {
fsExtra.copySync(`node_modules/${name}${folderName}${file}`, `media/vendor/${name.replace(/.+\//, '')}${type ? `/${type}` : ''}/${file}`);
if (FsExtra.existsSync(`node_modules/${name}${folderName}${file}`)) {
FsExtra.copySync(`node_modules/${name}${folderName}${file}`, `media/vendor/${name.replace(/.+\//, '')}${type ? `/${type}` : ''}/${file}`);
}
});
};
/**
*
* @param files Object of files map, eg {"src.js": "js/src.js"}
* @param srcDir Package root dir
* @param destDir Vendor destination dir
* @param {object} files the object of files map, eg {"src.js": "js/src.js"}
* @param {string} srcDir the name of the package root dir
* @param {string} destDir the name of the Vendor destination dir
*
* @returns {Array}
*/
@ -59,30 +81,39 @@ const copyFilesTo = (files, srcDir, destDir) => {
for (const srcFile in files) {
const destFile = files[srcFile];
const srcPath = Path.join(srcDir, srcFile);
// stats = fs.lstatSync(srcPath),
const destPath = Path.join(destDir, destFile);
fsExtra.copySync(srcPath, destPath);
FsExtra.copySync(srcPath, destPath);
filesResult.push(destPath);
}
return filesResult;
};
// Concatenate some files
/**
* Method to concatenate some files
*
* @param {array} files the array of files to be be concatenated
* @param {string} output the name of the output file
*/
const concatFiles = (files, output) => {
let tempMem = '';
files.forEach((file) => {
if (fsExtra.existsSync(`${rootPath}/${file}`)) {
tempMem += fs.readFileSync(`${rootPath}/${file}`);
if (FsExtra.existsSync(`${RootPath}/${file}`)) {
tempMem += Fs.readFileSync(`${RootPath}/${file}`);
}
});
fs.writeFileSync(`${rootPath}/${output}`, tempMem);
Fs.writeFileSync(`${RootPath}/${output}`, tempMem);
};
/**
* Main method that will copy all vendor files according to Joomla's specs
*
* @param options
*/
const copyFiles = (options) => {
const mediaVendorPath = Path.join(rootPath, 'media/vendor');
const mediaVendorPath = Path.join(RootPath, 'media/vendor');
const registry = {
name: options.name,
version: options.version,
@ -91,8 +122,8 @@ const copyFiles = (options) => {
assets: {},
};
if (!fsExtra.existsSync(mediaVendorPath)) {
fsExtra.mkdirSync(mediaVendorPath);
if (!FsExtra.existsSync(mediaVendorPath)) {
FsExtra.mkdirSync(mediaVendorPath);
}
// Loop to get some text for the packgage.json
@ -106,14 +137,14 @@ const copyFiles = (options) => {
const moduleOptions = require(modulePathJson);
if (packageName === 'codemirror') {
const itemvendorPath = Path.join(rootPath, `media/vendor/${packageName}`);
if (!fsExtra.existsSync(itemvendorPath)) {
fsExtra.mkdirSync(itemvendorPath);
fsExtra.mkdirSync(Path.join(itemvendorPath, 'addon'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'lib'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'mode'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'keymap'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'theme'));
const itemvendorPath = Path.join(RootPath, `media/vendor/${packageName}`);
if (!FsExtra.existsSync(itemvendorPath)) {
FsExtra.mkdirSync(itemvendorPath);
FsExtra.mkdirSync(Path.join(itemvendorPath, 'addon'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'lib'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'mode'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'keymap'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'theme'));
}
copyAll('addon', 'codemirror', 'addon');
@ -155,19 +186,19 @@ const copyFiles = (options) => {
], 'media/vendor/codemirror/lib/addons.css');
// Update the XML file for Codemirror
let codemirrorXml = fs.readFileSync(`${rootPath}/plugins/editors/codemirror/codemirror.xml`, { encoding: 'UTF-8' });
let codemirrorXml = Fs.readFileSync(`${RootPath}/plugins/editors/codemirror/codemirror.xml`, { encoding: 'UTF-8' });
codemirrorXml = codemirrorXml.replace(xmlVersionStr, `$1${options.dependencies.codemirror}$3`);
fs.writeFileSync(`${rootPath}/plugins/editors/codemirror/codemirror.xml`, codemirrorXml, { encoding: 'UTF-8' });
Fs.writeFileSync(`${RootPath}/plugins/editors/codemirror/codemirror.xml`, codemirrorXml, { encoding: 'UTF-8' });
} else if (packageName === 'tinymce') {
const itemvendorPath = Path.join(rootPath, `media/vendor/${packageName}`);
const itemvendorPath = Path.join(RootPath, `media/vendor/${packageName}`);
if (!fsExtra.existsSync(itemvendorPath)) {
fsExtra.mkdirSync(itemvendorPath);
fsExtra.mkdirSync(Path.join(itemvendorPath, 'plugins'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'langs'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'skins'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'themes'));
fsExtra.mkdirSync(Path.join(itemvendorPath, 'templates'));
if (!FsExtra.existsSync(itemvendorPath)) {
FsExtra.mkdirSync(itemvendorPath);
FsExtra.mkdirSync(Path.join(itemvendorPath, 'plugins'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'langs'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'skins'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'themes'));
FsExtra.mkdirSync(Path.join(itemvendorPath, 'templates'));
}
copyAll('plugins', 'tinymce', 'plugins');
@ -177,14 +208,14 @@ const copyFiles = (options) => {
copyArrayFiles('', ['tinymce.js', 'tinymce.min.js', 'changelog.txt', 'license.txt'], 'tinymce', '');
// Update the XML file for tinyMCE
let tinyXml = fs.readFileSync(`${rootPath}/plugins/editors/tinymce/tinymce.xml`, { encoding: 'UTF-8' });
let tinyXml = Fs.readFileSync(`${RootPath}/plugins/editors/tinymce/tinymce.xml`, { encoding: 'UTF-8' });
tinyXml = tinyXml.replace(xmlVersionStr, `$1${options.dependencies.tinymce}$3`);
fs.writeFileSync(`${rootPath}/plugins/editors/tinymce/tinymce.xml`, tinyXml, { encoding: 'UTF-8' });
Fs.writeFileSync(`${RootPath}/plugins/editors/tinymce/tinymce.xml`, tinyXml, { encoding: 'UTF-8' });
// Remove that sourcemap...
let tinyWrongMap = fs.readFileSync(`${rootPath}/media/vendor/tinymce/skins/lightgray/skin.min.css`, { encoding: 'UTF-8' });
let tinyWrongMap = Fs.readFileSync(`${RootPath}/media/vendor/tinymce/skins/lightgray/skin.min.css`, { encoding: 'UTF-8' });
tinyWrongMap = tinyWrongMap.replace('/*# sourceMappingURL=skin.min.css.map */', '');
fs.writeFileSync(`${rootPath}/media/vendor/tinymce/skins/lightgray/skin.min.css`, tinyWrongMap, { encoding: 'UTF-8' });
Fs.writeFileSync(`${RootPath}/media/vendor/tinymce/skins/lightgray/skin.min.css`, tinyWrongMap, { encoding: 'UTF-8' });
} else {
['js', 'css', 'filesExtra'].forEach((type) => {
if (!vendor[type]) return;
@ -195,10 +226,10 @@ const copyFiles = (options) => {
// Copy the license if exists
if (options.settings.vendors[packageName].licenseFilename &&
fs.existsSync(`${Path.join(rootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`)
Fs.existsSync(`${Path.join(RootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`)
) {
const dest = Path.join(mediaVendorPath, vendorName);
fsExtra.copySync(`${Path.join(rootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`, `${dest}/${options.settings.vendors[packageName].licenseFilename}`);
FsExtra.copySync(`${Path.join(RootPath, `node_modules/${packageName}`)}/${options.settings.vendors[packageName].licenseFilename}`, `${dest}/${options.settings.vendors[packageName].licenseFilename}`);
}
}
@ -207,11 +238,11 @@ const copyFiles = (options) => {
if (packageName === 'chosen-js') {
const dest = Path.join(mediaVendorPath, vendorName);
const chosenPath = `${dest}/${options.settings.vendors[packageName].js['chosen.jquery.js']}`;
let ChosenJs = fs.readFileSync(chosenPath, { encoding: 'UTF-8' });
let ChosenJs = Fs.readFileSync(chosenPath, { encoding: 'UTF-8' });
ChosenJs = ChosenJs.replace('}).call(this);', ' document.AbstractChosen = AbstractChosen;\n' +
' document.Chosen = Chosen;\n' +
'}).call(this);');
fs.writeFileSync(chosenPath, ChosenJs, { encoding: 'UTF-8' });
Fs.writeFileSync(chosenPath, ChosenJs, { encoding: 'UTF-8' });
}
// Add provided Assets to a registry, if any
@ -267,18 +298,21 @@ const copyFiles = (options) => {
}
// Write assets registry
fs.writeFileSync(
Fs.writeFileSync(
Path.join(mediaVendorPath, 'joomla.asset.json'),
JSON.stringify(registry, null, 2),
{encoding: 'UTF-8'}
);
};
/**
* Method to recreate the basic media folder structure
*/
const recreateMediaFolder = () => {
// eslint-disable-next-line no-console
console.log(`Recreating the media folder...`);
copydir.sync(Path.join(rootPath, 'build/media'), Path.join(rootPath, 'media'), function(stat, filepath, filename){
Copydir.sync(Path.join(RootPath, 'build/media'), Path.join(RootPath, 'media'), function(stat, filepath, filename){
if (stat === 'directory' && (filename === 'webcomponents' || filename === 'scss')) {
return false;
}
@ -289,7 +323,7 @@ const recreateMediaFolder = () => {
}
});
copydir.sync(Path.join(rootPath, 'build/media_src'), Path.join(rootPath, 'media'), function(stat, filepath, filename){
Copydir.sync(Path.join(RootPath, 'build/media_src'), Path.join(RootPath, 'media'), function(stat, filepath, filename){
if (stat === 'directory' && filename === 'scss') {
return false;
}
@ -301,25 +335,13 @@ const recreateMediaFolder = () => {
});
};
// List all files in a directory recursively in a synchronous fashion
const walkSync = function(dir, filelist) {
const files = fs.readdirSync(dir);
filelist = filelist || [];
files.forEach(function(file) {
if (fs.statSync(Path.join(dir, file)).isDirectory()) {
filelist = walkSync(Path.join(dir, file), filelist);
}
else {
filelist.push(Path.join(dir, file));
}
});
return filelist;
};
/**
* Method to minify the legacy ES5 files
*/
const uglifyLegacyFiles = () => {
// Minify the legacy files
console.log('Minifying legacy stylesheets/scripts...');
const files = walkSync(`${rootPath}/media`);
const files = WalkSync.run(`${RootPath}/media`, []);
if (files.length) {
files.forEach(
@ -330,12 +352,12 @@ const uglifyLegacyFiles = () => {
if (file.match(/\.js/) && !file.match(/\.min\.js/) && !file.toLowerCase().match(/license/) && !file.toLowerCase().match(/json/) ) {
console.log(`Processing: ${file}`);
// Create the minified file
fs.writeFileSync(file.replace(/\.js$/, '.min.js'), UglifyJS.minify(fs.readFileSync(file, 'utf8')).code, {encoding: 'utf8'});
Fs.writeFileSync(file.replace(/\.js$/, '.min.js'), UglifyJS.minify(Fs.readFileSync(file, 'utf8')).code, {encoding: 'utf8'});
}
if (file.match(/\.css/) && !file.match(/\.min\.css/) && !file.match(/\.css\.map/) && !file.toLowerCase().match(/license/)) {
console.log(`Processing: ${file}`);
// Create the minified file
fs.writeFileSync(
Fs.writeFileSync(
file.replace(/\.css$/, '.min.css'),
UglyCss.processFiles([file], { expandVars: false }),
{ encoding: 'utf8' },
@ -360,10 +382,10 @@ const copyAssets = (options) => {
.then(uglifyLegacyFiles(options))
// Handle errors
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err);
process.exit(-1);
.catch((error) => {
// eslint-disable-next-line no-console
console.error(`${error}`);
process.exit(1);
});
};

View File

@ -0,0 +1,30 @@
const Fs = require('fs');
const Path = require('path');
/**
* Method to list all files in a directory recursively in a synchronous fashion
*
* @param {string} dir the name of the folder to be recurse'd
* @param {array} filelist the array with all the files
*/
const walkSync = (dir, filelist) => {
if (!Array.isArray(filelist)) {
console.log('Method `walkSync` expects second parameter to be an array!');
process.env.exit(1)
}
const files = Fs.readdirSync(dir);
filelist = filelist || [];
files.forEach((file) => {
if (Fs.statSync(Path.join(dir, file)).isDirectory()) {
filelist = walkSync(Path.join(dir, file), filelist);
}
else {
filelist.push(Path.join(dir, file));
}
});
return filelist;
};
module.exports.run = walkSync;

View File

@ -24,4 +24,3 @@
document.addEventListener('DOMContentLoaded', onBoot);
})(document);

View File

@ -12,8 +12,8 @@
let batchSelector;
const onChange = () => {
if (!batchSelector.value ||
(batchSelector.value && parseInt(batchSelector.value, 10) === 0)) {
if (!batchSelector.value
|| (batchSelector.value && parseInt(batchSelector.value, 10) === 0)) {
batchCopyMove.style.display = 'none';
} else {
batchCopyMove.style.display = 'block';

View File

@ -7,13 +7,13 @@
// Extension variables
$extension-types: (
"jcommercial": #f6c801,
"jcomponent": #1e9e33,
"jlanguage": $dark,
"jmodule": #e20a0a,
"jplugin": #57278e,
"jspecific": #d69b34,
"jtool": #333
"jcommercial": #f6c801,
"jcomponent": #1e9e33,
"jlanguage": $dark,
"jmodule": #e20a0a,
"jplugin": #57278e,
"jspecific": #d69b34,
"jtool": #333
);
.com-apps-container {

View File

@ -31,13 +31,13 @@
})();
// Only define the Joomla namespace if not defined.
Joomla = window.Joomla || {};
window.Joomla = window.Joomla || {};
// Only define editors if not defined
Joomla.editors = Joomla.editors || {};
window.Joomla.editors = window.Joomla.editors || {};
// An object to hold each editor instance on page, only define if not defined.
Joomla.editors.instances = Joomla.editors.instances || {
window.Joomla.editors.instances = window.Joomla.editors.instances || {
/**
* *****************************************************************
* All Editors MUST register, per instance, the following callbacks:
@ -74,7 +74,7 @@ Joomla.editors.instances = Joomla.editors.instances || {
};
Joomla.Modal = {
window.Joomla.Modal = window.Joomla.Modal || {
/**
* *****************************************************************
* Modals should implement
@ -100,9 +100,9 @@ Joomla.Modal = {
*/
current: '',
setCurrent: (element) => {
this.current = element;
window.Joomla.current = element;
},
getCurrent: () => this.current,
getCurrent: () => window.Joomla.current,
};
((Joomla, document) => {
@ -1064,8 +1064,8 @@ Joomla.Modal = {
// Feature detect which polyfill needs to be imported.
let polyfills = [];
if (!('attachShadow' in Element.prototype && 'getRootNode' in Element.prototype) ||
(window.ShadyDOM && window.ShadyDOM.force)) {
if (!('attachShadow' in Element.prototype && 'getRootNode' in Element.prototype)
|| (window.ShadyDOM && window.ShadyDOM.force)) {
polyfills.push('sd');
}
if (!window.customElements || window.customElements.forcePolyfill) {
@ -1087,8 +1087,8 @@ Joomla.Modal = {
t2.content.appendChild(document.createElement('div'));
t.content.appendChild(t2);
const clone = t.cloneNode(true);
return (clone.content.childNodes.length === 0 ||
clone.content.firstChild.content.childNodes.length === 0);
return (clone.content.childNodes.length === 0
|| clone.content.firstChild.content.childNodes.length === 0);
})();
// NOTE: any browser that does not have template or ES6 features

View File

@ -181,7 +181,6 @@
document.body.addEventListener('click', (event) => {
if (document.body.classList.contains('filters-shown')) {
// Ignore click inside the filter container
if (event.composedPath && typeof event.composedPath === 'function') {
// Browser that support composedPath()

View File

@ -8,8 +8,8 @@ var errorLocale = window.errorLocale || null;
// Create links for all the languages
Object.keys(errorLocale).forEach(function(key) {
var sel = document.getElementById('translatedLanguagesSelect');
var opt = document.createElement('option');
var sel = document.getElementById('translatedLanguagesSelect'),
opt = document.createElement('option');
opt.text = errorLocale[key].language;
opt.value = key;
@ -18,17 +18,18 @@ var errorLocale = window.errorLocale || null;
}
document.getElementById('translatedLanguagesSelect').addEventListener('change', function(e) {
var ref = e.target.value;
var ref = e.target.value, helpLink, meta;
if (ref) {
header.innerHTML = errorLocale[ref].header;
}
var helpLink = document.getElementById('linkHelp');
helpLink = document.getElementById('linkHelp');
if (helpLink) {
helpLink.innerText = errorLocale[ref]['help-url-text'];
}
var meta = document.querySelector('[http-equiv="Content-Language"]');
meta = document.querySelector('[http-equiv="Content-Language"]');
if (meta) {
meta.setAttribute('content', ref);
}
@ -47,12 +48,13 @@ var errorLocale = window.errorLocale || null;
// Append the translated strings
header.innerHTML = errorLocale[key].header;
var helpLink = document.getElementById('linkHelp');
var helpLink = document.getElementById('linkHelp'), meta;
if (helpLink) {
helpLink.innerText = errorLocale[key]['help-url-text'];
}
var meta = document.querySelector('[http-equiv="Content-Language"]');
meta = document.querySelector('[http-equiv="Content-Language"]');
if (meta) {
meta.setAttribute('content', key);
}

4985
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@
"lint:js": "node ./node_modules/eslint/bin/eslint.js . || exit 0",
"test": "node node_modules/karma/bin/karma start node_modules/joomla-javascript-tests/src/karma.conf.js --single-run",
"install": "node build.js --copy-assets && node build.js --build-check",
"postinstall": "node build.js --compile-js && node build.js --compile-css && node build.js --compile-ce &&cd administrator/components/com_media && npm install && npm run build",
"postinstall": "node build.js --compile-js && node build.js --compile-css && node build.js --compile-ce && cd administrator/components/com_media && npm install && npm run build",
"update": "node build.js --copy-assets && node build.js --build-check && node build.js --compile-js && node build.js --compile-ce && node build.js --compile-css"
},
"dependencies": {
@ -27,10 +27,10 @@
"@webcomponents/webcomponentsjs": "2.1.2",
"awesomplete": "github:LeaVerou/awesomplete",
"bootstrap": "4.1.3",
"choices.js": "^3.0.4",
"chosen-js": "1.6.2",
"codemirror": "5.35.0",
"cropperjs": "1.2.2",
"choices.js": "^3.0.4",
"css-vars-ponyfill": "^1.9.0",
"diff": "3.4.0",
"dragula": "3.7.2",
@ -46,46 +46,41 @@
"tinymce": "4.8.3"
},
"devDependencies": {
"autoprefixer": "^8.0.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.0",
"babel-minify": "^0.3.0",
"@babel/core": "^7.1.6",
"@babel/plugin-transform-classes": "^7.1.0",
"@babel/preset-env": "^7.1.6",
"autoprefixer": "^9.3.1",
"babel-plugin-add-header-comment": "^1.0.3",
"babel-plugin-static-fs": "latest",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-minify": "^0.3.0",
"babelify": "^8.0.0",
"bluebird": "^3.5.2",
"babel-plugin-static-fs": "^1.1.0",
"babel-preset-minify": "^0.4.3",
"babelify": "^10.0.0",
"bluebird": "^3.5.3",
"browserify": "*",
"commander": "^2.18.0",
"commander": "^2.19.0",
"copy-dir": "^0.4.0",
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0",
"cssnano": "^4.1.7",
"eslint": "^5.9.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.14.0",
"fs": "0.0.1-security",
"fs-extra": "^5.0.0",
"fs-extra": "^7.0.1",
"glob": "^7.1.3",
"ini": "latest",
"jasmine-core": "latest",
"jasmine-jquery": "latest",
"ini": "^1.3.5",
"jasmine-core": "^3.3.0",
"joomla-javascript-tests": "github:joomla/test-javascript#4.0-dev",
"karma": "^3.0.0",
"karma-coverage": "latest",
"karma-firefox-launcher": "latest",
"karma-jasmine": "latest",
"karma-jasmine-ajax": "latest",
"karma-requirejs": "latest",
"karma-verbose-reporter": "latest",
"karma": "^3.1.1",
"karma-coverage": "^1.1.2",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^2.0.1",
"karma-jasmine-ajax": "^0.1.13",
"karma-verbose-reporter": "^0.0.6",
"lodash.debounce": "^4.0.8",
"node-sass": "^4.10.0",
"path": "^0.12.7",
"postcss": "^6.0.23",
"recursive-copy": "latest",
"recursive-readdir": "^2.2.1",
"requirejs": "latest",
"text": "github:requirejs/text",
"postcss": "^7.0.6",
"recursive-copy": "^2.0.9",
"recursive-readdir": "^2.2.2",
"uglify-es": "^3.3.9",
"uglifycss": "0.0.27"
"uglifycss": "^0.0.29"
}
}

View File

@ -34,6 +34,6 @@
</div>
</div>
</div>
<script>var errorLocale=window.errorLocale||null;!function(e,t){"use strict";if(t){var n=e.getElementById("headerText");Object.keys(t).forEach(function(a){var r=e.getElementById("translatedLanguagesSelect"),l=e.createElement("option");l.text=t[a].language,l.value=a,"en-GB"===a&&l.setAttribute("selected","selected"),e.getElementById("translatedLanguagesSelect").addEventListener("change",function(a){var r=a.target.value;r&&(n.innerHTML=t[r].header);var l=e.getElementById("linkHelp");l&&(l.innerText=t[r]["help-url-text"]);var u=e.querySelector('[http-equiv="Content-Language"]');u&&u.setAttribute("content",r)}),r.appendChild(l)}),Object.keys(t).forEach(function(a){if(navigator.language===a){e.querySelector('#translatedLanguagesSelect option[value="en-GB"]').removeAttribute("selected"),e.querySelector('#translatedLanguagesSelect option[value="'+a+'"]').setAttribute("selected","selected"),n.innerHTML=t[a].header;var r=e.getElementById("linkHelp");r&&(r.innerText=t[a]["help-url-text"]);var l=e.querySelector('[http-equiv="Content-Language"]');l&&l.setAttribute("content",a)}})}}(document,errorLocale);</script><!-- Sets the script, IMPORTANT DO NOT REMOVE -->
<script>var errorLocale=window.errorLocale||null;!function(e,t){"use strict";if(t){var n=e.getElementById("headerText");Object.keys(t).forEach(function(a){var r=e.getElementById("translatedLanguagesSelect"),l=e.createElement("option");l.text=t[a].language,l.value=a,"en-GB"===a&&l.setAttribute("selected","selected"),e.getElementById("translatedLanguagesSelect").addEventListener("change",function(a){var r,l,u=a.target.value;u&&(n.innerHTML=t[u].header),(r=e.getElementById("linkHelp"))&&(r.innerText=t[u]["help-url-text"]),(l=e.querySelector('[http-equiv="Content-Language"]'))&&l.setAttribute("content",u)}),r.appendChild(l)}),Object.keys(t).forEach(function(a){if(navigator.language===a){e.querySelector('#translatedLanguagesSelect option[value="en-GB"]').removeAttribute("selected"),e.querySelector('#translatedLanguagesSelect option[value="'+a+'"]').setAttribute("selected","selected"),n.innerHTML=t[a].header;var r,l=e.getElementById("linkHelp");l&&(l.innerText=t[a]["help-url-text"]),(r=e.querySelector('[http-equiv="Content-Language"]'))&&r.setAttribute("content",a)}})}}(document,errorLocale);</script><!-- Sets the script, IMPORTANT DO NOT REMOVE -->
</body>
</html>

View File

@ -34,6 +34,6 @@
</div>
</div>
</div>
<script>var errorLocale=window.errorLocale||null;!function(e,t){"use strict";if(t){var n=e.getElementById("headerText");Object.keys(t).forEach(function(a){var r=e.getElementById("translatedLanguagesSelect"),l=e.createElement("option");l.text=t[a].language,l.value=a,"en-GB"===a&&l.setAttribute("selected","selected"),e.getElementById("translatedLanguagesSelect").addEventListener("change",function(a){var r=a.target.value;r&&(n.innerHTML=t[r].header);var l=e.getElementById("linkHelp");l&&(l.innerText=t[r]["help-url-text"]);var u=e.querySelector('[http-equiv="Content-Language"]');u&&u.setAttribute("content",r)}),r.appendChild(l)}),Object.keys(t).forEach(function(a){if(navigator.language===a){e.querySelector('#translatedLanguagesSelect option[value="en-GB"]').removeAttribute("selected"),e.querySelector('#translatedLanguagesSelect option[value="'+a+'"]').setAttribute("selected","selected"),n.innerHTML=t[a].header;var r=e.getElementById("linkHelp");r&&(r.innerText=t[a]["help-url-text"]);var l=e.querySelector('[http-equiv="Content-Language"]');l&&l.setAttribute("content",a)}})}}(document,errorLocale);</script><!-- Sets the script, IMPORTANT DO NOT REMOVE -->
<script>var errorLocale=window.errorLocale||null;!function(e,t){"use strict";if(t){var n=e.getElementById("headerText");Object.keys(t).forEach(function(a){var r=e.getElementById("translatedLanguagesSelect"),l=e.createElement("option");l.text=t[a].language,l.value=a,"en-GB"===a&&l.setAttribute("selected","selected"),e.getElementById("translatedLanguagesSelect").addEventListener("change",function(a){var r,l,u=a.target.value;u&&(n.innerHTML=t[u].header),(r=e.getElementById("linkHelp"))&&(r.innerText=t[u]["help-url-text"]),(l=e.querySelector('[http-equiv="Content-Language"]'))&&l.setAttribute("content",u)}),r.appendChild(l)}),Object.keys(t).forEach(function(a){if(navigator.language===a){e.querySelector('#translatedLanguagesSelect option[value="en-GB"]').removeAttribute("selected"),e.querySelector('#translatedLanguagesSelect option[value="'+a+'"]').setAttribute("selected","selected"),n.innerHTML=t[a].header;var r,l=e.getElementById("linkHelp");l&&(l.innerText=t[a]["help-url-text"]),(r=e.querySelector('[http-equiv="Content-Language"]'))&&r.setAttribute("content",a)}})}}(document,errorLocale);</script><!-- Sets the script, IMPORTANT DO NOT REMOVE -->
</body>
</html>