@caweb/cli 1.4.3 → 1.4.5
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/README.md +2 -206
- package/commands/index.js +9 -2
- package/commands/test.js +0 -3
- package/commands/webpack/webpack.js +59 -26
- package/configs/webpack.config.js +34 -12
- package/lib/cli.js +65 -38
- package/lib/helpers.js +0 -1
- package/lib/webpack/plugins/a11y/aceconfig.js +44 -0
- package/lib/webpack/plugins/a11y/index.js +272 -0
- package/lib/webpack/plugins/a11y/package.json +12 -0
- package/lib/webpack/plugins/css-audit/css-audit.config.cjs +5 -0
- package/lib/webpack/plugins/css-audit/default.config.js +19 -0
- package/lib/webpack/plugins/css-audit/index.js +297 -0
- package/lib/webpack/plugins/css-audit/package.json +12 -0
- package/lib/webpack/plugins/jshint/.jshintrc +31 -0
- package/lib/webpack/plugins/jshint/index.js +286 -0
- package/lib/webpack/plugins/jshint/package-lock.json +22 -0
- package/lib/webpack/plugins/jshint/package.json +15 -0
- package/lib/webpack/plugins/jshint/reporter.cjs +663 -0
- package/package.json +5 -5
- package/assets/logo.ico +0 -0
- package/commands/a11y.js +0 -95
- package/commands/audit.js +0 -135
- package/configs/aceconfig.js +0 -28
- package/configs/css-audit.config.cjs +0 -9
- package/docs/CREDITS.MD +0 -32
- package/docs/ISSUES.MD +0 -7
- package/docs/OVERRIDES.md +0 -53
- package/docs/ROADMAP.MD +0 -20
- package/docs/SYNC.MD +0 -29
- package/docs/tool/index.js +0 -45
- package/gen/parser.js +0 -166
- package/gen/site-generator.js +0 -144
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
//"use strict";
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const htmlFormat = require('html-format');
|
|
5
|
+
|
|
6
|
+
let sortedReport = {
|
|
7
|
+
errors: [],
|
|
8
|
+
warnings: [],
|
|
9
|
+
info: []
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
let title = process.cwd().split('\\').pop();
|
|
13
|
+
|
|
14
|
+
let output = [];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Adds Head to output.
|
|
18
|
+
*/
|
|
19
|
+
function addHead(){
|
|
20
|
+
|
|
21
|
+
output.push(
|
|
22
|
+
'<head>',
|
|
23
|
+
'<meta charset="UTF-8">',
|
|
24
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1.0">',
|
|
25
|
+
`<title>JSHint Report for ${title}</title>`,
|
|
26
|
+
'<script src="./jshint.js"></script>',
|
|
27
|
+
'<link rel="stylesheet" href="./jshint.css">',
|
|
28
|
+
'</head>'
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Adds Header to output.
|
|
34
|
+
*/
|
|
35
|
+
function addHeader(){
|
|
36
|
+
let navItems = []
|
|
37
|
+
|
|
38
|
+
// add dark mode switch just for fun.
|
|
39
|
+
navItems.push(
|
|
40
|
+
'<li>',
|
|
41
|
+
'<button onclick="cssAudit.toggleDarkMode()" class="btn button__theme-toggle" aria-label="Dark Mode"></button>',
|
|
42
|
+
'</li>'
|
|
43
|
+
);
|
|
44
|
+
// open header and add title
|
|
45
|
+
output.push(
|
|
46
|
+
'<header id="top" class="site__header">',
|
|
47
|
+
`<h1>JSHint Report for ${title}</h1>`,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
// add navigation if items were found
|
|
51
|
+
if( navItems.length ){
|
|
52
|
+
output.push(
|
|
53
|
+
'<nav class="nav">',
|
|
54
|
+
'<ul>',
|
|
55
|
+
...navItems,
|
|
56
|
+
'</ul>',
|
|
57
|
+
'</nav>',
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// close the header.
|
|
62
|
+
output.push(
|
|
63
|
+
'</header>',
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Adds Result Summary to output.
|
|
70
|
+
* @param {Array} results
|
|
71
|
+
*/
|
|
72
|
+
function addSummary(results){
|
|
73
|
+
let items = [];
|
|
74
|
+
|
|
75
|
+
// summary
|
|
76
|
+
results.forEach(function(result) {
|
|
77
|
+
var file = result.file;
|
|
78
|
+
var error = result.error;
|
|
79
|
+
|
|
80
|
+
items.push(
|
|
81
|
+
'<li>',
|
|
82
|
+
`<a href="#${file.replace(/[\\:\.]/g, '-').toLowerCase()}" target="_blank">${file}</a>: line ${error.line}, col ${error.character}, ${error.reason}`,
|
|
83
|
+
'</li>'
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
let summary = [];
|
|
88
|
+
for(let [category] of Object.entries(sortedReport) ){
|
|
89
|
+
if( sortedReport[category].length ){
|
|
90
|
+
let cCase = capitalCase(category);
|
|
91
|
+
// if there is just 1, drop the plural
|
|
92
|
+
if( 1 === sortedReport[category].length ){
|
|
93
|
+
cCase = cCase.slice(0, -1)
|
|
94
|
+
}
|
|
95
|
+
summary.push(`${sortedReport[category].length} ${cCase} Detected`)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
output.push(
|
|
100
|
+
'<section class="hint" id="summary">',
|
|
101
|
+
'<header class="hint__header">',
|
|
102
|
+
`<h2 class="hint__title">Summary: <em>${summary.join(' & ')}</em></h2>`,
|
|
103
|
+
'</header>',
|
|
104
|
+
'<ol>',
|
|
105
|
+
...items,
|
|
106
|
+
'</ol>',
|
|
107
|
+
'</section>'
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Process data
|
|
114
|
+
*
|
|
115
|
+
* Data Object
|
|
116
|
+
* {
|
|
117
|
+
* functions,
|
|
118
|
+
* options,
|
|
119
|
+
* errors,
|
|
120
|
+
* globals,
|
|
121
|
+
* unused,
|
|
122
|
+
* member,
|
|
123
|
+
* file
|
|
124
|
+
* }
|
|
125
|
+
*/
|
|
126
|
+
function addBreakdown({
|
|
127
|
+
functions,
|
|
128
|
+
options,
|
|
129
|
+
errors,
|
|
130
|
+
implieds,
|
|
131
|
+
globals,
|
|
132
|
+
unused,
|
|
133
|
+
member,
|
|
134
|
+
file
|
|
135
|
+
}){
|
|
136
|
+
let functionList = [];
|
|
137
|
+
let errorList = [];
|
|
138
|
+
let unusedList = [];
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Process function data
|
|
142
|
+
*
|
|
143
|
+
* Function Data Object
|
|
144
|
+
* {
|
|
145
|
+
* name,
|
|
146
|
+
* param,
|
|
147
|
+
* line,
|
|
148
|
+
* character,
|
|
149
|
+
* last,
|
|
150
|
+
* lastcharacter,
|
|
151
|
+
* metrics {
|
|
152
|
+
* complexity,
|
|
153
|
+
* parameters,
|
|
154
|
+
* statements
|
|
155
|
+
* }
|
|
156
|
+
* }
|
|
157
|
+
*/
|
|
158
|
+
if( functions ){
|
|
159
|
+
functions.forEach(({ name, param, line, character, metrics }) => {
|
|
160
|
+
let { complexity, parameters, statements } = metrics;
|
|
161
|
+
|
|
162
|
+
functionList.push(
|
|
163
|
+
'<li>',
|
|
164
|
+
`<p><b>Name:</b> ${name}</p>`,
|
|
165
|
+
param && param.length ? `<p><b>Parameters:</b> ${param}</p>` : '',
|
|
166
|
+
`<p><b>Line:</b> ${line}</p>`,
|
|
167
|
+
`<p><b>Col:</b> ${character}</p>`,
|
|
168
|
+
`<p><b>Metrics:</b></p>`,
|
|
169
|
+
'<ul>',
|
|
170
|
+
`<li><b>Cyclomatic Complexity Number:</b> ${complexity}</li>`,
|
|
171
|
+
`<li><b>Arguments:</b> ${parameters}</li>`,
|
|
172
|
+
`<li><b>Statements:</b> ${statements}</li>`,
|
|
173
|
+
'</ul>',
|
|
174
|
+
'</li>'
|
|
175
|
+
)
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Process error data
|
|
182
|
+
*
|
|
183
|
+
* Error Data Object
|
|
184
|
+
* {
|
|
185
|
+
* id,
|
|
186
|
+
* raw,
|
|
187
|
+
* code,
|
|
188
|
+
* evidence,
|
|
189
|
+
* line,
|
|
190
|
+
* character,
|
|
191
|
+
* scope,
|
|
192
|
+
* a,
|
|
193
|
+
* b,
|
|
194
|
+
* c,
|
|
195
|
+
* d,
|
|
196
|
+
* reason
|
|
197
|
+
* }
|
|
198
|
+
*/
|
|
199
|
+
if( errors ){
|
|
200
|
+
errors.forEach(({reason, evidence, line, character}) => {
|
|
201
|
+
errorList.push(
|
|
202
|
+
'<li>',
|
|
203
|
+
`<p><b>Reason:</b> ${reason}</p>`,
|
|
204
|
+
`<p><b>Evidence:</b> ${evidence}</p>`,
|
|
205
|
+
`<p><b>Line:</b> ${line}</p>`,
|
|
206
|
+
`<p><b>Col:</b> ${character}</p>`,
|
|
207
|
+
'</li>'
|
|
208
|
+
)
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Unused Data
|
|
214
|
+
* {
|
|
215
|
+
* name,
|
|
216
|
+
* line,
|
|
217
|
+
* character
|
|
218
|
+
* }
|
|
219
|
+
*/
|
|
220
|
+
if( unused ){
|
|
221
|
+
unused.forEach(({name, line, character}) => {
|
|
222
|
+
unusedList.push(
|
|
223
|
+
'<li>',
|
|
224
|
+
`<p><b>Name:</b> ${name}</p>`,
|
|
225
|
+
`<p><b>Line:</b> ${line}</p>`,
|
|
226
|
+
`<p><b>Col:</b> ${character}</p>`,
|
|
227
|
+
'</li>'
|
|
228
|
+
)
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
output.push(
|
|
233
|
+
`<section id="${file.replace(/[\\:\.]/g, '-').toLowerCase()}" class="hint">`,
|
|
234
|
+
'<header class="hint__header">',
|
|
235
|
+
`<h2 class="hint__title"><a href="${file}" class="link" target="_blank"></a>File: <em>${file}</em></h2>`,
|
|
236
|
+
'<a class="btn back-to-top" href="#top" title="Back to top">⬆</a>',
|
|
237
|
+
'</header>',
|
|
238
|
+
`<h3>Functions: <span class="count">${functions.length}</span></h3>`,
|
|
239
|
+
functionList.length ? `<ol>${functionList.join('\n')}</ol>` : '',
|
|
240
|
+
`<h3>Errors: <span class="count">${errors ? errors.length : 0}</span></h3>`,
|
|
241
|
+
errorList.length ? `<ol>${errorList.join('\n')}</ol>` : '',
|
|
242
|
+
`<h3>Unused: <span class="count">${unused ? unused.length : 0}</span></h3>`,
|
|
243
|
+
unusedList.length ? `<ol>${unusedList.join('\n')}</ol>` : '',
|
|
244
|
+
'</section>'
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Add file list sidebar
|
|
250
|
+
*/
|
|
251
|
+
function addSidebar(data){
|
|
252
|
+
let fileList = [];
|
|
253
|
+
|
|
254
|
+
data.forEach(({file}) => {
|
|
255
|
+
fileList.push(
|
|
256
|
+
`<li><a href="#${ file.replace(/[\\:\.]/g, '-').toLowerCase() }">${file}</a></li>`
|
|
257
|
+
)
|
|
258
|
+
})
|
|
259
|
+
output.push(
|
|
260
|
+
'<aside>',
|
|
261
|
+
'<section>',
|
|
262
|
+
'<header class="hint__header"><h2 class="hint__title">Files</h2></header>',
|
|
263
|
+
'<ol>',
|
|
264
|
+
fileList.join('\n'),
|
|
265
|
+
'</section>',
|
|
266
|
+
'</ol>',
|
|
267
|
+
'</aside>'
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* JSHint Reporter
|
|
273
|
+
*
|
|
274
|
+
* @param {*} results
|
|
275
|
+
* @param {*} data
|
|
276
|
+
* @param {*} opts
|
|
277
|
+
*/
|
|
278
|
+
function reporter(results, data, opts){
|
|
279
|
+
let outputFolder = process.env.JSHINT_OUTPUT_DIR ?
|
|
280
|
+
path.resolve( process.env.JSHINT_OUTPUT_DIR ) :
|
|
281
|
+
path.join(__dirname, 'public')
|
|
282
|
+
let outputFilename = path.join(outputFolder, `${process.env.JSHINT_OUTPUT_FILENAME ?? 'jshint'}.html` );
|
|
283
|
+
|
|
284
|
+
// process results.
|
|
285
|
+
results.forEach((result) => {
|
|
286
|
+
var file = result.file;
|
|
287
|
+
var error = result.error;
|
|
288
|
+
|
|
289
|
+
// add error to sorted report array
|
|
290
|
+
switch( error.code.charAt(0) ){
|
|
291
|
+
case 'E': // errors
|
|
292
|
+
sortedReport.errors.push({...error, file: file})
|
|
293
|
+
break;
|
|
294
|
+
case 'I': // info
|
|
295
|
+
sortedReport.info.push({...error, file: file})
|
|
296
|
+
break;
|
|
297
|
+
case 'W': // warnings
|
|
298
|
+
sortedReport.warnings.push({...error, file: file})
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
try{
|
|
304
|
+
|
|
305
|
+
// Add Head Section.
|
|
306
|
+
addHead();
|
|
307
|
+
|
|
308
|
+
// Add Header Section.
|
|
309
|
+
addHeader();
|
|
310
|
+
|
|
311
|
+
output.push ('<div id="main">');
|
|
312
|
+
|
|
313
|
+
addSidebar(data);
|
|
314
|
+
|
|
315
|
+
output.push ('<div id="information">');
|
|
316
|
+
|
|
317
|
+
// Add Summary.
|
|
318
|
+
addSummary(results);
|
|
319
|
+
|
|
320
|
+
// process data.
|
|
321
|
+
data.forEach((d) => {
|
|
322
|
+
/*
|
|
323
|
+
Only used to see what the data is passing
|
|
324
|
+
for(let [prop, value] of Object.entries(d) ){
|
|
325
|
+
output.push(prop)
|
|
326
|
+
output.push('object' == typeof value ? value[0] : value)
|
|
327
|
+
output.push('<br />')
|
|
328
|
+
}
|
|
329
|
+
*/
|
|
330
|
+
addBreakdown(d)
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
output.push (
|
|
334
|
+
'</div> <!-- Close information div -->',
|
|
335
|
+
'</div> <!-- Close main div -->'
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
}catch(err){
|
|
339
|
+
process.stderr.write(err.toString())
|
|
340
|
+
process.exit(1)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// wrap the output in html tags.
|
|
344
|
+
output = ['<html>', ...output, '</html>']
|
|
345
|
+
|
|
346
|
+
fs.mkdirSync( outputFolder, {recursive: true} );
|
|
347
|
+
|
|
348
|
+
// write html file
|
|
349
|
+
fs.writeFileSync(
|
|
350
|
+
outputFilename,
|
|
351
|
+
htmlFormat(output.join('\n')," ".repeat(4), 250)
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
// write jshint.js file.
|
|
355
|
+
fs.writeFileSync(
|
|
356
|
+
path.join(outputFolder, 'jshint.js'),
|
|
357
|
+
jsContent()
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
// write jshint.css file.
|
|
361
|
+
fs.writeFileSync(
|
|
362
|
+
path.join(outputFolder, 'jshint.css'),
|
|
363
|
+
cssContent()
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
// console.log( htmlFormat(output.join('\n')," ".repeat(4), 250) );
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function capitalCase(str){
|
|
370
|
+
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Returns string content for css file
|
|
375
|
+
* @returns string
|
|
376
|
+
*/
|
|
377
|
+
function cssContent(){
|
|
378
|
+
return `
|
|
379
|
+
/*
|
|
380
|
+
* JSHint
|
|
381
|
+
*/
|
|
382
|
+
body {
|
|
383
|
+
--body-margin: 2rem;
|
|
384
|
+
|
|
385
|
+
/* Body colours */
|
|
386
|
+
--body-bg: #fff;
|
|
387
|
+
--body-fg: #111;
|
|
388
|
+
|
|
389
|
+
/* Nav & link colours */
|
|
390
|
+
--nav-bg: #eee;
|
|
391
|
+
--nav-bg-hover: #bbb;
|
|
392
|
+
--nav-fg: #11c;
|
|
393
|
+
|
|
394
|
+
/* Heading colours */
|
|
395
|
+
--h-fg: #222;
|
|
396
|
+
--h-bg: #eee;
|
|
397
|
+
|
|
398
|
+
/* Border style for bordered components */
|
|
399
|
+
--component-border: 1px solid #aaa;
|
|
400
|
+
|
|
401
|
+
/* Consistent component margins */
|
|
402
|
+
--component-margin-sm: 1.5rem;
|
|
403
|
+
--component-margin-lg: 3rem;
|
|
404
|
+
|
|
405
|
+
/* Colour chips */
|
|
406
|
+
--count-bg: #eee;
|
|
407
|
+
--count-border: var(--component-border);
|
|
408
|
+
}
|
|
409
|
+
/*
|
|
410
|
+
* Dark mode
|
|
411
|
+
*/
|
|
412
|
+
body.is-dark-mode {
|
|
413
|
+
/* Body colours */
|
|
414
|
+
--body-bg: #111;
|
|
415
|
+
--body-fg: #fff;
|
|
416
|
+
|
|
417
|
+
/* Nav & link colours */
|
|
418
|
+
--nav-bg: #444;
|
|
419
|
+
--nav-bg-hover: #222;
|
|
420
|
+
--nav-fg: #bcf;
|
|
421
|
+
|
|
422
|
+
/* Heading colours */
|
|
423
|
+
--h-fg: #eee;
|
|
424
|
+
--h-bg: #222;
|
|
425
|
+
|
|
426
|
+
/* Border style for bordered components */
|
|
427
|
+
--component-border: 1px solid #666;
|
|
428
|
+
|
|
429
|
+
/* Consistent component margins */
|
|
430
|
+
--component-margin-sm: 1.5rem;
|
|
431
|
+
--component-margin-lg: 3rem;
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
/* Colour chips */
|
|
435
|
+
--count-bg: #111;
|
|
436
|
+
--count-border: var(--component-border);
|
|
437
|
+
}
|
|
438
|
+
/*
|
|
439
|
+
* General
|
|
440
|
+
*/
|
|
441
|
+
* {
|
|
442
|
+
box-sizing: border-box;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
html {
|
|
446
|
+
scroll-behavior: smooth;
|
|
447
|
+
|
|
448
|
+
@media (prefers-reduced-motion: reduce) {
|
|
449
|
+
scroll-behavior: auto;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
body {
|
|
454
|
+
background-color: var(--body-bg);
|
|
455
|
+
color: var(--body-fg);
|
|
456
|
+
font-family: sans-serif;
|
|
457
|
+
margin: var(--body-margin);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
a {
|
|
461
|
+
color: var(--nav-fg);
|
|
462
|
+
}
|
|
463
|
+
p{
|
|
464
|
+
margin: 0 0 .5em 0
|
|
465
|
+
}
|
|
466
|
+
h1, h2 {
|
|
467
|
+
font-weight: normal;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
h1, h2, h3 {
|
|
471
|
+
color: var(--h-fg);
|
|
472
|
+
margin: 0 0 var(--component-margin-sm) 0;
|
|
473
|
+
}
|
|
474
|
+
/*
|
|
475
|
+
* Layout
|
|
476
|
+
*/
|
|
477
|
+
#main{
|
|
478
|
+
display: flex;
|
|
479
|
+
}
|
|
480
|
+
aside {
|
|
481
|
+
margin-right: calc(1.5* var(--body-margin));
|
|
482
|
+
padding-right: calc(1* var(--body-margin));
|
|
483
|
+
border-right: var(--component-border);
|
|
484
|
+
}
|
|
485
|
+
#information{
|
|
486
|
+
flex-grow: 1
|
|
487
|
+
}
|
|
488
|
+
/*
|
|
489
|
+
* Hints
|
|
490
|
+
*/
|
|
491
|
+
.hint {
|
|
492
|
+
margin-bottom: var(--component-margin-lg);
|
|
493
|
+
}
|
|
494
|
+
.hint__header {
|
|
495
|
+
align-items: baseline;
|
|
496
|
+
background-color: var(--h-bg);
|
|
497
|
+
display: flex;
|
|
498
|
+
justify-content: space-between;
|
|
499
|
+
margin-right: calc(-1 * var(--body-margin));
|
|
500
|
+
margin-left: calc(-1 * var(--body-margin));
|
|
501
|
+
margin-bottom: var(--component-margin-sm);
|
|
502
|
+
padding: var(--component-margin-sm) var(--body-margin) 0;
|
|
503
|
+
position: sticky;
|
|
504
|
+
top: 0;
|
|
505
|
+
z-index: 1;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/*
|
|
509
|
+
* Lists
|
|
510
|
+
*/
|
|
511
|
+
ul,
|
|
512
|
+
ol {
|
|
513
|
+
padding: 0 0 0 2em;
|
|
514
|
+
}
|
|
515
|
+
li {
|
|
516
|
+
margin: 0 0 2em 0;
|
|
517
|
+
}
|
|
518
|
+
li li {
|
|
519
|
+
margin: 0;
|
|
520
|
+
}
|
|
521
|
+
/*
|
|
522
|
+
* Header, nav, 'back to top' button
|
|
523
|
+
*/
|
|
524
|
+
.site__header {
|
|
525
|
+
align-items: baseline;
|
|
526
|
+
display: flex;
|
|
527
|
+
flex-wrap: wrap;
|
|
528
|
+
justify-content: space-between;
|
|
529
|
+
}
|
|
530
|
+
.nav {
|
|
531
|
+
margin-bottom: var(--component-margin-sm);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.nav ul {
|
|
535
|
+
display: flex;
|
|
536
|
+
justify-content: flex-start;
|
|
537
|
+
align-items: center;
|
|
538
|
+
list-style: none;
|
|
539
|
+
padding: 0;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.nav li {
|
|
543
|
+
margin-bottom: var(--component-margin-sm);
|
|
544
|
+
margin: 0 0.5em 0 0;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.nav a {
|
|
548
|
+
display: block;
|
|
549
|
+
height: 100%;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.nav a,
|
|
553
|
+
.btn {
|
|
554
|
+
background-color: var(--nav-bg);
|
|
555
|
+
padding: 0.5em;
|
|
556
|
+
text-decoration: none;
|
|
557
|
+
transition: background-color 0.2s ease;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.nav a:hover,
|
|
561
|
+
.nav a:focus,
|
|
562
|
+
.btn:hover,
|
|
563
|
+
.btn:focus {
|
|
564
|
+
background-color: var(--nav-bg-hover);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
.nav a:focus,
|
|
568
|
+
.btn:focus {
|
|
569
|
+
outline: 4px dashed var(--nav-fg);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.btn {
|
|
573
|
+
font-size: 1.2em;
|
|
574
|
+
margin-bottom: var(--component-margin-sm);
|
|
575
|
+
text-align: center;
|
|
576
|
+
}
|
|
577
|
+
/*
|
|
578
|
+
* Count component on colour chips
|
|
579
|
+
*/
|
|
580
|
+
.count {
|
|
581
|
+
background-color: var(--count-bg);
|
|
582
|
+
border: var(--count-border);
|
|
583
|
+
border-radius: 50%;
|
|
584
|
+
box-sizing: border-box;
|
|
585
|
+
color: var(--count-fg);
|
|
586
|
+
display: inline-block;
|
|
587
|
+
height: auto;
|
|
588
|
+
min-width: 2.3em;
|
|
589
|
+
padding: 0.5em;
|
|
590
|
+
text-align: center;
|
|
591
|
+
|
|
592
|
+
/* Counteract .chip:hover */
|
|
593
|
+
font-weight: normal;
|
|
594
|
+
text-shadow: none;
|
|
595
|
+
}
|
|
596
|
+
/*
|
|
597
|
+
* Darkmode switch
|
|
598
|
+
*/
|
|
599
|
+
.button__theme-toggle {
|
|
600
|
+
background: transparent;
|
|
601
|
+
border: none;
|
|
602
|
+
cursor: pointer;
|
|
603
|
+
margin-bottom: 0;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.button__theme-toggle::before {
|
|
607
|
+
content: "🌛";
|
|
608
|
+
font-size: 1.5rem;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
body.is-dark-mode .button__theme-toggle::before {
|
|
612
|
+
content: "🌞";
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/*
|
|
616
|
+
* Link Icon
|
|
617
|
+
*/
|
|
618
|
+
.link{
|
|
619
|
+
text-decoration: none;
|
|
620
|
+
cursor: pointer;
|
|
621
|
+
}
|
|
622
|
+
.link::before{
|
|
623
|
+
content: "🔗";
|
|
624
|
+
}
|
|
625
|
+
`;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Returns string content for js file
|
|
630
|
+
* @returns string
|
|
631
|
+
*/
|
|
632
|
+
function jsContent(){
|
|
633
|
+
return `
|
|
634
|
+
|
|
635
|
+
const cssAudit = {};
|
|
636
|
+
|
|
637
|
+
document.addEventListener( 'DOMContentLoaded', () => {
|
|
638
|
+
const button = document.querySelector( '.button__theme-toggle' );
|
|
639
|
+
|
|
640
|
+
cssAudit.toggleDarkMode = function() {
|
|
641
|
+
const isDarkMode = document.body.classList.contains( 'is-dark-mode' );
|
|
642
|
+
if ( isDarkMode ) {
|
|
643
|
+
button.setAttribute( 'aria-pressed', 'false' );
|
|
644
|
+
document.body.classList.remove( 'is-dark-mode' );
|
|
645
|
+
} else {
|
|
646
|
+
button.setAttribute( 'aria-pressed', 'true' );
|
|
647
|
+
document.body.classList.add( 'is-dark-mode' );
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Set is-dark-mode class if user has requested dark mode.
|
|
652
|
+
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches ){
|
|
653
|
+
document.body.classList.add( 'is-dark-mode' );
|
|
654
|
+
button.setAttribute( 'aria-pressed', 'true' );
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
});
|
|
658
|
+
`;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
module.exports = {
|
|
662
|
+
reporter
|
|
663
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caweb/cli",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "CAWebPublishing Command Line Interface.",
|
|
5
5
|
"exports": "./lib/env.js",
|
|
6
6
|
"type": "module",
|
|
@@ -13,12 +13,9 @@
|
|
|
13
13
|
"auditor": "bin/css-audit/index.js"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
-
"assets",
|
|
17
16
|
"bin",
|
|
18
17
|
"commands",
|
|
19
18
|
"configs",
|
|
20
|
-
"docs",
|
|
21
|
-
"gen",
|
|
22
19
|
"lib",
|
|
23
20
|
"template"
|
|
24
21
|
],
|
|
@@ -80,9 +77,11 @@
|
|
|
80
77
|
"get-all-files": "^5.0.0",
|
|
81
78
|
"got": "^14.4.1",
|
|
82
79
|
"handlebars-loader": "^1.7.3",
|
|
80
|
+
"html-format": "^1.1.7",
|
|
83
81
|
"html-to-json-parser": "^2.0.1",
|
|
84
82
|
"html-webpack-plugin": "^5.6.0",
|
|
85
83
|
"html-webpack-skip-assets-plugin": "^1.0.4",
|
|
84
|
+
"jshint": "^2.13.6",
|
|
86
85
|
"mini-css-extract-plugin": "^2.9.0",
|
|
87
86
|
"ora": "^8.0.1",
|
|
88
87
|
"postcss-loader": "^8.1.1",
|
|
@@ -91,6 +90,7 @@
|
|
|
91
90
|
"snyk": "^1.1292.1",
|
|
92
91
|
"terminal-link": "^3.0.0",
|
|
93
92
|
"url": "^0.11.3",
|
|
94
|
-
"webpack": "^5.92.1"
|
|
93
|
+
"webpack": "^5.92.1",
|
|
94
|
+
"webpack-dev-server": "^5.0.4"
|
|
95
95
|
}
|
|
96
96
|
}
|
package/assets/logo.ico
DELETED
|
Binary file
|