| const pkg = require('./package.json') |
| const path = require('path') |
| const glob = require('glob') |
| const yargs = require('yargs') |
| const colors = require('colors') |
| const through = require('through2'); |
| const qunit = require('node-qunit-puppeteer') |
| |
| const {rollup} = require('rollup') |
| const {terser} = require('rollup-plugin-terser') |
| const babel = require('@rollup/plugin-babel').default |
| const commonjs = require('@rollup/plugin-commonjs') |
| const resolve = require('@rollup/plugin-node-resolve').default |
| const sass = require('sass') |
| |
| const gulp = require('gulp') |
| const tap = require('gulp-tap') |
| const zip = require('gulp-zip') |
| const header = require('gulp-header') |
| const eslint = require('gulp-eslint') |
| const minify = require('gulp-clean-css') |
| const connect = require('gulp-connect') |
| const autoprefixer = require('gulp-autoprefixer') |
| |
| const root = yargs.argv.root || '.' |
| const port = yargs.argv.port || 8000 |
| const host = yargs.argv.host || 'localhost' |
| |
| const banner = `/*! |
| * reveal.js ${pkg.version} |
| * ${pkg.homepage} |
| * MIT licensed |
| * |
| * Copyright (C) 2011-2023 Hakim El Hattab, https://hakim.se |
| */\n` |
| |
| // Prevents warnings from opening too many test pages |
| process.setMaxListeners(20); |
| |
| const babelConfig = { |
| babelHelpers: 'bundled', |
| ignore: ['node_modules'], |
| compact: false, |
| extensions: ['.js', '.html'], |
| plugins: [ |
| 'transform-html-import-to-string' |
| ], |
| presets: [[ |
| '@babel/preset-env', |
| { |
| corejs: 3, |
| useBuiltIns: 'usage', |
| modules: false |
| } |
| ]] |
| }; |
| |
| // Our ES module bundle only targets newer browsers with |
| // module support. Browsers are targeted explicitly instead |
| // of using the "esmodule: true" target since that leads to |
| // polyfilling older browsers and a larger bundle. |
| const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) ); |
| babelConfigESM.presets[0][1].targets = { browsers: [ |
| 'last 2 Chrome versions', |
| 'last 2 Safari versions', |
| 'last 2 iOS versions', |
| 'last 2 Firefox versions', |
| 'last 2 Edge versions', |
| ] }; |
| |
| let cache = {}; |
| |
| // Creates a bundle with broad browser support, exposed |
| // as UMD |
| gulp.task('js-es5', () => { |
| return rollup({ |
| cache: cache.umd, |
| input: 'js/index.js', |
| plugins: [ |
| resolve(), |
| commonjs(), |
| babel( babelConfig ), |
| terser() |
| ] |
| }).then( bundle => { |
| cache.umd = bundle.cache; |
| return bundle.write({ |
| name: 'Reveal', |
| file: './dist/reveal.js', |
| format: 'umd', |
| banner: banner, |
| sourcemap: true |
| }); |
| }); |
| }) |
| |
| // Creates an ES module bundle |
| gulp.task('js-es6', () => { |
| return rollup({ |
| cache: cache.esm, |
| input: 'js/index.js', |
| plugins: [ |
| resolve(), |
| commonjs(), |
| babel( babelConfigESM ), |
| terser() |
| ] |
| }).then( bundle => { |
| cache.esm = bundle.cache; |
| return bundle.write({ |
| file: './dist/reveal.esm.js', |
| format: 'es', |
| banner: banner, |
| sourcemap: true |
| }); |
| }); |
| }) |
| gulp.task('js', gulp.parallel('js-es5', 'js-es6')); |
| |
| // Creates a UMD and ES module bundle for each of our |
| // built-in plugins |
| gulp.task('plugins', () => { |
| return Promise.all([ |
| { name: 'RevealHighlight', input: './plugin/highlight/plugin.js', output: './plugin/highlight/highlight' }, |
| { name: 'RevealMarkdown', input: './plugin/markdown/plugin.js', output: './plugin/markdown/markdown' }, |
| { name: 'RevealSearch', input: './plugin/search/plugin.js', output: './plugin/search/search' }, |
| { name: 'RevealNotes', input: './plugin/notes/plugin.js', output: './plugin/notes/notes' }, |
| { name: 'RevealZoom', input: './plugin/zoom/plugin.js', output: './plugin/zoom/zoom' }, |
| { name: 'RevealMath', input: './plugin/math/plugin.js', output: './plugin/math/math' }, |
| ].map( plugin => { |
| return rollup({ |
| cache: cache[plugin.input], |
| input: plugin.input, |
| plugins: [ |
| resolve(), |
| commonjs(), |
| babel({ |
| ...babelConfig, |
| ignore: [/node_modules\/(?!(highlight\.js|marked)\/).*/], |
| }), |
| terser() |
| ] |
| }).then( bundle => { |
| cache[plugin.input] = bundle.cache; |
| bundle.write({ |
| file: plugin.output + '.esm.js', |
| name: plugin.name, |
| format: 'es' |
| }) |
| |
| bundle.write({ |
| file: plugin.output + '.js', |
| name: plugin.name, |
| format: 'umd' |
| }) |
| }); |
| } )); |
| }) |
| |
| // a custom pipeable step to transform Sass to CSS |
| function compileSass() { |
| return through.obj( ( vinylFile, encoding, callback ) => { |
| const transformedFile = vinylFile.clone(); |
| |
| sass.render({ |
| data: transformedFile.contents.toString(), |
| file: transformedFile.path, |
| }, ( err, result ) => { |
| if( err ) { |
| callback(err); |
| } |
| else { |
| transformedFile.extname = '.css'; |
| transformedFile.contents = result.css; |
| callback( null, transformedFile ); |
| } |
| }); |
| }); |
| } |
| |
| gulp.task('css-themes', () => gulp.src(['./css/theme/source/*.{sass,scss}']) |
| .pipe(compileSass()) |
| .pipe(gulp.dest('./dist/theme'))) |
| |
| gulp.task('css-core', () => gulp.src(['css/reveal.scss']) |
| .pipe(compileSass()) |
| .pipe(autoprefixer()) |
| .pipe(minify({compatibility: 'ie9'})) |
| .pipe(header(banner)) |
| .pipe(gulp.dest('./dist'))) |
| |
| gulp.task('css', gulp.parallel('css-themes', 'css-core')) |
| |
| gulp.task('qunit', () => { |
| |
| let serverConfig = { |
| root, |
| port: 8009, |
| host: 'localhost', |
| name: 'test-server' |
| } |
| |
| let server = connect.server( serverConfig ) |
| |
| let testFiles = glob.sync('test/*.html' ) |
| |
| let totalTests = 0; |
| let failingTests = 0; |
| |
| let tests = Promise.all( testFiles.map( filename => { |
| return new Promise( ( resolve, reject ) => { |
| qunit.runQunitPuppeteer({ |
| targetUrl: `http://${serverConfig.host}:${serverConfig.port}/${filename}`, |
| timeout: 20000, |
| redirectConsole: false, |
| puppeteerArgs: ['--allow-file-access-from-files'] |
| }) |
| .then(result => { |
| if( result.stats.failed > 0 ) { |
| console.log(`${'!'} ${filename} [${result.stats.passed}/${result.stats.total}] in ${result.stats.runtime}ms`.red); |
| // qunit.printResultSummary(result, console); |
| qunit.printFailedTests(result, console); |
| } |
| else { |
| console.log(`${'✔'} ${filename} [${result.stats.passed}/${result.stats.total}] in ${result.stats.runtime}ms`.green); |
| } |
| |
| totalTests += result.stats.total; |
| failingTests += result.stats.failed; |
| |
| resolve(); |
| }) |
| .catch(error => { |
| console.error(error); |
| reject(); |
| }); |
| } ) |
| } ) ); |
| |
| return new Promise( ( resolve, reject ) => { |
| |
| tests.then( () => { |
| if( failingTests > 0 ) { |
| reject( new Error(`${failingTests}/${totalTests} tests failed`.red) ); |
| } |
| else { |
| console.log(`${'✔'} Passed ${totalTests} tests`.green.bold); |
| resolve(); |
| } |
| } ) |
| .catch( () => { |
| reject(); |
| } ) |
| .finally( () => { |
| server.close(); |
| } ); |
| |
| } ); |
| } ) |
| |
| gulp.task('eslint', () => gulp.src(['./js/**', 'gulpfile.js']) |
| .pipe(eslint()) |
| .pipe(eslint.format())) |
| |
| gulp.task('test', gulp.series( 'eslint', 'qunit' )) |
| |
| gulp.task('default', gulp.series(gulp.parallel('js', 'css', 'plugins'), 'test')) |
| |
| gulp.task('build', gulp.parallel('js', 'css', 'plugins')) |
| |
| gulp.task('package', gulp.series(() => |
| |
| gulp.src( |
| [ |
| './index.html', |
| './dist/**', |
| './lib/**', |
| './images/**', |
| './plugin/**', |
| './**/*.md' |
| ], |
| { base: './' } |
| ) |
| .pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./')) |
| |
| )) |
| |
| gulp.task('reload', () => gulp.src(['index.html']) |
| .pipe(connect.reload())); |
| |
| gulp.task('serve', () => { |
| |
| connect.server({ |
| root: root, |
| port: port, |
| host: host, |
| livereload: true |
| }) |
| |
| const slidesRoot = root.endsWith('/') ? root : root + '/' |
| gulp.watch([ |
| slidesRoot + '**/*.html', |
| slidesRoot + '**/*.md', |
| `!${slidesRoot}**/node_modules/**`, // ignore node_modules |
| ], gulp.series('reload')) |
| |
| gulp.watch(['js/**'], gulp.series('js', 'reload', 'eslint')) |
| |
| gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload')) |
| |
| gulp.watch([ |
| 'css/theme/source/**/*.{sass,scss}', |
| 'css/theme/template/*.{sass,scss}', |
| ], gulp.series('css-themes', 'reload')) |
| |
| gulp.watch([ |
| 'css/*.scss', |
| 'css/print/*.{sass,scss,css}' |
| ], gulp.series('css-core', 'reload')) |
| |
| gulp.watch(['test/*.html'], gulp.series('test')) |
| |
| }) |