purgetss 5.2.2 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/old-index.js DELETED
@@ -1,1980 +0,0 @@
1
- const fs = require('fs');
2
- const cwd = process.cwd();
3
- const _ = require('lodash');
4
- const junk = require('junk');
5
- const glob = require("glob");
6
- const path = require('path');
7
- const chalk = require('chalk');
8
- const convert = require('xml-js');
9
- const readCSS = require('read-css');
10
- const traverse = require('traverse');
11
- const colores = require('./lib/colores').colores;
12
- const isInstalledGlobally = require('is-installed-globally');
13
- module.exports.colores = colores;
14
- const purgeLabel = colores.purgeLabel;
15
- const helpers = require(path.resolve(__dirname, './lib/helpers'));
16
-
17
- const logger = {
18
- info: function(...args) {
19
- console.log(purgeLabel, args.join(' '));
20
- },
21
- warn: function(...args) {
22
- console.log(purgeLabel, chalk.yellow(args.join(' ')));
23
- },
24
- error: function(...args) {
25
- console.log(purgeLabel, chalk.red(args.join(' ')));
26
- },
27
- file: function(...args) {
28
- console.log(purgeLabel, chalk.yellow(args.join(' ')), 'file created!');
29
- }
30
- }
31
-
32
- const projectLibFolder = cwd + '/app/lib';
33
- const projectAppTSS = cwd + '/app/styles/app.tss';
34
- const project_AppTSS = cwd + '/app/styles/_app.tss';
35
- const projectAlloyJMKFile = cwd + '/app/alloy.jmk';
36
- const projectFontsFolder = cwd + '/app/assets/fonts';
37
- const projectFontAwesomeJS = cwd + '/app/lib/fontawesome.js';
38
-
39
- const projectPurgeTSSFolder = cwd + '/purgetss';
40
- const projectConfigJS = cwd + '/purgetss/config.js';
41
- const projectTailwindTSS = cwd + '/purgetss/tailwind.tss';
42
- const projectPurgeTSSFontsFolder = cwd + '/purgetss/fonts';
43
- const projecrFontAwesomeTSS = cwd + '/purgetss/fontawesome.tss';
44
-
45
- // js icon modules
46
- const srcLibFA = path.resolve(__dirname, './dist/fontawesome.js');
47
- const srcLibF7 = path.resolve(__dirname, './dist/framework7icons.js');
48
- const srcLibMD = path.resolve(__dirname, './dist/materialdesignicons.js');
49
- const srcPurgeTSSLibrary = path.resolve(__dirname, './dist/purgetss.ui.js');
50
-
51
- //
52
- const srcTailwindTSS = path.resolve(__dirname, './dist/tailwind.tss');
53
- //
54
-
55
- // PRO
56
- const srcFontAwesomeProCSSFile = cwd + '/node_modules/@fortawesome/fontawesome-pro/css/all.css';
57
- const srcFontAwesomeProWebFontsFolder = cwd + '/node_modules/@fortawesome/fontawesome-pro/webfonts/';
58
- // Alternate location
59
- const srcFontAwesomeProCSSFileAlternate = cwd + '/app/lib/node_modules/@fortawesome/fontawesome-pro/css/all.css';
60
- const srcFontAwesomeProWebFontsFolderAlternate = cwd + '/app/lib/node_modules/@fortawesome/fontawesome-pro/webfonts/';
61
-
62
- const srcFontAwesomeProResetTSS = './lib/templates/fontawesome/pro-reset.tss';
63
- const srcFontAwesomeProTemplateTSS = './lib/templates/fontawesome/pro-template.tss';
64
- const srcFontAwesomeProFontFamilies = {
65
- 'fa-thin-100.ttf': 'FontAwesome6Pro-Thin.ttf',
66
- 'fa-light-300.ttf': 'FontAwesome6Pro-Light.ttf',
67
- 'fa-brands-400.ttf': 'FontAwesome6Brands-Regular.ttf',
68
- 'fa-regular-400.ttf': 'FontAwesome6Pro-Regular.ttf',
69
- 'fa-solid-900.ttf': 'FontAwesome6Pro-Solid.ttf'
70
- }
71
-
72
- // BETA
73
- const srcFontAwesomeBetaCSSFile = cwd + '/purgetss/fontawesome-beta/css/all.css';
74
- const srcFontAwesomeBetaWebFontsFolder = cwd + '/purgetss/fontawesome-beta/webfonts/';
75
- const srcFontAwesomeBetaResetTSS = './lib/templates/fontawesome/beta-reset.tss';
76
- const srcFontAwesomeBetaTemplateTSS = './lib/templates/fontawesome/beta-template.tss';
77
- const srcFontAwesomeBetaFontFamilies = {
78
- 'fa-thin-100.ttf': 'FontAwesome6Pro-Thin.ttf',
79
- 'fa-light-300.ttf': 'FontAwesome6Pro-Light.ttf',
80
- 'fa-brands-400.ttf': 'FontAwesome6Brands-Regular.ttf',
81
- 'fa-regular-400.ttf': 'FontAwesome6Pro-Regular.ttf',
82
- 'fa-solid-900.ttf': 'FontAwesome6Pro-Solid.ttf',
83
- }
84
- //
85
- const srcFontsFolder = path.resolve(__dirname, './assets/fonts');
86
- const srcResetTSSFile = path.resolve(__dirname, './dist/reset.tss');
87
- const srcJMKFile = path.resolve(__dirname, './lib/templates/alloy.jmk');
88
-
89
- const srcFontAwesomeTSSFile = path.resolve(__dirname, './dist/fontawesome.tss');
90
- const srcFramework7FontTSSFile = path.resolve(__dirname, './dist/framework7icons.tss');
91
- const srcMaterialDesignIconsTSSFile = path.resolve(__dirname, './dist/materialdesignicons.tss');
92
-
93
- const srcConfigFile = path.resolve(__dirname, './lib/templates/purgetss.config.js');
94
-
95
- //! Interfase
96
-
97
- //! Command: purgetss
98
- function purgeClasses(options) {
99
- if (alloyProject()) {
100
- start();
101
-
102
- if (!fs.existsSync(projectConfigJS)) {
103
- init();
104
- }
105
-
106
- if (!fs.existsSync(projectTailwindTSS)) {
107
- buildCustomTailwind('file created!');
108
- }
109
-
110
- if (isInstalledGlobally) {
111
- if (fs.existsSync(projectAlloyJMKFile)) {
112
- if (!fs.readFileSync(projectAlloyJMKFile, 'utf8').includes('::PurgeTSS::')) {
113
- addHook();
114
- }
115
- } else {
116
- createJMKFile();
117
- }
118
- } else {
119
- logger.error('Please install PurgeTSS globally!');
120
- }
121
-
122
- backupOriginalAppTss();
123
-
124
- let uniqueClasses = getUniqueClasses();
125
-
126
- let tempPurged = copyResetTemplateAnd_appTSS();
127
-
128
- tempPurged += purgeTailwind(uniqueClasses);
129
-
130
- let cleanUniqueClasses = cleanClasses(uniqueClasses);
131
-
132
- tempPurged += purgeFontAwesome(uniqueClasses, cleanUniqueClasses);
133
-
134
- tempPurged += purgeMaterialDesign(uniqueClasses, cleanUniqueClasses);
135
-
136
- tempPurged += purgeFramework7(uniqueClasses, cleanUniqueClasses);
137
-
138
- tempPurged += purgeCustomFonts(uniqueClasses, cleanUniqueClasses);
139
-
140
- let missingClasses = getMissingClasses(tempPurged);
141
-
142
- if (missingClasses.length > 0) {
143
- tempPurged += '\n';
144
- tempPurged += '// Unused or unsupported classes\n';
145
-
146
- _.each(missingClasses, (missingClass) => {
147
- tempPurged += `'.${missingClass}': { }\n`;
148
- });
149
- }
150
-
151
- saveFile(projectAppTSS, tempPurged);
152
-
153
- logger.file('app.tss');
154
-
155
- finish();
156
- }
157
- }
158
- module.exports.purgeClasses = purgeClasses;
159
-
160
- //! Command: watch
161
- function watchMode(options) {
162
- if (alloyProject() && isInstalledGlobally) {
163
- if (fs.existsSync(projectAlloyJMKFile)) {
164
- //! TODO: Refactor with readline or line-reader: https://stackabuse.com/reading-a-file-line-by-line-in-node-js/
165
- if (options.off) {
166
- removeHook();
167
- } else if (!fs.readFileSync(projectAlloyJMKFile, 'utf8').includes('purgetss')) {
168
- addHook();
169
- } else if (fs.readFileSync(projectAlloyJMKFile, 'utf8').includes("//\trequire('child_process').execSync('purgetss")) {
170
- enableHook();
171
- } else {
172
- logger.warn(chalk.yellow('Auto-Purging hook already present!'));
173
- }
174
- } else if (!options.off) {
175
- createJMKFile();
176
- }
177
- }
178
- }
179
- module.exports.watchMode = watchMode;
180
-
181
- //! Command: copy-fonts
182
- function copyFonts(options) {
183
- if (alloyProject()) {
184
- makeSureFolderExists(projectFontsFolder);
185
-
186
- if (options.vendor && typeof options.vendor === 'string') {
187
- let selected = _.uniq(options.vendor.replace(/ /g, '').split(','));
188
- _.each(selected, vendor => {
189
- copyFont(vendor);
190
- });
191
- } else {
192
- copyFont('fa');
193
- copyFont('md');
194
- copyFont('f7');
195
- }
196
-
197
- if (options.modules) {
198
- copyFontLibraries(options);
199
- }
200
- }
201
- }
202
- module.exports.copyFonts = copyFonts;
203
-
204
- //! Command: copy-font-liraries
205
- function copyFontLibraries(options) {
206
- if (alloyProject()) {
207
- makeSureFolderExists(projectLibFolder);
208
-
209
- if (options.vendor && typeof options.vendor === 'string') {
210
- let selected = _.uniq(options.vendor.replace(/ /g, '').split(','));
211
- _.each(selected, vendor => {
212
- copyFontLibrary(vendor);
213
- });
214
- } else {
215
- copyFontLibrary('fa');
216
- copyFontLibrary('md');
217
- copyFontLibrary('f7');
218
- }
219
- }
220
- }
221
- module.exports.copyFontLibraries = copyFontLibraries;
222
-
223
- function copyModulesLibrary() {
224
- if (alloyProject()) {
225
- makeSureFolderExists(projectLibFolder);
226
-
227
- fs.copyFileSync(srcPurgeTSSLibrary, projectLibFolder + '/purgetss.ui.js');
228
- logger.info('PurgeTSS modules copied to', chalk.yellow('./app/lib'), 'folder');
229
- }
230
- }
231
- module.exports.copyModulesLibrary = copyModulesLibrary;
232
-
233
- function getFileUpdatedDate(path) {
234
- return fs.statSync(path).mtime;
235
- }
236
-
237
- function cleanClasses(uniqueClasses) {
238
- let cleanClassNames = [];
239
-
240
- uniqueClasses.forEach(classeName => {
241
- cleanClassNames.push(cleanClassNameFn(classeName));
242
- });
243
-
244
- return cleanClassNames;
245
- }
246
-
247
- //! Command: init
248
- function init() {
249
- if (alloyProject()) {
250
- makeSureFolderExists(projectPurgeTSSFolder);
251
- makeSureFolderExists(projectPurgeTSSFontsFolder);
252
- if (fs.existsSync(projectConfigJS)) {
253
- logger.warn('./purgetss/config.js', chalk.red('file already exists!'));
254
- } else {
255
- fs.copyFileSync(srcConfigFile, projectConfigJS);
256
- logger.file('./purgetss/config.js');
257
- }
258
- }
259
- }
260
- module.exports.init = init;
261
-
262
- //! Command: create
263
- function create(args, options) {
264
- start();
265
- const { exec } = require("child_process");
266
- const commandExistsSync = require('command-exists').sync;
267
-
268
- exec(`ti config app.idprefix && ti config app.workspace`, (error, stdout) => {
269
-
270
- let results = stdout.split('\n');
271
- let idPrefix = results[0];
272
- let workspace = results[1];
273
-
274
- // if (error) return logger.error(error);
275
-
276
- if (idPrefix !== 'app.idprefix not found' && workspace !== '') {
277
- console.log('');
278
- logger.info('Creating a new Titanium project');
279
-
280
- let projectName = `"${args.name}"`;
281
- let projectID = `${idPrefix}.${args.name.replace(/ /g, '').replace(/-/g, '').replace(/_/g, '').toLowerCase()}`;
282
-
283
- let tiCreateCommand = `ti create -t app -p all -n ${projectName} --no-prompt --id ${projectID}`;
284
- exec(tiCreateCommand, (error) => {
285
- if (error) return logger.error(error);
286
-
287
- let fonts = (options.vendor) ? `&& purgetss f -m -v=${options.vendor}` : '';
288
-
289
- if (options.vendor) {
290
- logger.info('Installing requested fonts');
291
- }
292
-
293
- let cdToProject = `cd ${workspace}/${projectName} && alloy new && purgetss w && purgetss b ${fonts}`;
294
- exec(cdToProject, (error) => {
295
- if (error) return logger.error(error);
296
-
297
- let theOpenCommand;
298
- if (commandExistsSync('code')) {
299
- theOpenCommand = `cd ${workspace}/${projectName} && code .`;
300
- } else if (commandExistsSync('subl')) {
301
- theOpenCommand = `cd ${workspace}/${projectName} && subl .`;
302
- } else {
303
- theOpenCommand = `cd ${workspace}/${projectName} && open .`;
304
- }
305
-
306
- if (options.tailwind) {
307
- logger.info('Installing Tailwind CSS');
308
-
309
- fs.writeFileSync(`${workspace}/${args.name}/package.json`, JSON.stringify({ "name": `${args.name.replace(/ /g, '-').toLowerCase()}`, "private": true }));
310
-
311
- let installTailwind = `cd ${workspace}/${projectName} && npm init -y && npm i tailwindcss -D && npx tailwindcss init`;
312
- exec(installTailwind, (error) => {
313
- if (error) return logger.error(error);
314
-
315
- finish(chalk.yellow(`‘${args.name}’`) + ' project created successfully in');
316
-
317
- exec(theOpenCommand, (error) => {
318
- if (error) return logger.error(error);
319
- });
320
- });
321
- } else {
322
- finish(chalk.yellow(`‘${args.name}’`) + ' project created successfully in');
323
-
324
- exec(theOpenCommand, (error) => {
325
- if (error) return logger.error(error);
326
- });
327
- }
328
- });
329
- });
330
- } else {
331
- console.log('');
332
- logger.error('::Can’t create a Titanium project::');
333
- logger.info('You need to have', chalk.green('`app.idprefix`'), 'and', chalk.green('`app.workspace`'), 'configured to create a Project with', chalk.green('`PurgeTSS`'));
334
- console.log('');
335
- logger.info('Please, set them like this:');
336
- logger.info(chalk.green('ti config app.idprefix'), chalk.yellow("'com.your.reverse.domain'"));
337
- logger.info(chalk.green('ti config app.workspace'), chalk.yellow("'path/to/your/workspace/directory'"));
338
- }
339
- });
340
- }
341
- exports.create = create;
342
-
343
- //! Command: build-custom
344
- function buildCustom() {
345
- if (alloyProject()) {
346
- initIfNotConfig()
347
- buildCustomTailwind();
348
- buildCustomFontAwesome();
349
- buildCustomFontAwesomeJS();
350
- createDefinitionsFile();
351
- }
352
- }
353
- module.exports.buildCustom = buildCustom;
354
-
355
- //! Command: Build fonts.tss
356
- function buildCustomFonts(options) {
357
- if (fs.existsSync(projectPurgeTSSFontsFolder)) {
358
- start();
359
-
360
- let files = getFiles(projectPurgeTSSFontsFolder).filter(file => {
361
- return file.endsWith('.ttf') || file.endsWith('.otf') || file.endsWith('.css') || file.endsWith('.TTF') || file.endsWith('.OTF') || file.endsWith('.CSS');
362
- });
363
-
364
- let fontMeta = '';
365
- let customFontsJS = '';
366
- const FontName = require('fontname');
367
- let tssClasses = `// Fonts TSS file generated with PurgeTSS\n// https://github.com/macCesar/purgeTSS\n`;
368
-
369
- _.each(files, file => {
370
- if (file.endsWith('.ttf') || file.endsWith('.otf') || file.endsWith('.TTF') || file.endsWith('.OTF')) {
371
- fontMeta = FontName.parse(fs.readFileSync(file))[0];
372
-
373
- tssClasses += processFontMeta(fontMeta);
374
-
375
- tssClasses += `\n'.${getFileName(file).toLowerCase()}': { font: { fontFamily: '${fontMeta.postScriptName.replace(/\//g, '')}' } }\n`;
376
-
377
- //! Copy Font File
378
- makeSureFolderExists(projectFontsFolder);
379
- let fontExtension = file.split('.').pop();
380
- fs.copyFile(file, `${projectFontsFolder}/${fontMeta.postScriptName.replace(/\//g, '')}.${fontExtension}`, err => { });
381
- logger.info('Copying font', `${chalk.yellow(file.split('/').pop())}...`);
382
- }
383
- });
384
-
385
- let oneTimeMessage = `\n// Unicode Characters\n// To use your Icon Fonts in Buttons AND Labels each class sets 'text' and 'title' properties\n`;
386
-
387
- _.each(files, file => {
388
- if (file.endsWith('.css') || file.endsWith('.CSS')) {
389
- tssClasses += oneTimeMessage + `\n// ${file.split('/').pop()}\n`;
390
- oneTimeMessage = '';
391
-
392
- tssClasses += processCustomFontsCSS(readCSS(file));
393
-
394
- //! JavaScript Module
395
- if (options.modules) {
396
- customFontsJS += processCustomFontsJS(readCSS(file), `\n\t// ${getFileName(file)}`);
397
- }
398
-
399
- // !Done processing stylesheet
400
- logger.info('Processing', `${chalk.yellow(file.split('/').pop())}...`);
401
- }
402
- });
403
-
404
- if (files.length > 0) {
405
- makeSureFolderExists(projectPurgeTSSFolder);
406
-
407
- fs.writeFileSync(cwd + '/purgetss/fonts.tss', tssClasses, err => {
408
- throw err;
409
- });
410
-
411
- makeSureFolderExists(projectLibFolder);
412
- }
413
-
414
- if (customFontsJS) {
415
- let exportIcons = fs.readFileSync(path.resolve(__dirname, './lib/templates/icon-functions.js'), 'utf8');
416
- exportIcons += '\nconst icons = {';
417
- exportIcons += customFontsJS.slice(0, -1);
418
- exportIcons += '\n};\n';
419
- exportIcons += 'exports.icons = icons;\n';
420
-
421
- fs.writeFileSync(projectLibFolder + '/purgetss.fonts.js', exportIcons, err => {
422
- throw err;
423
- });
424
-
425
- logger.info(`${chalk.yellow('./app/lib/purgetss.fonts.js')} file created!`);
426
- } else {
427
- if (fs.existsSync(projectLibFolder + '/purgetss.fonts.js')) {
428
- fs.unlinkSync(projectLibFolder + '/purgetss.fonts.js');
429
- }
430
- }
431
-
432
- if (files.length > 0) {
433
- console.log();
434
-
435
- finish(`Finished building ${chalk.yellow('fonts.tss')} in`);
436
-
437
- createDefinitionsFile();
438
- } else {
439
- logger.info('No fonts found in', chalk.yellow('./purgetss/fonts'), 'folder!');
440
- }
441
- } else {
442
- logger.info(`Add font and style files to ${chalk.yellow('./purgetss/fonts')} and run this command again!`);
443
- }
444
- }
445
- module.exports.buildCustomFonts = buildCustomFonts;
446
-
447
- function buildCustomFontAwesome() {
448
- if (fs.existsSync(srcFontAwesomeBetaCSSFile)) {
449
- processCustomFontAwesomeTSS(srcFontAwesomeBetaCSSFile, srcFontAwesomeBetaTemplateTSS, srcFontAwesomeBetaResetTSS, srcFontAwesomeBetaFontFamilies, srcFontAwesomeBetaWebFontsFolder);
450
- } else if (fs.existsSync(srcFontAwesomeProCSSFile)) {
451
- processCustomFontAwesomeTSS(srcFontAwesomeProCSSFile, srcFontAwesomeProTemplateTSS, srcFontAwesomeProResetTSS, srcFontAwesomeProFontFamilies, srcFontAwesomeProWebFontsFolder);
452
- } else if (fs.existsSync(srcFontAwesomeProCSSFileAlternate)) {
453
- processCustomFontAwesomeTSS(srcFontAwesomeProCSSFileAlternate, srcFontAwesomeProTemplateTSS, srcFontAwesomeProResetTSS, srcFontAwesomeProFontFamilies, srcFontAwesomeProWebFontsFolderAlternate);
454
- }
455
- }
456
-
457
- function processCustomFontAwesomeTSS(CSSFile, templateTSS, resetTSS, fontFamilies, webFonts) {
458
- readCSS(CSSFile, (err, data) => {
459
- if (err) throw err
460
-
461
- let tssClasses = fs.readFileSync(path.resolve(__dirname, templateTSS), 'utf8') + '\n';
462
-
463
- tssClasses += fs.readFileSync(path.resolve(__dirname, resetTSS), 'utf8') + '\n';
464
-
465
- tssClasses += processFontawesomeStyles(data);
466
-
467
- fs.writeFileSync(projecrFontAwesomeTSS, tssClasses, err => {
468
- throw err;
469
- });
470
-
471
- logger.file('./purgetss/fontawesome.tss');
472
-
473
- makeSureFolderExists(projectFontsFolder);
474
-
475
- copyProFonts(fontFamilies, webFonts);
476
- });
477
- }
478
-
479
- function buildCustomFontAwesomeJS() {
480
- if (fs.existsSync(srcFontAwesomeBetaCSSFile)) {
481
- processCustomFontAwesomeJS(srcFontAwesomeBetaCSSFile, './lib/templates/fontawesome/beta-template.js');
482
- } else if (fs.existsSync(srcFontAwesomeProCSSFile)) {
483
- processCustomFontAwesomeJS(srcFontAwesomeProCSSFile, './lib/templates/fontawesome/pro-template.js');
484
- }
485
- }
486
-
487
- function processFontawesomeStyles(data) {
488
- let convertedTSSClasses = '';
489
-
490
- let rules = _.map(data.stylesheet.rules, rule => {
491
- // Without Duotones
492
- if (rule.type === 'rule' && rule.selectors[0].includes(':before') && !rule.selectors[0].includes('.fad')) {
493
- return {
494
- 'selector': rule.selectors[0].replace(':before', '').replace(':', ''),
495
- 'property': ('0000' + rule.declarations[0].value.replace('\"\\', '').replace('\"', '')).slice(-4)
496
- };
497
- }
498
- });
499
-
500
- _.each(rules, rule => {
501
- if (rule) {
502
- convertedTSSClasses += `'${rule.selector}': { text: '\\u${rule.property}', title: '\\u${rule.property}' }\n`;
503
- }
504
- });
505
-
506
- return convertedTSSClasses;
507
- }
508
-
509
- function processCustomFontAwesomeJS(CSSFile, faJS) {
510
- readCSS(CSSFile, (err, data) => {
511
- if (err) throw err
512
-
513
- let rules = _.map(data.stylesheet.rules, rule => {
514
- if (rule.type === 'rule' && rule.selectors[0].includes(':before') && !rule.selectors[0].includes('.fad')) {
515
- return {
516
- 'selector': rule.selectors[0].replace(':before', '').replace('.', '').replace(':', ''),
517
- 'property': ('0000' + rule.declarations[0].value.replace('\"\\', '').replace('\"', '')).slice(-4)
518
- };
519
- }
520
- });
521
-
522
- let fontAwesomeContent = fs.readFileSync(path.resolve(__dirname, faJS), 'utf8');
523
-
524
- fontAwesomeContent += '\n' + fs.readFileSync(path.resolve(__dirname, './lib/templates/icon-functions.js'), 'utf8');
525
-
526
- let exportIcons = '\nconst icons = {\n';
527
-
528
- _.each(rules, rule => {
529
- if (rule) {
530
- exportIcons += `\t'${prettifyFontName(rule.selector, 'fa')}': '\\u${rule.property}',\n`;
531
- }
532
- });
533
-
534
- exportIcons += '};\n';
535
-
536
- exportIcons += 'exports.icons = icons;\n';
537
-
538
- fontAwesomeContent += exportIcons;
539
-
540
- makeSureFolderExists(projectLibFolder);
541
-
542
- fs.writeFileSync(projectFontAwesomeJS, fontAwesomeContent, err => {
543
- throw err;
544
- });
545
-
546
- logger.file('./app/lib/fontawesome.js');
547
- });
548
- }
549
-
550
- function copyFreeFonts() {
551
- fs.copyFile(srcFontsFolder + '/FontAwesome6Brands-Regular.ttf', projectFontsFolder + '/FontAwesome6Brands-Regular.ttf', callback);
552
- fs.copyFile(srcFontsFolder + '/FontAwesome6Free-Regular.ttf', projectFontsFolder + '/FontAwesome6Free-Regular.ttf', callback);
553
- fs.copyFile(srcFontsFolder + '/FontAwesome6Free-Solid.ttf', projectFontsFolder + '/FontAwesome6Free-Solid.ttf', callback);
554
-
555
- logger.info('Font Awesome Free Icons Fonts copied to', chalk.yellow('./app/assets/fonts'), 'folder');
556
- }
557
-
558
- function copyProFonts(fontFamilies, webFonts) {
559
- _.each(fontFamilies, (dest, src) => {
560
- if (copyFile(`${webFonts}/${src}`, dest)) {
561
- logger.info(`${dest} Font copied to`, chalk.yellow('./app/assets/fonts'), 'folder');
562
- }
563
- });
564
- }
565
-
566
- function copyMaterialDesignFonts() {
567
- // Material Design Icons Font
568
- let fontFamilies = [
569
- 'MaterialIcons-Regular.ttf',
570
- 'MaterialIconsOutlined-Regular.otf',
571
- 'MaterialIconsRound-Regular.otf',
572
- 'MaterialIconsSharp-Regular.otf',
573
- 'MaterialIconsTwoTone-Regular.otf'
574
- ];
575
-
576
- _.each(fontFamilies, familyName => {
577
- copyFile(`${srcFontsFolder}/${familyName}`, familyName);
578
- });
579
-
580
- logger.info('Material Design Icons Font copied to', chalk.yellow('./app/assets/fonts'), 'folder');
581
- }
582
-
583
- function copyFramework7IconsFonts() {
584
- // Framework7 Font
585
- copyFile(srcFontsFolder + '/Framework7-Icons.ttf', 'Framework7-Icons.ttf');
586
- logger.info('Framework7-Icons Font copied to', chalk.yellow('./app/assets/fonts'), 'folder');
587
- }
588
-
589
- function processCustomFontsCSS(data) {
590
- let rules = getRules(data);
591
-
592
- let processedRules = '';
593
-
594
- _.each(rules, rule => {
595
- if (rule) {
596
- processedRules += `'${rule.selector}': { text: '\\u${rule.property}', title: '\\u${rule.property}' }\n`;
597
- }
598
- });
599
-
600
- return processedRules;
601
- }
602
-
603
- function processCustomFontsJS(data, fontFamily = '') {
604
- let rules = getRules(data);
605
-
606
- let exportIcons = '\n';
607
-
608
- let thePrefix = findPrefix(rules);
609
-
610
- _.each(rules, rule => {
611
- if (rule) {
612
- exportIcons += `\t\t'${prettifyFontName(rule.selector.replace('.', ''), thePrefix)}': '\\u${rule.property}',\n`;
613
- }
614
- });
615
-
616
- if (thePrefix === undefined) {
617
- thePrefix = fontFamily;
618
- }
619
-
620
- return `${fontFamily}\n\t'${_.camelCase(thePrefix)}': {${exportIcons}\t},`;
621
- }
622
-
623
- function processFontMeta(fontMeta) {
624
- let fontMetaString = `\n/**\n * ${fontMeta.fullName}`;
625
-
626
- fontMetaString += `\n * ${fontMeta.version}`;
627
-
628
- // if (fontMeta.description) {
629
- // fontMetaString += `\n * description: ${fontMeta.description}`;
630
- // }
631
-
632
- if (fontMeta.designer) {
633
- fontMetaString += `\n * ${fontMeta.designer}`;
634
- }
635
-
636
- if (fontMeta.urlVendor) {
637
- fontMetaString += `\n * ${fontMeta.urlVendor}`;
638
- }
639
-
640
- // if (fontMeta.urlDesigner) {
641
- // fontMetaString += `\n * urlDesigner: ${fontMeta.urlDesigner}`;
642
- // }
643
-
644
- if (fontMeta.copyright) {
645
- fontMetaString += `\n * ${fontMeta.copyright}`;
646
- }
647
-
648
- if (fontMeta.trademark) {
649
- fontMetaString += `\n * ${fontMeta.trademark}`;
650
- }
651
-
652
- if (fontMeta.licence) {
653
- fontMetaString += `\n * ${fontMeta.licence.split('\n')[0]}`;
654
- }
655
-
656
- if (fontMeta.licenceURL) {
657
- fontMetaString += `\n * ${fontMeta.licenceURL}`;
658
- }
659
-
660
- fontMetaString += `\n */`;
661
-
662
- return fontMetaString;
663
- }
664
-
665
- function getFiles(dir) {
666
- return fs.readdirSync(dir).flatMap((item) => {
667
- const path = `${dir}/${item}`;
668
- if (fs.statSync(path).isDirectory()) {
669
- return getFiles(path);
670
- }
671
-
672
- return path;
673
- });
674
- }
675
-
676
- function getFileName(file) {
677
- return file.split('/').pop().split('.').shift();
678
- }
679
-
680
- function getRules(data) {
681
- let rules = _.map(data.stylesheet.rules, rule => {
682
- if (rule.type === 'rule' && rule.declarations[0].property === 'content' && rule.selectors[0].includes('before')) {
683
- return {
684
- 'selector': '.' + rule.selectors[0].replace('.', '').replace('::before', '').replace(':before', ''),
685
- 'property': ('0000' + rule.declarations[0].value.replace('\"\\', '').replace('\"', '').replace('\'\\', '').replace('\'', '')).slice(-4)
686
- };
687
- }
688
- }).filter(rule => rule);
689
-
690
- return rules;
691
- }
692
-
693
- function findPrefix(rules) {
694
- let arrayOfRules = rules.map(function(item) {
695
- return item.selector.replace('.', '').split('-');
696
- });
697
-
698
- let firstPrefix = '';
699
- let firstCounter = 0;
700
- let secondPrefix = '';
701
- let secondCounter = 0;
702
- let thirdPrefix = '';
703
- let thirdCounter = 0;
704
-
705
- _.each(arrayOfRules, item => {
706
- if (item[0] != firstPrefix) {
707
- firstPrefix = item[0];
708
- firstCounter++;
709
- }
710
- if (item.length > 1 && secondPrefix != item[1]) {
711
- secondPrefix = item[1];
712
- secondCounter++;
713
- }
714
- if (item.length > 2 && thirdPrefix != item[2]) {
715
- thirdPrefix = item[2];
716
- thirdCounter++;
717
- }
718
- });
719
-
720
- if (firstCounter == 1 && secondCounter == 1 && thirdCounter == 1) {
721
- return `${firstPrefix}-${secondPrefix}-${thirdPrefix}`;
722
- } else if (firstCounter == 1 && secondCounter == 1) {
723
- return `${firstPrefix}-${secondPrefix}`;
724
- } else if (firstCounter == 1) {
725
- return `${firstPrefix}`;
726
- };
727
- }
728
-
729
- //! Purge Custom Fonts
730
- function purgeCustomFonts(uniqueClasses, cleanUniqueClasses) {
731
- if (fs.existsSync(cwd + '/purgetss/fonts.tss')) {
732
- let purgedClasses = '\n// Custom Fonts styles\n';
733
-
734
- let sourceTSS = fs.readFileSync(cwd + '/purgetss/fonts.tss', 'utf8').split(/\r?\n/);
735
-
736
- purgedClasses += purgeFontIcons(sourceTSS, uniqueClasses, 'Purging Custom Fonts styles...', cleanUniqueClasses, []);
737
-
738
- return (purgedClasses === '\n// Custom Fonts styles\n') ? '' : purgedClasses;
739
- }
740
-
741
- return '';
742
- }
743
-
744
- function prettifyFontName(str, prefix) {
745
- let temp = str.replace(/_/g, '-').replace(prefix, '').replace(/\s/g, '').split('-');
746
-
747
- let withoutPrefix = [];
748
-
749
- let i = 1;
750
- if (prefix === undefined) {
751
- i = 0;
752
- }
753
-
754
- for (i; i < temp.length; i++) {
755
- withoutPrefix.push(temp[i].charAt(0).toUpperCase() + temp[i].slice(1));
756
- }
757
-
758
- let pretty = withoutPrefix.join('').replace(':', '');
759
- return pretty.replace(/^.{1}/g, pretty[0].toLowerCase());
760
- };
761
-
762
- //! Helper Functions
763
- function getMissingClasses(tempPurged) {
764
- _.each(getFiles(cwd + '/app/styles').filter(file => file.endsWith('.tss') && !file.endsWith('app.tss')), file => {
765
- tempPurged += '\n' + fs.readFileSync(file, 'utf8');
766
- });
767
-
768
- return getOnlyClassesFromXMLFiles().filter(item => !tempPurged.includes(item));
769
- }
770
-
771
- function addHook() {
772
- logger.warn(chalk.green('Adding Auto-Purging hook!'));
773
- let originalJMKFile = fs.readFileSync(projectAlloyJMKFile, 'utf8');
774
-
775
- if (originalJMKFile.includes('pre:compile')) {
776
- let updatedJMKFile = [];
777
-
778
- originalJMKFile.split(/\r?\n/).forEach((line) => {
779
- if (line.includes('pre:compile')) {
780
- line += "\n\trequire('child_process').execSync('purgetss', logger.warn('::PurgeTSS:: Auto-Purging ' + event.dir.project));";
781
- }
782
- updatedJMKFile.push(line);
783
- });
784
-
785
- saveFile(projectAlloyJMKFile, updatedJMKFile.join("\n"));
786
- } else {
787
- fs.appendFileSync(projectAlloyJMKFile, '\n' + fs.readFileSync(srcJMKFile, 'utf8'));
788
- }
789
- }
790
-
791
- function removeHook() {
792
- let updatedJMKFile = [];
793
- let originalJMKFile = fs.readFileSync(projectAlloyJMKFile, 'utf8');
794
- let purgeCmdPresent = (originalJMKFile.includes('::PurgeTSS::'));
795
-
796
- if (purgeCmdPresent) {
797
- originalJMKFile.split(/\r?\n/).forEach((line) => {
798
- if (!line.includes("require('child_process').execSync('purgetss")) {
799
- updatedJMKFile.push(line);
800
- } else if (!line.includes("//")) {
801
- updatedJMKFile.push(`\t//${line}`);
802
- logger.warn(chalk.yellow('Auto-Purging hook disabled!'));
803
- } else {
804
- logger.warn(chalk.red('Auto-Purging hook removed!'));
805
- logger.warn(chalk.red('It will be added the next time `PurgeTSS` runs!'));
806
- }
807
- });
808
-
809
- saveFile(projectAlloyJMKFile, updatedJMKFile.join("\n"));
810
- }
811
- }
812
-
813
- function enableHook() {
814
- let updatedJMKFile = [];
815
-
816
- let originalJMKFile = fs.readFileSync(projectAlloyJMKFile, 'utf8');
817
-
818
- originalJMKFile.split(/\r?\n/).forEach((line) => {
819
- if (line.includes("require('child_process').execSync('purgetss")) {
820
- logger.warn(chalk.green('Auto-Purging hook enabled!'));
821
- line = line.replace(/\/\/\t/g, "");
822
- }
823
-
824
- updatedJMKFile.push(line);
825
-
826
- saveFile(projectAlloyJMKFile, updatedJMKFile.join("\n"));
827
- });
828
- }
829
-
830
- function initIfNotConfig() {
831
- if (!fs.existsSync(projectConfigJS)) {
832
- init();
833
- }
834
- }
835
-
836
- function makeSureFolderExists(folder) {
837
- if (!fs.existsSync(folder)) {
838
- fs.mkdirSync(folder);
839
- }
840
- }
841
-
842
- function copyFile(src, dest) {
843
- if (fs.existsSync(src)) {
844
- // if (!fs.existsSync(`${projectFontsFolder}/${dest}`)) {
845
- fs.copyFile(src, `${projectFontsFolder}/${dest}`, callback);
846
- return true;
847
- // }
848
- }
849
- }
850
-
851
- function getOnlyClassesFromXMLFiles() {
852
- let viewPaths = [];
853
-
854
- readAllXMLFiles(cwd + '/app/views', viewPath => {
855
- viewPaths.push(viewPath);
856
- });
857
-
858
- let allClasses = [];
859
- _.each(viewPaths, viewPath => {
860
- allClasses.push(extractOnlyClasses(fs.readFileSync(viewPath, 'utf8'), viewPath));
861
- });
862
-
863
- let uniqueClasses = [];
864
- _.each(_.uniq(_.flattenDeep(allClasses)).sort(), uniqueClass => {
865
- if (filterCharacters(uniqueClass)) {
866
- uniqueClasses.push(uniqueClass);
867
- }
868
- });
869
-
870
- return uniqueClasses.sort();
871
- }
872
-
873
- function getUniqueClasses() {
874
- let configFile = (fs.existsSync(projectConfigJS)) ? require(projectConfigJS) : false;
875
-
876
- let widgets = false;
877
- let safelist = false;
878
- let purgeMode = 'all';
879
- let purgeOptions = false;
880
-
881
- if (configFile.purge) {
882
- purgeOptions = configFile.purge.options || false;
883
- widgets = purgeOptions.widgets || false;
884
- safelist = purgeOptions.safelist || false;
885
- purgeMode = configFile.purge.mode || 'all';
886
- }
887
-
888
- let viewPaths = [];
889
-
890
- readAllXMLFiles(cwd + '/app/views', viewPath => {
891
- viewPaths.push(viewPath);
892
- });
893
-
894
- if (widgets) {
895
- //! Parse Widgets' Views ( Experimental )
896
- viewPaths.push(...glob.sync(cwd + '/app/widgets/**/views/*.xml'));
897
- }
898
-
899
- let allClasses = [];
900
-
901
- // read all XML files
902
- _.each(viewPaths, viewPath => {
903
- let file = fs.readFileSync(viewPath, 'utf8');
904
-
905
- allClasses.push((purgeMode === 'all') ? file.match(/[^<>"'`\s]*[^<>"'`\s:]/g) : extractClasses(file, viewPath));
906
- });
907
-
908
- if (safelist) {
909
- _.each(safelist, safe => {
910
- allClasses.push(safe);
911
- })
912
- }
913
-
914
- let uniqueClasses = [];
915
-
916
- // Clean even more unnecessary names
917
- _.each(_.uniq(_.flattenDeep(allClasses)).sort(), uniqueClass => {
918
- if (filterCharacters(uniqueClass)) {
919
- uniqueClasses.push(uniqueClass);
920
- }
921
- });
922
-
923
- return uniqueClasses.sort();
924
- }
925
-
926
- function filterCharacters(uniqueClass) {
927
- return isNaN(uniqueClass.charAt(0)) &&
928
- !uniqueClass.startsWith('--') &&
929
- !uniqueClass.startsWith('!') &&
930
- !uniqueClass.startsWith('[') &&
931
- !uniqueClass.startsWith('{') &&
932
- !uniqueClass.startsWith('/') &&
933
- !uniqueClass.startsWith('\\') &&
934
- !uniqueClass.startsWith('#') &&
935
- !uniqueClass.startsWith('$') &&
936
- !uniqueClass.startsWith('Ti.') &&
937
- !uniqueClass.startsWith(',') &&
938
- !uniqueClass.includes('http') &&
939
- !uniqueClass.includes('www') &&
940
- // !uniqueClass.includes(')') &&
941
- !uniqueClass.includes('=') &&
942
- !uniqueClass.includes('L(') &&
943
- !uniqueClass.endsWith(',') &&
944
- !uniqueClass.endsWith('/');
945
- }
946
-
947
- //! Build Custom Tailwind ( Main )
948
- function buildCustomTailwind(message = 'file created!') {
949
- let iAmInProjectFolder = fs.existsSync(projectConfigJS);
950
- let configFile = (iAmInProjectFolder) ? require(projectConfigJS) : require(srcConfigFile);
951
-
952
- const defaultColors = require('tailwindcss/colors');
953
- const defaultTheme = require('tailwindcss/defaultTheme');
954
-
955
- // Remove deprecated colors
956
- delete defaultColors.blueGray;
957
- delete defaultColors.coolGray;
958
- delete defaultColors.current;
959
- delete defaultColors.inherit;
960
- delete defaultColors.lightBlue;
961
- delete defaultColors.trueGray;
962
- delete defaultColors.warmGray;
963
-
964
- // !Prepare values
965
- configFile.theme.extend = configFile.theme.extend ?? {};
966
-
967
- let allWidthsCombined = (configFile.theme.spacing) ? { ...{ full: '100%', auto: '', screen: '' }, ...configFile.theme.spacing } : { ...defaultTheme.width({ theme: () => (defaultTheme.spacing) }) };
968
- let allHeightsCombined = (configFile.theme.spacing) ? { ...{ full: '100%', auto: '', screen: '' }, ...configFile.theme.spacing } : defaultTheme.height({ theme: () => (defaultTheme.spacing) });
969
-
970
- let overwritten = {
971
- width: configFile.theme.width ?? allWidthsCombined,
972
- height: configFile.theme.height ?? allHeightsCombined,
973
- spacing: configFile.theme.spacing ?? { ...defaultTheme.spacing },
974
- colors: configFile.theme.colors ?? { transparent: 'transparent', ...defaultColors },
975
- }
976
-
977
- let base = {
978
- colors: _.merge(overwritten.colors, configFile.theme.extend.colors),
979
- spacing: _.merge(overwritten.spacing, configFile.theme.extend.spacing),
980
- width: _.merge(overwritten.spacing, configFile.theme.extend.spacing, overwritten.width, configFile.theme.extend.width),
981
- height: _.merge(overwritten.spacing, configFile.theme.extend.spacing, overwritten.height, configFile.theme.extend.height)
982
- }
983
-
984
- // Have to 'fix' any '.333333%' value to '.333334%' to propertly fit the screen
985
- _.each(base.spacing, (value, key) => {
986
- if (value.toString().includes('.333333%')) {
987
- base.spacing[key] = value.replace('.333333%', '.333334%');
988
- }
989
- });
990
-
991
- //! Process custom Window, View and ImageView
992
- if (configFile.theme.Window && configFile.theme.Window.apply) {
993
- let theApply = configFile.theme.Window.apply;
994
- delete configFile.theme.Window.apply;
995
- configFile.theme['Window'] = _.merge({ apply: theApply }, configFile.theme.Window);
996
- } else {
997
- configFile.theme['Window'] = _.merge({ default: { backgroundColor: '#ffffff' } }, configFile.theme.Window);
998
- }
999
-
1000
- if (configFile.theme.ImageView && configFile.theme.ImageView.apply) {
1001
- let theApply = configFile.theme.ImageView.apply;
1002
- delete configFile.theme.ImageView.apply;
1003
- configFile.theme['ImageView'] = _.merge({ apply: theApply }, { ios: { hires: true } }, configFile.theme.ImageView);
1004
- } else {
1005
- configFile.theme['ImageView'] = _.merge({ ios: { hires: true } }, configFile.theme.ImageView);
1006
- }
1007
-
1008
- if (configFile.theme.View && configFile.theme.View.apply) {
1009
- let theApply = configFile.theme.View.apply;
1010
- delete configFile.theme.View.apply;
1011
- configFile.theme['View'] = _.merge({ apply: theApply }, configFile.theme.View);
1012
- } else {
1013
- configFile.theme['View'] = _.merge({ default: { width: 'Ti.UI.SIZE', height: 'Ti.UI.SIZE' } }, configFile.theme.View);
1014
- }
1015
-
1016
- let defaultBorderRadius = (configFile.theme.spacing || configFile.theme.borderRadius) ? {} : { ...defaultTheme.borderRadius, ...base.spacing };
1017
-
1018
- // Some clean up
1019
- // pagingControlHeight
1020
- delete base.height['fit'];
1021
- delete base.height['max'];
1022
- delete base.height['min'];
1023
- delete base.height['min-content'];
1024
- delete base.height['max-content'];
1025
-
1026
- //! Width, height and margin properties
1027
- configFile.theme.height = base.height;
1028
- configFile.theme.width = base.width;
1029
- configFile.theme.margin = combineKeys(configFile.theme, base.spacing, 'margin');
1030
-
1031
- //! Properties with constant values
1032
- configFile.theme.accessibilityHidden = {};
1033
- configFile.theme.activeIconIsMask = {};
1034
- configFile.theme.activityEnterTransition = {};
1035
- configFile.theme.activityExitTransition = {};
1036
- configFile.theme.activityIndicatorStyle = {};
1037
- configFile.theme.activityReenterTransition = {};
1038
- configFile.theme.activityReturnTransition = {};
1039
- configFile.theme.activitySharedElementEnterTransition = {};
1040
- configFile.theme.activitySharedElementExitTransition = {};
1041
- configFile.theme.activitySharedElementReenterTransition = {};
1042
- configFile.theme.activitySharedElementReturnTransition = {};
1043
- configFile.theme.alertDialogStyle = {};
1044
- configFile.theme.allowsMultipleSelectionDuringEditing = {};
1045
- configFile.theme.allowsMultipleSelectionInteraction = {};
1046
- configFile.theme.allowsSelection = {};
1047
- configFile.theme.allowsSelectionDuringEditing = {};
1048
- configFile.theme.allowUserCustomization = {};
1049
- configFile.theme.animationStyle = {};
1050
- configFile.theme.autoAdjustScrollViewInsets = {};
1051
- configFile.theme.autocapitalization = {};
1052
- configFile.theme.autocorrect = {};
1053
- configFile.theme.autofillType = {};
1054
- configFile.theme.autoLink = {};
1055
- configFile.theme.autoreverse = {};
1056
- configFile.theme.backgroundBlendMode = {};
1057
- configFile.theme.backgroundLinearGradient = {};
1058
- configFile.theme.backgroundRadialGradient = {};
1059
- configFile.theme.backgroundRepeat = {};
1060
- configFile.theme.borderStyle = {};
1061
- configFile.theme.bubbleParent = {};
1062
- configFile.theme.buttonStyle = {};
1063
- configFile.theme.cacheSize = {};
1064
- configFile.theme.canDelete = {};
1065
- configFile.theme.canScroll = {};
1066
- configFile.theme.caseInsensitiveSearch = {};
1067
- configFile.theme.clipMode = {};
1068
- configFile.theme.defaultItemTemplate = {};
1069
- configFile.theme.dimBackgroundForSearch = {};
1070
- configFile.theme.disableBounce = {};
1071
- configFile.theme.displayCaps = {};
1072
- configFile.theme.displayHomeAsUp = {};
1073
- configFile.theme.displayUtilities = {};
1074
- configFile.theme.draggingConstraints = {};
1075
- configFile.theme.draggingType = {};
1076
- configFile.theme.drawerIndicatorEnabled = {};
1077
- configFile.theme.drawerLockMode = {};
1078
- configFile.theme.dropShadow = {};
1079
- configFile.theme.editable = {};
1080
- configFile.theme.editing = {};
1081
- configFile.theme.ellipsize = {};
1082
- configFile.theme.enableCopy = {};
1083
- configFile.theme.enabled = {};
1084
- configFile.theme.enableReturnKey = {};
1085
- configFile.theme.enableZoomControls = {};
1086
- configFile.theme.exitOnClose = {};
1087
- configFile.theme.extendBackground = {};
1088
- configFile.theme.extendEdges = {};
1089
- configFile.theme.extendSafeArea = {};
1090
- configFile.theme.fastScroll = {};
1091
- configFile.theme.filterAnchored = {};
1092
- configFile.theme.filterAttribute = {};
1093
- configFile.theme.filterCaseInsensitive = {};
1094
- configFile.theme.flagSecure = {};
1095
- configFile.theme.flip = {};
1096
- configFile.theme.fontStyle = {};
1097
- configFile.theme.footerDividersEnabled = {};
1098
- configFile.theme.fullscreen = {};
1099
- configFile.theme.gridColumnsStartEnd = {};
1100
- configFile.theme.gridFlow = {};
1101
- configFile.theme.gridSystem = {};
1102
- configFile.theme.headerDividersEnabled = {};
1103
- configFile.theme.hidesBackButton = {};
1104
- configFile.theme.hidesBarsOnSwipe = {};
1105
- configFile.theme.hidesBarsOnTap = {};
1106
- configFile.theme.hidesBarsWhenKeyboardAppears = {};
1107
- configFile.theme.hideSearchOnSelection = {};
1108
- configFile.theme.hideShadow = {};
1109
- configFile.theme.hidesSearchBarWhenScrolling = {};
1110
- configFile.theme.hires = {};
1111
- configFile.theme.homeButtonEnabled = {};
1112
- configFile.theme.homeIndicatorAutoHidden = {};
1113
- configFile.theme.html = {};
1114
- configFile.theme.iconified = {};
1115
- configFile.theme.iconifiedByDefault = {};
1116
- configFile.theme.iconIsMask = {};
1117
- configFile.theme.includeOpaqueBars = {};
1118
- configFile.theme.items = {};
1119
- configFile.theme.keepScreenOn = {};
1120
- configFile.theme.keepSectionsInSearch = {};
1121
- configFile.theme.keyboardAppearance = {};
1122
- configFile.theme.keyboardDismissMode = {};
1123
- configFile.theme.keyboardType = {};
1124
- configFile.theme.largeTitleDisplayMode = {};
1125
- configFile.theme.largeTitleEnabled = {};
1126
- configFile.theme.layout = {};
1127
- configFile.theme.lazyLoadingEnabled = {};
1128
- configFile.theme.leftDrawerLockMode = {};
1129
- configFile.theme.listViewStyle = {};
1130
- configFile.theme.loginKeyboardType = {};
1131
- configFile.theme.loginReturnKeyType = {};
1132
- configFile.theme.modal = {};
1133
- configFile.theme.moveable = {};
1134
- configFile.theme.moving = {};
1135
- configFile.theme.navBarHidden = {};
1136
- configFile.theme.orientationModes = {};
1137
- configFile.theme.origin = {};
1138
- configFile.theme.overlayEnabled = {};
1139
- configFile.theme.overScrollMode = {};
1140
- configFile.theme.pagingControl = {};
1141
- configFile.theme.pagingControlOnTop = {};
1142
- configFile.theme.passwordKeyboardType = {};
1143
- configFile.theme.pickerType = {};
1144
- configFile.theme.placement = {};
1145
- configFile.theme.preventCornerOverlap = {};
1146
- configFile.theme.preventDefaultImage = {};
1147
- configFile.theme.previewActionStyle = {};
1148
- configFile.theme.progressBarStyle = {};
1149
- configFile.theme.progressIndicatorCancelable = {};
1150
- configFile.theme.progressIndicatorCancelOnTouchOutside = {};
1151
- configFile.theme.progressIndicatorLocation = {};
1152
- configFile.theme.progressIndicatorType = {};
1153
- configFile.theme.pruneSectionsOnEdit = {};
1154
- configFile.theme.repeat = {};
1155
- configFile.theme.requestOrientation = {};
1156
- configFile.theme.resultsSeparatorStyle = {};
1157
- configFile.theme.returnKeyType = {};
1158
- configFile.theme.rightDrawerLockMode = {};
1159
- configFile.theme.rowAndColumnCount = {};
1160
- configFile.theme.scrollable = {};
1161
- configFile.theme.scrollableRegion = {};
1162
- configFile.theme.scrollIndicators = {};
1163
- configFile.theme.scrollIndicatorStyle = {};
1164
- configFile.theme.scrollingEnabled = {};
1165
- configFile.theme.scrollsToTop = {};
1166
- configFile.theme.scrollType = {};
1167
- configFile.theme.searchAsChild = {};
1168
- configFile.theme.searchBarStyle = {};
1169
- configFile.theme.searchHidden = {};
1170
- configFile.theme.sectionHeaderTopPadding = {};
1171
- configFile.theme.selectionStyle = {};
1172
- configFile.theme.separatorStyle = {};
1173
- configFile.theme.shiftMode = {};
1174
- configFile.theme.showAsAction = {};
1175
- configFile.theme.showBookmark = {};
1176
- configFile.theme.showCancel = {};
1177
- configFile.theme.showSearchBarInNavBar = {};
1178
- configFile.theme.showSelectionCheck = {};
1179
- configFile.theme.showVerticalScrollIndicator = {};
1180
- configFile.theme.smoothScrollOnTabClick = {};
1181
- configFile.theme.statusBarStyle = {};
1182
- configFile.theme.submitEnabled = {};
1183
- configFile.theme.sustainedPerformanceMode = {};
1184
- configFile.theme.swipeToClose = {};
1185
- configFile.theme.switchStyle = {};
1186
- configFile.theme.systemButton = {};
1187
- configFile.theme.tabBarHidden = {};
1188
- configFile.theme.tabbedBarStyle = {};
1189
- configFile.theme.tabGroupStyle = {};
1190
- configFile.theme.tableViewStyle = {};
1191
- configFile.theme.tabsTranslucent = {};
1192
- configFile.theme.textAlign = {};
1193
- configFile.theme.theme = {};
1194
- configFile.theme.tiMedia = {};
1195
- configFile.theme.titleAttributesShadow = {};
1196
- configFile.theme.toolbarEnabled = {};
1197
- configFile.theme.touchEnabled = {};
1198
- configFile.theme.touchFeedback = {};
1199
- configFile.theme.transition = {};
1200
- configFile.theme.translucent = {};
1201
- configFile.theme.useCompatPadding = {};
1202
- configFile.theme.useSpinner = {};
1203
- configFile.theme.verticalAlign = {};
1204
- configFile.theme.viewShadow = {};
1205
- configFile.theme.willScrollOnStatusTap = {};
1206
- configFile.theme.windowPixelFormat = {};
1207
- configFile.theme.windowSoftInputMode = {};
1208
- configFile.theme.wobble = {};
1209
-
1210
- //! Configurable properties
1211
- configFile.theme.borderRadius = combineKeys(configFile.theme, _.merge(defaultBorderRadius, configFile.theme.spacing, configFile.theme.extend.spacing), 'borderRadius');
1212
- configFile.theme.borderWidth = combineKeys(configFile.theme, defaultTheme.borderWidth, 'borderWidth');
1213
- configFile.theme.bottomNavigation = combineKeys(configFile.theme, base.spacing, 'bottomNavigation');
1214
- configFile.theme.elevation = combineKeys(configFile.theme, _.merge(base.spacing, configFile.theme.spacing, configFile.theme.extend.spacing), 'elevation');
1215
- configFile.theme.fontFamily = combineKeys(configFile.theme, {}, 'fontFamily');
1216
- configFile.theme.fontSize = combineKeys(configFile.theme, defaultTheme.fontSize, 'fontSize');
1217
- configFile.theme.fontWeight = combineKeys(configFile.theme, defaultTheme.fontWeight, 'fontWeight');
1218
- configFile.theme.gap = combineKeys(configFile.theme, base.spacing, 'margin');
1219
- configFile.theme.leftWidth = combineKeys(configFile.theme, base.width, 'leftWidth');
1220
- configFile.theme.maxElevation = combineKeys(configFile.theme, _.merge(base.spacing, configFile.theme.spacing, configFile.theme.extend.spacing), 'maxElevation');
1221
- configFile.theme.maxRowHeight = combineKeys(configFile.theme, base.height, 'maxRowHeight');
1222
- configFile.theme.minRowHeight = combineKeys(configFile.theme, base.height, 'minRowHeight');
1223
- configFile.theme.opacity = combineKeys(configFile.theme, defaultTheme.opacity, 'opacity');
1224
- configFile.theme.padding = combineKeys(configFile.theme, base.spacing, 'padding');
1225
- configFile.theme.pagingControlAlpha = combineKeys(configFile.theme, defaultTheme.opacity, 'pagingControlAlpha');
1226
- configFile.theme.pagingControlHeight = combineKeys(configFile.theme, base.height, 'pagingControlHeight');
1227
- configFile.theme.pagingControlTimeout = combineKeys(configFile.theme, { ...{ '0': '0ms', '25': '25ms', '50': '50ms', '2000': '2000ms', '3000': '3000ms', '4000': '4000ms', '5000': '5000ms' }, ...defaultTheme.transitionDelay }, 'pagingControlTimeout');
1228
- configFile.theme.rightWidth = combineKeys(configFile.theme, base.width, 'rightWidth');
1229
- configFile.theme.rotate = combineKeys(configFile.theme, defaultTheme.rotate, 'rotate');
1230
- configFile.theme.rowHeight = combineKeys(configFile.theme, base.height, 'rowHeight');
1231
- configFile.theme.scale = combineKeys(configFile.theme, { ...{ 5: '.05', 10: '.10', 25: '.25' }, ...defaultTheme.scale }, 'scale');
1232
- configFile.theme.separatorHeight = combineKeys(configFile.theme, base.height, 'separatorHeight');
1233
- configFile.theme.shadowRadius = combineKeys(configFile.theme, _.merge(base.spacing, configFile.theme.spacing, configFile.theme.extend.spacing), 'shadowRadius');
1234
- configFile.theme.transitionDelay = combineKeys(configFile.theme, { ...{ '0': '0ms', '25': '25ms', '50': '50ms', '250': '250ms', '350': '350ms', '400': '400ms', '450': '450ms', '600': '600ms', '800': '800ms', '900': '900ms', '2000': '2000ms', '3000': '3000ms', '4000': '4000ms', '5000': '5000ms' }, ...defaultTheme.transitionDelay }, 'transitionDelay');
1235
- configFile.theme.transitionDuration = combineKeys(configFile.theme, { ...{ '0': '0ms', '25': '25ms', '50': '50ms', '250': '250ms', '350': '350ms', '400': '400ms', '450': '450ms', '600': '600ms', '800': '800ms', '900': '900ms', '2000': '2000ms', '3000': '3000ms', '4000': '4000ms', '5000': '5000ms' }, ...defaultTheme.transitionDuration }, 'transitionDuration');
1236
- configFile.theme.zIndex = combineKeys(configFile.theme, defaultTheme.zIndex, 'zIndex');
1237
-
1238
- //! Color related properties
1239
- configFile.theme.activeTintColor = combineKeys(configFile.theme, base.colors, 'activeTintColor');
1240
- configFile.theme.activeTitleColor = combineKeys(configFile.theme, base.colors, 'activeTitleColor');
1241
- configFile.theme.backgroundColor = combineKeys(configFile.theme, base.colors, 'backgroundColor');
1242
- configFile.theme.backgroundGradient = combineKeys(configFile.theme, base.colors, 'backgroundGradient');
1243
- configFile.theme.backgroundSelectedColor = combineKeys(configFile.theme, base.colors, 'backgroundSelectedColor');
1244
- configFile.theme.barColor = combineKeys(configFile.theme, base.colors, 'barColor');
1245
- configFile.theme.borderColor = combineKeys(configFile.theme, base.colors, 'borderColor');
1246
- configFile.theme.currentPageIndicatorColor = combineKeys(configFile.theme, base.colors, 'currentPageIndicatorColor');
1247
- configFile.theme.disabledColor = combineKeys(configFile.theme, base.colors, 'disabledColor');
1248
- configFile.theme.dropShadowColor = combineKeys(configFile.theme, base.colors, 'shadowColor');
1249
- configFile.theme.hintTextColor = combineKeys(configFile.theme, base.colors, 'hintTextColor');
1250
- configFile.theme.indicatorColor = combineKeys(configFile.theme, base.colors, 'indicatorColor');
1251
- configFile.theme.navTintColor = combineKeys(configFile.theme, base.colors, 'navTintColor');
1252
- configFile.theme.pageIndicatorColor = combineKeys(configFile.theme, base.colors, 'pageIndicatorColor');
1253
- configFile.theme.pagingControlColor = combineKeys(configFile.theme, base.colors, 'pagingControlColor');
1254
- configFile.theme.resultsBackgroundColor = combineKeys(configFile.theme, base.colors, 'resultsBackgroundColor');
1255
- configFile.theme.resultsSeparatorColor = combineKeys(configFile.theme, base.colors, 'resultsSeparatorColor');
1256
- configFile.theme.selectedButtonColor = combineKeys(configFile.theme, base.colors, 'selectedButtonColor');
1257
- configFile.theme.selectedColor = combineKeys(configFile.theme, base.colors, 'selectedColor');
1258
- configFile.theme.selectedTextColor = combineKeys(configFile.theme, base.colors, 'selectedTextColor');
1259
- configFile.theme.separatorColor = combineKeys(configFile.theme, base.colors, 'separatorColor');
1260
- configFile.theme.tabsBackgroundColor = combineKeys(configFile.theme, base.colors, 'tabsBackgroundColor');
1261
- configFile.theme.tabsBackgroundSelectedColor = combineKeys(configFile.theme, base.colors, 'tabsBackgroundSelectedColor');
1262
- configFile.theme.textColor = combineKeys(configFile.theme, base.colors, 'textColor');
1263
- configFile.theme.tintColor = combineKeys(configFile.theme, base.colors, 'tintColor');
1264
- configFile.theme.titleAttributesColor = combineKeys(configFile.theme, base.colors, 'titleAttributesColor');
1265
- configFile.theme.titleAttributesShadowColor = combineKeys(configFile.theme, base.colors, 'titleAttributesShadowColor');
1266
- configFile.theme.titleColor = combineKeys(configFile.theme, base.colors, 'titleColor');
1267
- configFile.theme.touchFeedbackColor = combineKeys(configFile.theme, base.colors, 'touchFeedbackColor');
1268
- configFile.theme.viewShadowColor = combineKeys(configFile.theme, base.colors, 'viewShadowColor');
1269
-
1270
- // !Some final cleanup
1271
- delete configFile.theme.extend;
1272
- delete configFile.theme.colors;
1273
- delete configFile.theme.spacing;
1274
-
1275
- if (!Object.keys(configFile.theme.fontFamily).length) {
1276
- delete configFile.theme.fontFamily;
1277
- }
1278
-
1279
- // convert Object to Array
1280
- let corePlugins = Array.isArray(configFile.corePlugins) ? configFile.corePlugins : Object.keys(configFile.corePlugins).map(key => key);
1281
- // !Delete corePlugins specified in the config file
1282
- _.each(corePlugins, value => {
1283
- delete configFile.theme[value];
1284
- });
1285
-
1286
- let tailwindStyles = fs.readFileSync(path.resolve(__dirname, './lib/templates/tailwind/template.tss'), 'utf8');
1287
- tailwindStyles += fs.readFileSync(path.resolve(__dirname, './lib/templates/tailwind/custom-template.tss'), 'utf8');
1288
- tailwindStyles += (iAmInProjectFolder) ? `// config.js file updated on: ${getFileUpdatedDate(projectConfigJS)}\n` : `// default config.js file\n`;
1289
- tailwindStyles += '\n// Custom Styles and Resets\n';
1290
-
1291
- _.each(configFile.theme, (value, key) => {
1292
- tailwindStyles += helperToBuildCustomTailwindClasses(key, value);
1293
- });
1294
-
1295
- let finalTailwindStyles = helpers.applyProperties(tailwindStyles);
1296
-
1297
- if (iAmInProjectFolder) {
1298
- fs.writeFileSync(projectTailwindTSS, finalTailwindStyles);
1299
- logger.info(chalk.yellow('./purgetss/tailwind.tss'), message);
1300
- } else {
1301
- fs.writeFileSync(srcTailwindTSS, finalTailwindStyles);
1302
- logger.info(chalk.yellow('./dist/tailwind.tss'), message);
1303
- }
1304
- }
1305
- module.exports.buildCustomTailwind = buildCustomTailwind;
1306
-
1307
- function createDefinitionsFile() {
1308
- let classDefinitions = '';
1309
-
1310
- if (fs.existsSync(projectTailwindTSS)) {
1311
- classDefinitions += fs.readFileSync(projectTailwindTSS, 'utf8');
1312
- }
1313
-
1314
- if (fs.existsSync(cwd + '/purgetss/fonts.tss')) {
1315
- classDefinitions += fs.readFileSync(cwd + '/purgetss/fonts.tss', 'utf8').replace(/\n\/\*\*\n([\s\S]*?)\*\/\n/g, '');
1316
- }
1317
-
1318
- if (fs.existsSync(projecrFontAwesomeTSS)) {
1319
- classDefinitions += fs.readFileSync(projecrFontAwesomeTSS, 'utf8');
1320
- }
1321
-
1322
- classDefinitions = classDefinitions
1323
- .replace(`'ImageView[platform=ios]': { hires: true }\n`, '')
1324
- .replace(`'View': { width: Ti.UI.SIZE, height: Ti.UI.SIZE }\n`, '')
1325
- .replace(`'Window': { backgroundColor: '#ffffff' }\n\n`, '')
1326
- .replace(/'.(.*)': /g, '.$1')
1327
- .replace(/{(.*)}/g, '{}')
1328
- .replace(/\[(.*)\]/g, '')
1329
- .replace(/\/\/(.*)\n/g, '')
1330
- .replace(/\n\n/g, '\n');
1331
-
1332
- fs.writeFileSync(cwd + '/purgetss/definitions.css', `/* Class definitions */${classDefinitions}`);
1333
-
1334
- logger.file('./purgetss/definitions.css');
1335
- }
1336
-
1337
- //! Build tailwind's custom values
1338
- function helperToBuildCustomTailwindClasses(key, value) {
1339
- switch (key) {
1340
- case 'accessibilityHidden':
1341
- case 'activeIconIsMask':
1342
- case 'activeTintColor':
1343
- case 'activeTitleColor':
1344
- case 'activityEnterTransition':
1345
- case 'activityExitTransition':
1346
- case 'activityIndicatorStyle':
1347
- case 'activityReenterTransition':
1348
- case 'activityReturnTransition':
1349
- case 'activitySharedElementEnterTransition':
1350
- case 'activitySharedElementExitTransition':
1351
- case 'activitySharedElementReenterTransition':
1352
- case 'activitySharedElementReturnTransition':
1353
- case 'alertDialogStyle':
1354
- case 'allowsMultipleSelectionDuringEditing':
1355
- case 'allowsMultipleSelectionInteraction':
1356
- case 'allowsSelection':
1357
- case 'allowsSelectionDuringEditing':
1358
- case 'allowUserCustomization':
1359
- case 'animationStyle':
1360
- case 'autoAdjustScrollViewInsets':
1361
- case 'autocapitalization':
1362
- case 'autocorrect':
1363
- case 'autofillType':
1364
- case 'autoLink':
1365
- case 'autoreverse':
1366
- case 'backgroundBlendMode':
1367
- case 'backgroundColor':
1368
- case 'backgroundGradient':
1369
- case 'backgroundLinearGradient':
1370
- case 'backgroundRadialGradient':
1371
- case 'backgroundRepeat':
1372
- case 'backgroundSelectedColor':
1373
- case 'barColor':
1374
- case 'borderColor':
1375
- case 'borderRadius':
1376
- case 'borderStyle':
1377
- case 'borderWidth':
1378
- case 'bottomNavigation':
1379
- case 'bubbleParent':
1380
- case 'buttonStyle':
1381
- case 'cacheSize':
1382
- case 'canDelete':
1383
- case 'canScroll':
1384
- case 'caseInsensitiveSearch':
1385
- case 'clipMode':
1386
- case 'currentPageIndicatorColor':
1387
- case 'defaultItemTemplate':
1388
- case 'dimBackgroundForSearch':
1389
- case 'disableBounce':
1390
- case 'disabledColor':
1391
- case 'displayCaps':
1392
- case 'displayHomeAsUp':
1393
- case 'displayUtilities':
1394
- case 'draggingConstraints':
1395
- case 'draggingType':
1396
- case 'drawerIndicatorEnabled':
1397
- case 'drawerLockMode':
1398
- case 'dropShadow':
1399
- case 'dropShadowColor':
1400
- case 'editable':
1401
- case 'editing':
1402
- case 'elevation':
1403
- case 'ellipsize':
1404
- case 'enableCopy':
1405
- case 'enabled':
1406
- case 'enableReturnKey':
1407
- case 'enableZoomControls':
1408
- case 'exitOnClose':
1409
- case 'extendBackground':
1410
- case 'extendEdges':
1411
- case 'extendSafeArea':
1412
- case 'fastScroll':
1413
- case 'filterAnchored':
1414
- case 'filterAttribute':
1415
- case 'filterCaseInsensitive':
1416
- case 'flagSecure':
1417
- case 'flip':
1418
- case 'fontFamily':
1419
- case 'fontSize':
1420
- case 'fontStyle':
1421
- case 'fontWeight':
1422
- case 'footerDividersEnabled':
1423
- case 'fullscreen':
1424
- case 'gap':
1425
- case 'gridColumnsStartEnd':
1426
- case 'gridFlow':
1427
- case 'gridSystem':
1428
- case 'headerDividersEnabled':
1429
- case 'height':
1430
- case 'hidesBackButton':
1431
- case 'hidesBarsOnSwipe':
1432
- case 'hidesBarsOnTap':
1433
- case 'hidesBarsWhenKeyboardAppears':
1434
- case 'hideSearchOnSelection':
1435
- case 'hideShadow':
1436
- case 'hidesSearchBarWhenScrolling':
1437
- case 'hintTextColor':
1438
- case 'hires':
1439
- case 'homeButtonEnabled':
1440
- case 'homeIndicatorAutoHidden':
1441
- case 'html':
1442
- case 'iconified':
1443
- case 'iconifiedByDefault':
1444
- case 'iconIsMask':
1445
- case 'includeOpaqueBars':
1446
- case 'indicatorColor':
1447
- case 'items':
1448
- case 'keepScreenOn':
1449
- case 'keepSectionsInSearch':
1450
- case 'keyboardAppearance':
1451
- case 'keyboardDismissMode':
1452
- case 'keyboardType':
1453
- case 'largeTitleDisplayMode':
1454
- case 'largeTitleEnabled':
1455
- case 'layout':
1456
- case 'lazyLoadingEnabled':
1457
- case 'leftDrawerLockMode':
1458
- case 'leftWidth':
1459
- case 'listViewStyle':
1460
- case 'loginKeyboardType':
1461
- case 'loginReturnKeyType':
1462
- case 'margin':
1463
- case 'maxElevation':
1464
- case 'maxRowHeight':
1465
- case 'minRowHeight':
1466
- case 'modal':
1467
- case 'moveable':
1468
- case 'moving':
1469
- case 'navBarHidden':
1470
- case 'navTintColor':
1471
- case 'opacity':
1472
- case 'orientationModes':
1473
- case 'origin':
1474
- case 'overlayEnabled':
1475
- case 'overScrollMode':
1476
- case 'padding':
1477
- case 'pageIndicatorColor':
1478
- case 'pagingControl':
1479
- case 'pagingControlAlpha':
1480
- case 'pagingControlColor':
1481
- case 'pagingControlHeight':
1482
- case 'pagingControlOnTop':
1483
- case 'pagingControlTimeout':
1484
- case 'passwordKeyboardType':
1485
- case 'pickerType':
1486
- case 'placement':
1487
- case 'preventCornerOverlap':
1488
- case 'preventDefaultImage':
1489
- case 'previewActionStyle':
1490
- case 'progressBarStyle':
1491
- case 'progressIndicatorCancelable':
1492
- case 'progressIndicatorCancelOnTouchOutside':
1493
- case 'progressIndicatorLocation':
1494
- case 'progressIndicatorType':
1495
- case 'pruneSectionsOnEdit':
1496
- case 'repeat':
1497
- case 'requestOrientation':
1498
- case 'resultsBackgroundColor':
1499
- case 'resultsSeparatorColor':
1500
- case 'resultsSeparatorStyle':
1501
- case 'returnKeyType':
1502
- case 'rightDrawerLockMode':
1503
- case 'rightWidth':
1504
- case 'rotate':
1505
- case 'rowAndColumnCount':
1506
- case 'rowHeight':
1507
- case 'scale':
1508
- case 'scrollable':
1509
- case 'scrollableRegion':
1510
- case 'scrollIndicators':
1511
- case 'scrollIndicatorStyle':
1512
- case 'scrollingEnabled':
1513
- case 'scrollsToTop':
1514
- case 'scrollType':
1515
- case 'searchAsChild':
1516
- case 'searchBarStyle':
1517
- case 'searchHidden':
1518
- case 'sectionHeaderTopPadding':
1519
- case 'selectedButtonColor':
1520
- case 'selectedColor':
1521
- case 'selectedTextColor':
1522
- case 'selectionStyle':
1523
- case 'separatorColor':
1524
- case 'separatorHeight':
1525
- case 'separatorStyle':
1526
- case 'shadow':
1527
- case 'shadowRadius':
1528
- case 'shiftMode':
1529
- case 'showAsAction':
1530
- case 'showBookmark':
1531
- case 'showCancel':
1532
- case 'showSearchBarInNavBar':
1533
- case 'showSelectionCheck':
1534
- case 'showVerticalScrollIndicator':
1535
- case 'smoothScrollOnTabClick':
1536
- case 'statusBarStyle':
1537
- case 'submitEnabled':
1538
- case 'sustainedPerformanceMode':
1539
- case 'swipeToClose':
1540
- case 'switchStyle':
1541
- case 'systemButton':
1542
- case 'tabBarHidden':
1543
- case 'tabbedBarStyle':
1544
- case 'tabGroupStyle':
1545
- case 'tableViewStyle':
1546
- case 'tabsBackgroundColor':
1547
- case 'tabsBackgroundSelectedColor':
1548
- case 'tabsTranslucent':
1549
- case 'textAlign':
1550
- case 'textColor':
1551
- case 'theme':
1552
- case 'tiMedia':
1553
- case 'tintColor':
1554
- case 'titleAttributesColor':
1555
- case 'titleAttributesShadow':
1556
- case 'titleAttributesShadowColor':
1557
- case 'titleColor':
1558
- case 'toolbarEnabled':
1559
- case 'touchEnabled':
1560
- case 'touchFeedback':
1561
- case 'touchFeedbackColor':
1562
- case 'transition':
1563
- case 'transitionDelay':
1564
- case 'transitionDuration':
1565
- case 'translucent':
1566
- case 'useCompatPadding':
1567
- case 'useSpinner':
1568
- case 'verticalAlign':
1569
- case 'viewShadow':
1570
- case 'viewShadowColor':
1571
- case 'width':
1572
- case 'willScrollOnStatusTap':
1573
- case 'windowPixelFormat':
1574
- case 'windowSoftInputMode':
1575
- case 'wobble':
1576
- case 'zIndex':
1577
- return helpers[key](value);
1578
-
1579
- default: return helpers.customRules(value, key);
1580
- }
1581
- }
1582
-
1583
- function combineKeys(values, base, key) {
1584
- return (values[key]) ? { ...values[key], ...values.extend[key] } : { ...base, ...values.extend[key] };
1585
- }
1586
-
1587
- function extractClasses(currentText, currentFile) {
1588
- try {
1589
- let jsontext = convert.xml2json(encodeHTML(currentText), { compact: true });
1590
-
1591
- return traverse(JSON.parse(jsontext)).reduce(function(acc, value) {
1592
- if (this.key === 'class' || this.key === 'id') acc.push(value.split(' '));
1593
- return acc;
1594
- }, []);
1595
- } catch (error) {
1596
- throw chalk.red(`::PurgeTSS:: Error processing: “${currentFile}”`);
1597
- }
1598
- }
1599
-
1600
- function extractOnlyClasses(currentText, currentFile) {
1601
- try {
1602
- let jsontext = convert.xml2json(encodeHTML(currentText), { compact: true });
1603
-
1604
- return traverse(JSON.parse(jsontext)).reduce(function(acc, value) {
1605
- if (this.key === 'class') acc.push(value.split(' '));
1606
- return acc;
1607
- }, []);
1608
- } catch (error) {
1609
- throw chalk.red(`::PurgeTSS:: Error processing: “${currentFile}”`);
1610
- }
1611
- }
1612
-
1613
- function encodeHTML(str) {
1614
- const code = {
1615
- '&': '&amp;',
1616
- };
1617
- return str.replace(/[&]/gm, i => code[i]);
1618
- }
1619
-
1620
- function callback(err) {
1621
- if (err) throw err;
1622
- }
1623
-
1624
- function readAllXMLFiles(currentDirPath, callback) {
1625
- let files = fs.readdirSync(currentDirPath);
1626
-
1627
- files.filter(junk.not).forEach(name => {
1628
- let filePath = path.join(currentDirPath, name);
1629
-
1630
- let stat = fs.statSync(filePath);
1631
-
1632
- if (stat.isFile()) {
1633
- if (name.includes('xml')) {
1634
- callback(filePath, stat);
1635
- }
1636
- } else if (stat.isDirectory()) {
1637
- readAllXMLFiles(filePath, callback);
1638
- }
1639
- });
1640
- }
1641
-
1642
- //! Copy Fonts
1643
- function copyFont(vendor) {
1644
- makeSureFolderExists(projectFontsFolder);
1645
-
1646
- switch (vendor) {
1647
- case 'fa':
1648
- case 'font':
1649
- case 'fontawesome':
1650
- if (fs.existsSync(srcFontAwesomeBetaCSSFile)) {
1651
- copyProFonts(srcFontAwesomeBetaFontFamilies, srcFontAwesomeBetaWebFontsFolder);
1652
- } else if (fs.existsSync(srcFontAwesomeProCSSFile)) {
1653
- copyProFonts(srcFontAwesomeProFontFamilies, srcFontAwesomeProWebFontsFolder);
1654
- } else {
1655
- copyFreeFonts();
1656
- }
1657
- break;
1658
- case 'md':
1659
- case 'material':
1660
- case 'materialdesign':
1661
- copyMaterialDesignFonts();
1662
- break;
1663
- case 'f7':
1664
- case 'framework':
1665
- case 'framework7':
1666
- copyFramework7IconsFonts();
1667
- break;
1668
- }
1669
- }
1670
-
1671
- //! Copy Font Libraries
1672
- function copyFontLibrary(vendor) {
1673
- switch (vendor) {
1674
- case 'fa':
1675
- case 'font':
1676
- case 'fontawesome':
1677
- if (fs.existsSync(srcFontAwesomeBetaCSSFile) || fs.existsSync(srcFontAwesomeProCSSFile)) {
1678
- buildCustomFontAwesomeJS();
1679
- } else {
1680
- fs.copyFileSync(srcLibFA, projectLibFolder + '/fontawesome.js');
1681
- logger.info('FontAwesome CommonJS module copied to', chalk.yellow('./app/lib'), 'folder');
1682
- }
1683
- break;
1684
- case 'md':
1685
- case 'material':
1686
- case 'materialdesign':
1687
- fs.copyFileSync(srcLibMD, projectLibFolder + '/materialdesignicons.js');
1688
- logger.info('Material Design CommonJS module copied to', chalk.yellow('./app/lib'), 'folder');
1689
- break;
1690
- case 'f7':
1691
- case 'framework':
1692
- case 'framework7':
1693
- fs.copyFileSync(srcLibF7, projectLibFolder + '/framework7icons.js');
1694
- logger.info('Framework7-Icons CommonJS module copied to', chalk.yellow('./app/lib'), 'folder');
1695
- break;
1696
- }
1697
- }
1698
-
1699
- //! Check if running inside an Alloy Project
1700
- function alloyProject() {
1701
- if (!fs.existsSync(cwd + '/app/views')) {
1702
- logger.error('Please make sure you’re running PurgeTSS inside an Alloy Project.');
1703
-
1704
- return false;
1705
- }
1706
-
1707
- return true;
1708
- }
1709
-
1710
- //! FIRST: Backup original app.tss
1711
- function backupOriginalAppTss() {
1712
- if (!fs.existsSync(project_AppTSS) && fs.existsSync(projectAppTSS)) {
1713
- logger.warn('Backing up app.tss into _app.tss\n FROM NOW ON, add, update or delete your original classes in _app.tss');
1714
- fs.copyFileSync(projectAppTSS, project_AppTSS);
1715
- } else if (!fs.existsSync(project_AppTSS)) {
1716
- fs.appendFileSync(project_AppTSS, '// Empty _app.tss\n');
1717
- }
1718
- }
1719
-
1720
- //! Copy Reset template
1721
- function copyResetTemplateAnd_appTSS() {
1722
- logger.info('Copying Reset styles...');
1723
-
1724
- let tempPurged = fs.readFileSync(srcResetTSSFile, 'utf8');
1725
-
1726
- if (fs.existsSync(project_AppTSS)) {
1727
- let appTSSContent = fs.readFileSync(project_AppTSS, 'utf8');
1728
-
1729
- if (appTSSContent.length) {
1730
- logger.info('Copying', chalk.yellow('_app.tss'), 'styles...');
1731
- tempPurged += '\n// Styles from _app.tss\n' + appTSSContent;
1732
- }
1733
- }
1734
-
1735
- return tempPurged;
1736
- }
1737
-
1738
- let startTime;
1739
-
1740
- function start() {
1741
- startTime = new Date();
1742
- };
1743
-
1744
- function finish(customMessage = 'Finished purging in') {
1745
- let endTime = new Date(new Date() - startTime);
1746
- logger.info(customMessage, chalk.green(`${endTime.getSeconds()}s ${endTime.getMilliseconds()}ms`));
1747
- }
1748
-
1749
- //! Purge Functions
1750
- //! Tailwind
1751
- function purgeTailwind(uniqueClasses) {
1752
- let purgedClasses = '\n// Main styles\n';
1753
- let tailwindClasses = fs.readFileSync(projectTailwindTSS, 'utf8').split(/\r?\n/);
1754
-
1755
- if (`// config.js file updated on: ${getFileUpdatedDate(projectConfigJS)}` !== tailwindClasses[6]) {
1756
- logger.info(chalk.yellow('config.js'), 'file updated!, rebuilding tailwind.tss...');
1757
- buildCustomTailwind('file updated!');
1758
- tailwindClasses = fs.readFileSync(projectTailwindTSS, 'utf8').split(/\r?\n/);
1759
- }
1760
-
1761
- logger.info('Purging', chalk.yellow('Custom Tailwind'), 'styles...')
1762
-
1763
- let cleanUniqueClasses = [];
1764
- let classesWithOpacityValues = [];
1765
-
1766
- let arbitraryValues = '\n// Styles with arbitrary values\n';
1767
-
1768
- uniqueClasses.forEach((className, index) => {
1769
- let cleanClassName = cleanClassNameFn(className);
1770
-
1771
- if (cleanClassName.includes('(')) {
1772
- let line = helpers.formatArbitraryValues(cleanClassName, fromXMLs = true);
1773
- if (line) arbitraryValues += helpers.checkPlatformAndDevice(line, className);
1774
- } else if (helpers.checkColorClasses(cleanClassName)) {
1775
- let decimalValue = cleanClassName.split('/')[1];
1776
- let transparency = Math.round(decimalValue * 255 / 100).toString(16);
1777
- if (transparency.length === 1) transparency = '0' + transparency;
1778
- let classNameWithTransparency = uniqueClasses[index];
1779
- let className = cleanClassName.substring(0, cleanClassName.lastIndexOf('/'));
1780
- classesWithOpacityValues.push({ decimalValue, transparency, className, classNameWithTransparency });
1781
- } else {
1782
- cleanUniqueClasses.push(className);
1783
- }
1784
- });
1785
-
1786
- let anArrayOfClasses = [];
1787
- tailwindClasses.forEach(tailwindClass => {
1788
- if (tailwindClass !== '' && !tailwindClass.includes('//')) {
1789
- let cleanTailwindClass = `${tailwindClass.split(':')[0].replace('.', '').replace(/'/g, '').replace(/ *\[[^\]]*]/, '')}`;
1790
-
1791
- if (cleanUniqueClasses.indexOf(cleanTailwindClass) > -1) {
1792
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(cleanTailwindClass)]));
1793
- }
1794
-
1795
- if (cleanUniqueClasses.indexOf(`ios:${cleanTailwindClass}`) > -1) {
1796
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`ios:${cleanTailwindClass}`)]));
1797
- }
1798
-
1799
- if (cleanUniqueClasses.indexOf(`android:${cleanTailwindClass}`) > -1) {
1800
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`android:${cleanTailwindClass}`)]));
1801
- }
1802
-
1803
- if (cleanUniqueClasses.indexOf(`tablet:${cleanTailwindClass}`) > -1) {
1804
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`tablet:${cleanTailwindClass}`)]));
1805
- }
1806
-
1807
- if (cleanUniqueClasses.indexOf(`handheld:${cleanTailwindClass}`) > -1) {
1808
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`handheld:${cleanTailwindClass}`)]));
1809
- }
1810
-
1811
- if (cleanUniqueClasses.indexOf(`open:${cleanTailwindClass}`) > -1) {
1812
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`open:${cleanTailwindClass}`)]));
1813
- }
1814
-
1815
- if (cleanUniqueClasses.indexOf(`close:${cleanTailwindClass}`) > -1) {
1816
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`close:${cleanTailwindClass}`)]));
1817
- }
1818
-
1819
- if (cleanUniqueClasses.indexOf(`drag:${cleanTailwindClass}`) > -1) {
1820
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`drag:${cleanTailwindClass}`)]));
1821
- }
1822
-
1823
- if (cleanUniqueClasses.indexOf(`drop:${cleanTailwindClass}`) > -1) {
1824
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`drop:${cleanTailwindClass}`)]));
1825
- }
1826
-
1827
- if (cleanUniqueClasses.indexOf(`complete:${cleanTailwindClass}`) > -1) {
1828
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`complete:${cleanTailwindClass}`)]));
1829
- }
1830
-
1831
- if (cleanUniqueClasses.indexOf(`bounds:${cleanTailwindClass}`) > -1) {
1832
- anArrayOfClasses.push(helpers.checkPlatformAndDevice(tailwindClass, cleanUniqueClasses[cleanUniqueClasses.indexOf(`bounds:${cleanTailwindClass}`)]));
1833
- }
1834
- }
1835
- });
1836
-
1837
- purgedClasses += anArrayOfClasses.join('');
1838
-
1839
- // Styles with color opacity modifiers
1840
- if (classesWithOpacityValues.length > 0) {
1841
- purgedClasses += '\n// Styles with color opacity modifiers\n';
1842
- classesWithOpacityValues.forEach(opacityValue => {
1843
- let opacityIndex = _.findIndex(tailwindClasses, line => line.startsWith(`'.${opacityValue.className}`));
1844
-
1845
- if (opacityIndex > -1) {
1846
- let defaultHexValue;
1847
- if (tailwindClasses[opacityIndex].includes('from')) {
1848
- defaultHexValue = tailwindClasses[opacityIndex].match(/\#[0-9a-f]{6}/g)[1];
1849
- } else {
1850
- defaultHexValue = tailwindClasses[opacityIndex].match(/\#[0-9a-f]{6}/i)[0];
1851
- }
1852
-
1853
- let classWithoutDecimalOpacity = `${tailwindClasses[opacityIndex].replace(new RegExp(defaultHexValue.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), `#${opacityValue.transparency}${defaultHexValue.substring(1)}`)}`;
1854
- let defaultTextValue = tailwindClasses[opacityIndex].match(/'[^']*'/i)[0];
1855
- defaultTextValue = defaultTextValue.substring(1, defaultTextValue.length);
1856
- let finalClassName = `${classWithoutDecimalOpacity.replace(defaultTextValue, `.${defaultTextValue.substring(1, defaultTextValue.length - 1)}/${opacityValue.decimalValue}'`)}`;
1857
- let withPlatformDeviceStyle = helpers.checkPlatformAndDevice(finalClassName, opacityValue.classNameWithTransparency);
1858
-
1859
- // !Move platform specific styles to the end of the class name
1860
- let platformIndex = withPlatformDeviceStyle.search(/\[platform=ios\]|\[platform=android\]/i);
1861
- if (platformIndex > -1) {
1862
- if (withPlatformDeviceStyle.includes('[platform=ios]')) {
1863
- withPlatformDeviceStyle = withPlatformDeviceStyle.replace('[platform=ios]', '').replace(/[^'.][^']+|1/, `$&[platform=ios]`);
1864
- } else {
1865
- withPlatformDeviceStyle = withPlatformDeviceStyle.replace('[platform=android]', '').replace(/[^'.][^']+|1/, `$&[platform=android]`);
1866
- }
1867
- }
1868
-
1869
- purgedClasses += withPlatformDeviceStyle;
1870
- }
1871
- });
1872
- }
1873
-
1874
- // Add arbitrary values
1875
- purgedClasses += (arbitraryValues !== '\n// Styles with arbitrary values\n') ? arbitraryValues : '';
1876
-
1877
- return purgedClasses;
1878
- }
1879
-
1880
- function cleanClassNameFn(className) {
1881
- return className.replace('ios:', '').replace('android:', '').replace('handheld:', '').replace('tablet:', '').replace('open:', '').replace('complete:', '').replace('close:', '').replace('complete:', '').replace('drag:', '').replace('drop:', '').replace('bounds:', '');
1882
- }
1883
-
1884
- //! FontAwesome
1885
- function purgeFontAwesome(uniqueClasses, cleanUniqueClasses) {
1886
- let sourceFolder = '';
1887
- let purgedClasses = '';
1888
- let purgingMessage = '';
1889
-
1890
- if (fs.existsSync(projecrFontAwesomeTSS)) {
1891
- sourceFolder = projecrFontAwesomeTSS;
1892
- purgedClasses = '\n// Pro/Beta Font Awesome styles\n';
1893
- purgingMessage = `Purging ${chalk.yellow('Pro/Beta Font Awesome')} styles...')`;
1894
- } else {
1895
- sourceFolder = srcFontAwesomeTSSFile;
1896
- purgedClasses = '\n// Default Font Awesome styles\n';
1897
- purgingMessage = `Purging Default Font Awesome styles...`;
1898
- }
1899
-
1900
- let sourceTSS = fs.readFileSync(sourceFolder, 'utf8').split(/\r?\n/);
1901
-
1902
- purgedClasses += purgeFontIcons(sourceTSS, uniqueClasses, purgingMessage, cleanUniqueClasses, ['fa', 'fat', 'fas', 'fal', 'far', 'fab', 'fa-thin', 'fa-solid', 'fa-light', 'fa-regular', 'fa-brands', 'fontawesome', 'fontawesome-thin', 'fontawesome-solid', 'fontawesome-light', 'fontawesome-regular', 'fontawesome-brands']);
1903
-
1904
- return (purgedClasses === '\n// Pro/Beta Font Awesome styles\n' || purgedClasses === '\n// Default Font Awesome styles\n') ? '' : purgedClasses;
1905
- }
1906
-
1907
- //! Material Design Icons
1908
- function purgeMaterialDesign(uniqueClasses, cleanUniqueClasses) {
1909
- let purgedClasses = '\n// Material Design Icons styles\n';
1910
-
1911
- let sourceTSS = fs.readFileSync(srcMaterialDesignIconsTSSFile, 'utf8').split(/\r?\n/);
1912
-
1913
- purgedClasses += purgeFontIcons(sourceTSS, uniqueClasses, 'Purging Material Design Icons styles...', cleanUniqueClasses, ['md', 'mdo', 'mdr', 'mds', 'mdt', '.materialdesign', '.materialdesign-round', '.materialdesign-sharp', '.materialdesign-two-tone', '.materialdesign-outlined', '.material-icons', '.material-icons-round', '.material-icons-sharp', '.material-icons-two-tone', '.material-icons-outlined']);
1914
-
1915
- return (purgedClasses === '\n// Material Design Icons styles\n') ? '' : purgedClasses;
1916
- }
1917
-
1918
- //! Framework7
1919
- function purgeFramework7(uniqueClasses, cleanUniqueClasses) {
1920
- let purgedClasses = '\n// Framework7 styles\n';
1921
-
1922
- let sourceTSS = fs.readFileSync(srcFramework7FontTSSFile, 'utf8').split(/\r?\n/);
1923
-
1924
- purgedClasses += purgeFontIcons(sourceTSS, uniqueClasses, 'Purging Framework7 Icons styles...', cleanUniqueClasses, ['f7', 'f7i', 'framework7']);
1925
-
1926
- return (purgedClasses === '\n// Framework7 styles\n') ? '' : purgedClasses;
1927
- }
1928
-
1929
- function purgeFontIcons(sourceTSS, uniqueClasses, message, cleanUniqueClasses, prefixes) {
1930
- let purgedClasses = '';
1931
- let soc = sourceTSS.toString();
1932
-
1933
- if (prefixes.length > 0) {
1934
- if (cleanUniqueClasses.some(element => prefixes.includes(element))) {
1935
- logger.info(message);
1936
- uniqueClasses.forEach(className => {
1937
- let cleanClassName = cleanClassNameFn(className);
1938
- if (soc.includes(`'.${cleanClassName}'`)) {
1939
- sourceTSS.forEach(line => {
1940
- if (line.startsWith(`'.${cleanClassName}'`)) {
1941
- purgedClasses += helpers.checkPlatformAndDevice(line, uniqueClasses[uniqueClasses.indexOf(className)]);
1942
- }
1943
- });
1944
- }
1945
- });
1946
- }
1947
- } else {
1948
- logger.info(message);
1949
- uniqueClasses.forEach(className => {
1950
- let cleanClassName = cleanClassNameFn(className);
1951
- if (soc.includes(`'.${cleanClassName}'`)) {
1952
- sourceTSS.forEach(line => {
1953
- if (line.startsWith(`'.${cleanClassName}'`)) {
1954
- purgedClasses += helpers.checkPlatformAndDevice(line, uniqueClasses[uniqueClasses.indexOf(className)]);
1955
- }
1956
- });
1957
- }
1958
- });
1959
- }
1960
-
1961
- return purgedClasses;
1962
- }
1963
-
1964
- function saveFile(file, data) {
1965
- fs.writeFileSync(file, data, err => {
1966
- throw err;
1967
- });
1968
- }
1969
-
1970
- function createJMKFile() {
1971
- logger.warn(chalk.green('Adding Auto-Purging hook!'));
1972
- fs.copyFileSync(srcJMKFile, projectAlloyJMKFile);
1973
- logger.file('./app/alloy.jmk');
1974
- }
1975
-
1976
- //! Soon to be deleted
1977
- function reviewThis(className) {
1978
- let twStylesWithoyPlatformSpecificStyles = className.replace(/\[platform=ios\]/g, '').replace(/\[platform=android\]/g, '').split(/\r?\n/);
1979
- twStylesArray[indexOfClass].replace('[platform=android]', '').replace('[platform=ios]', '')
1980
- }