add/edit event rework to get workable.
[openemr.git] / gulpfile.js
blobe996aaa14a5c34e94ac61fc2ab052b5ea65a230a
1 'use strict';
3 // modules
4 const browserSync = require('browser-sync');
5 const csso = require('gulp-csso');
6 const del = require('del');
7 const fs = require('fs');
8 const glob = require('glob');
9 const gap = require('gulp-append-prepend');
10 const replace = require('replace-in-file');
11 const gulp = require('gulp');
12 const argv = require('minimist')(process.argv.slice(2));
13 const gulpif = require('gulp-if');
14 const prefix = require('gulp-autoprefixer');
15 const reload = browserSync.reload;
16 const rename = require('gulp-rename');
17 const sass = require('gulp-sass');
18 const sourcemaps = require('gulp-sourcemaps');
19 const gulp_watch = require('gulp-watch');
21 // package.json
22 const packages = require('./package.json');
24 // configuration
25 let config = {
26     all: [], // must always be empty
28     // Command Line Arguments
29     dev: argv['dev'],
30     build: argv['b'],
31     syncOnly: argv['sync-only'],
32     proxy: argv['p'],
33     install: argv['i'],
35     // Source file locations
36     src: {
37         styles: {
38             style_uni: 'interface/themes/style_*.scss',
39             style_color: 'interface/themes/colors/*.scss',
40             directional: 'interface/themes/directional.scss'
41         }
42     },
43     dist: {
44         assets: 'public/assets/'
45     },
46     dest: {
47         themes: 'public/themes'
48     }
51 // Clean up lingering static themes
52 function clean(done) {
53     del.sync([config.dest.themes + "/*"]);
54     done();
57 // Parses command line arguments
58 function ingest(done) {
59     if (config.dev && typeof config.dev !== "boolean") {
60         // allows for custom proxy to be passed into script
61         config.proxy = config.dev;
62         config.dev = true;
63     }
64     done();
67 // definition of header for all compiled css
68 const autoGeneratedHeader = `
69 /*! This style sheet was autogenerated using gulp + scss
70  *  For usage instructions, see: https://github.com/openemr/openemr/blob/master/interface/README.md
71  */
74 // standard themes css compilation
75 function styles_style_uni() {
76     return gulp.src(config.src.styles.style_uni)
77         .pipe(sourcemaps.init())
78         .pipe(sass().on('error', sass.logError))
79         .pipe(prefix('last 1 version'))
80         .pipe(gap.prependText(autoGeneratedHeader))
81         .pipe(gulpif(!config.dev, csso()))
82         .pipe(gulpif(!config.dev, sourcemaps.write()))
83         .pipe(gulp.dest(config.dest.themes))
84         .pipe(gulpif(config.dev && config.build, gulp.dest(config.dest.themes)))
85         .pipe(gulpif(config.dev, reload({ stream: true })));
88 // color themes css compilation
89 function styles_style_color() {
90     return gulp.src(config.src.styles.style_color)
91         .pipe(sourcemaps.init())
92         .pipe(sass().on('error', sass.logError))
93         .pipe(prefix('last 1 version'))
94         .pipe(gap.prependText(autoGeneratedHeader))
95         .pipe(gulpif(!config.dev, csso()))
96         .pipe(gulpif(!config.dev, sourcemaps.write()))
97         .pipe(gulp.dest(config.dest.themes))
98         .pipe(gulpif(config.dev && config.build, gulp.dest(config.dest.themes)))
99         .pipe(gulpif(config.dev, reload({ stream: true })));
102 // compile themes
103 const styles = gulp.parallel(styles_style_uni, styles_style_color);
105 // rtl standard themes css compilation
106 function rtl_style_uni() {
107     return gulp.src(config.src.styles.style_uni)
108         .pipe(gap.prependText('@import "./rtl.scss";\n')) // watch out for this relative path!
109         .pipe(sourcemaps.init())
110         .pipe(sass().on('error', sass.logError))
111         .pipe(prefix('last 1 version'))
112         .pipe(gap.prependText(autoGeneratedHeader))
113         .pipe(gulpif(!config.dev, csso()))
114         .pipe(gulpif(!config.dev, sourcemaps.write()))
115         .pipe(rename({ prefix: "rtl_" }))
116         .pipe(gulp.dest(config.dest.themes))
117         .pipe(gulpif(config.dev && config.build, gulp.dest(config.dest.themes)))
118         .pipe(gulpif(config.dev, reload({ stream: true })));
121 // rtl color themes css compilation
122 function rtl_style_color() {
123     return gulp.src(config.src.styles.style_color)
124         .pipe(gap.prependText('@import "../rtl.scss";\n')) // watch out for this relative path!
125         .pipe(sourcemaps.init())
126         .pipe(sass().on('error', sass.logError))
127         .pipe(prefix('last 1 version'))
128         .pipe(gap.prependText(autoGeneratedHeader))
129         .pipe(gulpif(!config.dev, csso()))
130         .pipe(gulpif(!config.dev, sourcemaps.write()))
131         .pipe(rename({ prefix: "rtl_" }))
132         .pipe(gulp.dest(config.dest.themes))
133         .pipe(gulpif(config.dev && config.build, gulp.dest(config.dest.themes)))
134         .pipe(gulpif(config.dev, reload({ stream: true })));
137 // compile rtl themes
138 const rtl_styles = gulp.parallel(rtl_style_uni, rtl_style_color);
140 // append rtl css to all style themes
141 //  also, create list of all themes for style_list to use
142 function rtl_setup(done) {
143     const uni = glob.sync(config.src.styles.style_uni);
144     const colors = glob.sync(config.src.styles.style_color);
145     config.all = uni.concat(colors);
147     // backup and update directional file
148     fs.copyFile(config.src.styles.directional, config.src.styles.directional + '.temp', (err) => {
149         if (err) throw err;
150         replace({
151             files: config.src.styles.directional,
152             from: /ltr \!default/g,
153             to: 'rtl !default',
154         }).then(done());
155     });
158 function rtl_teardown(done) {
159     replace({
160         files: config.src.styles.directional,
161         from: /rtl \!default/g,
162         to: 'ltr !default',
163     }).then(function () {
164         fs.unlink(config.src.styles.directional + '.temp', (err) => {
165             if (err) throw err;
166         done();
167         });
168     });
172 // Copies (and distills, if possible) assets from node_modules to public/assets
173 function install(done) {
174     // combine dependencies and napa sources into one object
175     const dependencies = packages.dependencies;
176     for (let key in packages.napa) {
177         if (packages.napa.hasOwnProperty(key)) {
178             dependencies[key] = packages.napa[key];
179         }
180     }
182     for (let key in dependencies) {
183         // check if the property/key is defined in the object itself, not in parent
184         if (dependencies.hasOwnProperty(key)) {
185             if (key == 'dwv') {
186                 // dwv is special and need to copy dist, decoders and locales
187                 gulp.src('node_modules/' + key + '/dist/**/*')
188                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
189                 gulp.src('node_modules/' + key + '/decoders/**/*')
190                     .pipe(gulp.dest(config.dist.assets + key + '/decoders'));
191                 gulp.src('node_modules/' + key + '/locales/**/*')
192                     .pipe(gulp.dest(config.dist.assets + key + '/locales'));
193             } else if (key == 'bootstrap' || key == 'bootstrap-v4-rtl') {
194                 // bootstrap and bootstrap-v4-rtl are special and need to copy dist and scss
195                 gulp.src('node_modules/' + key + '/dist/**/*')
196                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
197                 gulp.src('node_modules/' + key + '/scss/**/*')
198                     .pipe(gulp.dest(config.dist.assets + key + '/scss'));
199             } else if (fs.existsSync('node_modules/' + key + '/dist')) {
200                 // only copy dist directory, if it exists
201                 gulp.src('node_modules/' + key + '/dist/**/*')
202                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
203             } else {
204                 // copy everything
205                 gulp.src('node_modules/' + key + '/**/*')
206                     .pipe(gulp.dest(config.dist.assets + key));
207             }
208         }
209     }
211     done();
214 function watch() {
215     // watch all changes and re-run styles
216     gulp.watch('./interface/**/*.scss', { interval: 1000, mode: 'poll' }, styles);
218     // watch all changes to css/php files in themes and copy to public
219     return gulp_watch('./interface/themes/*.{css,php}', { ignoreInitial: false })
220         .pipe(gulp.dest(config.dest.themes));
223 function sync_only(done) {
224     browserSync.init({
225         proxy: "127.0.0.1:" + config.proxy,
226         open: false
227     });
228     done();
231 // Will start browser sync and/or watch changes to scss
232 //  = Runs task(styles) first
233 function sync() {
234     if (config.proxy) {
235         browserSync.init({
236             proxy: "127.0.0.1:" + config.proxy
237         });
238     }
240     // copy all leftover root-level components to the theme directory
241     // hoping this is only temporary
242     return gulp.src(['interface/themes/*.{css,php}'])
243         .pipe(gulp.dest(config.dest.themes));
246 // Export watch task
247 exports.watch = watch;
249 // Export pertinent default task
250 // - Note that the default task runs if no other task is chosen,
251 //    which is generally how this script is always used (except in
252 //    rare case where the user is running the watch task).
253 if (config.install) {
254     exports.default = gulp.series(install)
255 } else if (config.syncOnly && config.proxy) {
256     exports.default = gulp.parallel(sync_only, watch)
257 } else {
258     exports.default = gulp.series(clean, ingest, styles, sync, rtl_setup, rtl_styles, rtl_teardown);