dialog enhancements (#3351)
[openemr.git] / gulpfile.js
blob464c19f280265b308bbadef9ecd263bf80e3e88e
1 'use strict';
3 // modules
4 const csso = require('gulp-csso');
5 const del = require('del');
6 const fs = require('fs');
7 const glob = require('glob');
8 const gap = require('gulp-append-prepend');
9 const replace = require('replace-in-file');
10 const gulp = require('gulp');
11 const argv = require('minimist')(process.argv.slice(2));
12 const gulpif = require('gulp-if');
13 const prefix = require('gulp-autoprefixer');
14 const rename = require('gulp-rename');
15 const sass = require('gulp-sass');
16 const sourcemaps = require('gulp-sourcemaps');
17 const gulp_watch = require('gulp-watch');
19 // package.json
20 const packages = require('./package.json');
22 // configuration
23 let config = {
24     all: [], // must always be empty
26     // Command Line Arguments
27     dev: argv['dev'],
28     build: argv['b'],
29     install: argv['i'],
31     // Source file locations
32     src: {
33         styles: {
34             style_portal: 'interface/themes/patientportal-style.scss',
35             style_uni: 'interface/themes/oe-styles/style_*.scss',
36             style_color: 'interface/themes/colors/*.scss',
37             directional: 'interface/themes/directional.scss'
38         }
39     },
40     dist: {
41         assets: 'public/assets/'
42     },
43     dest: {
44         themes: 'public/themes'
45     }
48 // Clean up lingering static themes
49 function clean(done) {
50     del.sync([config.dest.themes + "/*"]);
51     done();
54 // Parses command line arguments
55 function ingest(done) {
56     if (config.dev && typeof config.dev !== "boolean") {
57         config.dev = true;
58     }
59     done();
62 // definition of header for all compiled css
63 const autoGeneratedHeader = `
64 /*! This style sheet was autogenerated using gulp + scss
65  *  For usage instructions, see: https://github.com/openemr/openemr/blob/master/interface/README.md
66  */
69 // standard themes css compilation
70 function styles_style_portal() {
71     return gulp.src(config.src.styles.style_portal)
72     .pipe(sourcemaps.init())
73     .pipe(sass().on('error', sass.logError))
74     .pipe(prefix('last 1 version'))
75     .pipe(gap.prependText(autoGeneratedHeader))
76     .pipe(gulpif(!config.dev, csso()))
77     .pipe(gulpif(!config.dev, sourcemaps.write()))
78     .pipe(gulp.dest(config.dest.themes));
80 // standard themes css compilation
81 function styles_style_uni() {
82     return gulp.src(config.src.styles.style_uni)
83         .pipe(sourcemaps.init())
84         .pipe(sass().on('error', sass.logError))
85         .pipe(prefix('last 1 version'))
86         .pipe(gap.prependText(autoGeneratedHeader))
87         .pipe(gulpif(!config.dev, csso()))
88         .pipe(gulpif(!config.dev, sourcemaps.write()))
89         .pipe(gulp.dest(config.dest.themes));
92 // color themes css compilation
93 function styles_style_color() {
94     return gulp.src(config.src.styles.style_color)
95         .pipe(sourcemaps.init())
96         .pipe(sass().on('error', sass.logError))
97         .pipe(prefix('last 1 version'))
98         .pipe(gap.prependText(autoGeneratedHeader))
99         .pipe(gulpif(!config.dev, csso()))
100         .pipe(gulpif(!config.dev, sourcemaps.write()))
101         .pipe(gulp.dest(config.dest.themes));
104 // rtl standard themes css compilation
105 function rtl_style_portal() {
106     return gulp.src(config.src.styles.style_portal)
107         .pipe(gap.prependText('$dir: rtl;\n@import "rtl";\n@import "directional";\n')) // watch out for this relative path!
108         .pipe(gap.appendText('@include if-rtl { @include rtl_style; }\n'))
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));
119 // rtl standard themes css compilation
120 function rtl_style_uni() {
121     return gulp.src(config.src.styles.style_uni)
122         .pipe(gap.prependText('$dir: rtl;\n@import "../rtl";\n')) // watch out for this relative path!
123         .pipe(gap.appendText('@include if-rtl { @include rtl_style; #bigCal { border-right: 1px solid $black !important; } }\n'))
124         .pipe(sourcemaps.init())
125         .pipe(sass().on('error', sass.logError))
126         .pipe(prefix('last 1 version'))
127         .pipe(gap.prependText(autoGeneratedHeader))
128         .pipe(gulpif(!config.dev, csso()))
129         .pipe(gulpif(!config.dev, sourcemaps.write()))
130         .pipe(rename({ prefix: "rtl_" }))
131         .pipe(gulp.dest(config.dest.themes));
134 // rtl color themes css compilation
135 function rtl_style_color() {
136     return gulp.src(config.src.styles.style_color)
137         .pipe(gap.prependText('$dir: rtl;\n@import "../rtl";\n')) // watch out for this relative path!
138         .pipe(gap.appendText('@include if-rtl { @include rtl_style; #bigCal { border-right: 1px solid $black !important; } }\n'))
139         .pipe(sourcemaps.init())
140         .pipe(sass().on('error', sass.logError))
141         .pipe(prefix('last 1 version'))
142         .pipe(gap.prependText(autoGeneratedHeader))
143         .pipe(gulpif(!config.dev, csso()))
144         .pipe(gulpif(!config.dev, sourcemaps.write()))
145         .pipe(rename({ prefix: "rtl_" }))
146         .pipe(gulp.dest(config.dest.themes));
149 // compile themes
150 const styles = gulp.parallel(styles_style_color, styles_style_uni, styles_style_portal, rtl_style_color, rtl_style_uni, rtl_style_portal);
152 // Copies (and distills, if possible) assets from node_modules to public/assets
153 function install(done) {
154     // combine dependencies and napa sources into one object
155     const dependencies = packages.dependencies;
156     for (let key in packages.napa) {
157         if (packages.napa.hasOwnProperty(key)) {
158             dependencies[key] = packages.napa[key];
159         }
160     }
162     for (let key in dependencies) {
163         // check if the property/key is defined in the object itself, not in parent
164         if (dependencies.hasOwnProperty(key)) {
165             if (key == 'dwv') {
166                 // dwv is special and need to copy dist, decoders and locales
167                 gulp.src('node_modules/' + key + '/dist/**/*')
168                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
169                 gulp.src('node_modules/' + key + '/decoders/**/*')
170                     .pipe(gulp.dest(config.dist.assets + key + '/decoders'));
171                 gulp.src('node_modules/' + key + '/locales/**/*')
172                     .pipe(gulp.dest(config.dist.assets + key + '/locales'));
173             } else if (key == 'bootstrap' || key == 'bootstrap-v4-rtl' || key == 'bootswatch') {
174                 // bootstrap, bootstrap-v4-rtl, and bootswatch are special and need to copy dist and scss
175                 gulp.src('node_modules/' + key + '/dist/**/*')
176                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
177                 gulp.src('node_modules/' + key + '/scss/**/*')
178                     .pipe(gulp.dest(config.dist.assets + key + '/scss'));
179             } else if (key == '@ttskch/select2-bootstrap4-theme') {
180                 // @ttskch/select2-bootstrap4-theme is special and need to copy dist and src
181                 //  modify src/layout.scss in order for sass build to work by removing:
182                 //   @import "~bootstrap/scss/functions";
183                 //   @import "~bootstrap/scss/variables";
184                 //   @import "~bootstrap/scss/mixins";
185                 gulp.src('node_modules/' + key + '/dist/**/*')
186                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
187                 gulp.src('node_modules/' + key + '/src/**/*')
188                     .pipe(gulp.dest(config.dist.assets + key + '/src'))
189                     .on('end', function() {
190                         replace({
191                             files: config.dist.assets + key + '/src/layout.scss',
192                             from:
193                                 [
194                                     /@import "~bootstrap\/scss\/functions";/,
195                                     /@import "~bootstrap\/scss\/variables";/,
196                                     /@import "~bootstrap\/scss\/mixins";/
197                                 ],
198                             to: '',
199                         });
200                     });
201             } else if (fs.existsSync('node_modules/' + key + '/dist')) {
202                 // only copy dist directory, if it exists
203                 gulp.src('node_modules/' + key + '/dist/**/*')
204                     .pipe(gulp.dest(config.dist.assets + key + '/dist'));
205             } else {
206                 // copy everything
207                 gulp.src('node_modules/' + key + '/**/*')
208                     .pipe(gulp.dest(config.dist.assets + key));
209             }
210         }
211     }
213     done();
216 function watch() {
217     // watch all changes and re-run styles
218     gulp.watch('./interface/**/*.scss', { interval: 1000, mode: 'poll' }, styles);
220     // watch all changes to css/php files in themes and copy to public
221     return gulp_watch('./interface/themes/*.{css,php}', { ignoreInitial: false })
222         .pipe(gulp.dest(config.dest.themes));
225 function sync() {
226     // copy all leftover root-level components to the theme directory
227     // hoping this is only temporary
228     return gulp.src(['interface/themes/*.{css,php}'])
229         .pipe(gulp.dest(config.dest.themes));
232 // Export watch task
233 exports.watch = watch;
235 // Export pertinent default task
236 // - Note that the default task runs if no other task is chosen,
237 //    which is generally how this script is always used (except in
238 //    rare case where the user is running the watch task).
239 if (config.install) {
240     exports.default = gulp.series(install)
241 } else {
242     exports.default = gulp.series(clean, ingest, styles, sync);