Skip to content

Commit 02b7b0d

Browse files
committedJun 1, 2020
refactor: Organizing files
·
v2.4.4v2.3.0
1 parent affd6af commit 02b7b0d

File tree

4 files changed

+170
-171
lines changed

4 files changed

+170
-171
lines changed
 

‎index.d.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export interface AxeRunOptions {
8989
/**
9090
* Log rule performance metrics to the console
9191
*/
92-
performanceTimer?: boolean,
92+
performanceTimer?: boolean
9393
}
9494

9595
export interface VueAxeStyle {
@@ -135,17 +135,12 @@ export interface VueAxeOptions {
135135
/**
136136
* Handle the results. (This may be needed for automated tests)
137137
*/
138-
customResultHandler?: (error: any, results: any),
138+
customResultHandler?: (error: any, results: any)
139139
}
140140

141141
export interface VueAxe {
142142
run({ clearConsole, element }: RunOptions): void;
143-
144143
plugins: Record<string, any>;
145-
146-
clearConsole(forceClear: boolean): void;
147-
148-
debounce(): void;
149144
}
150145

151146
declare module 'vue/types/vue' {

‎src/audit.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import axeCore from 'axe-core'
2+
3+
let cache = {}
4+
let style = {}
5+
let lastNotification = ''
6+
7+
const deferred = {}
8+
const impacts = [...axeCore.constants.impact].reverse()
9+
10+
export function checkAndReport (options, node) {
11+
const deferred = createDeferred()
12+
style = { ...options.style }
13+
14+
axeCore.run(node || document, options.runOptions, (error, results) => {
15+
if (error) deferred.reject(error)
16+
if (results && !results.violations.length) return
17+
if (JSON.stringify(results.violations) === lastNotification) return
18+
19+
if (options.clearConsoleOnUpdate) {
20+
console.clear()
21+
}
22+
23+
options.customResultHandler ? options.customResultHandler(error, results) : standardResultHandler(error, results)
24+
deferred.resolve()
25+
lastNotification = JSON.stringify(results.violations)
26+
})
27+
return deferred.promise
28+
}
29+
30+
const standardResultHandler = function (errorInfo, results) {
31+
results.violations = results.violations.filter(result => {
32+
result.nodes = result.nodes.filter(node => {
33+
const key = node.target.toString() + result.id
34+
const retVal = (!cache[key])
35+
cache[key] = key
36+
return retVal
37+
})
38+
return (!!result.nodes.length)
39+
})
40+
41+
if (results.violations.length) {
42+
const violations = sortViolations(results.violations)
43+
console.group('%cNew axe issues', style.head)
44+
violations.forEach(result => {
45+
console.groupCollapsed('%c%s%c %s %s %c%s', style[result.impact || 'minor'], result.impact, style.title, result.help, '\n', style.url, result.helpUrl)
46+
result.nodes.forEach(node => {
47+
failureSummary(node, 'any')
48+
failureSummary(node, 'none')
49+
})
50+
console.groupEnd()
51+
})
52+
console.groupEnd()
53+
}
54+
}
55+
56+
export function resetCache () {
57+
cache = {}
58+
}
59+
60+
export function resetLastNotification () {
61+
lastNotification = ''
62+
}
63+
64+
export const draf = (cb) => requestAnimationFrame(() => requestAnimationFrame(cb))
65+
66+
function sortViolations (violations) {
67+
let sorted = []
68+
impacts.forEach(impact => {
69+
sorted = [...sorted, ...violations.filter(violation => violation.impact === impact)]
70+
})
71+
return sorted
72+
}
73+
74+
function createDeferred () {
75+
deferred.promise = new Promise((resolve, reject) => {
76+
deferred.resolve = resolve
77+
deferred.reject = reject
78+
})
79+
return deferred
80+
}
81+
82+
function failureSummary (node, key) {
83+
if (node[key].length > 0) {
84+
logElement(node, console.groupCollapsed)
85+
logHtml(node)
86+
logFailureMessage(node, key)
87+
88+
var relatedNodes = []
89+
node[key].forEach(check => {
90+
relatedNodes = relatedNodes.concat(check.relatedNodes)
91+
})
92+
93+
if (relatedNodes.length > 0) {
94+
console.groupCollapsed('Related nodes')
95+
relatedNodes.forEach(relatedNode => {
96+
logElement(relatedNode, console.log)
97+
logHtml(relatedNode)
98+
})
99+
console.groupEnd()
100+
}
101+
console.groupEnd()
102+
}
103+
}
104+
105+
function logElement (node, logFn) {
106+
const el = document.querySelector(node.target.toString())
107+
if (!el) {
108+
return logFn('Selector: %c%s', style.boldCourier, node.target.toString())
109+
}
110+
logFn('Element: %o', el)
111+
}
112+
113+
function logHtml (node) {
114+
console.log('HTML: %c%s', style.boldCourier, node.html)
115+
}
116+
117+
function logFailureMessage (node, key) {
118+
const message = axeCore._audit.data.failureSummaries[key]
119+
.failureMessage(node[key]
120+
.map(function (check) {
121+
return check.message || ''
122+
}))
123+
console.error(message)
124+
}

‎src/index.js

Lines changed: 13 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,17 @@
11
import axeCore from 'axe-core'
22
import debounce from 'lodash.debounce'
33
import merge from 'lodash.merge'
4-
import { checkAndReport, draf, resetCache, resetLastNotification } from './utils'
5-
6-
let firstCheck = false
4+
import { checkAndReport, resetCache } from './audit'
5+
import { clear, defaultOptions, draf } from './utils'
76

87
export default function install (Vue, options) {
98
// Browser only
109
if (typeof window === 'undefined') return
1110

12-
const defaultOptions = {
13-
auto: true,
14-
clearConsoleOnUpdate: false,
15-
delay: 0,
16-
config: {
17-
branding: {
18-
application: 'vue-axe'
19-
}
20-
},
21-
runOptions: {
22-
reporter: 'v2',
23-
resultTypes: ['violations']
24-
},
25-
style: {
26-
head: 'padding:6px;font-size:20px;color:#333;font-weight:bold;',
27-
boldCourier: 'font-weight:bold;font-family:Courier;',
28-
moderate: 'padding:2px 4px;border-radius:5px;background-color:#FFBA52;color:#222;font-weight:normal;',
29-
critical: 'padding:2px 4px;border-radius:5px;background-color:#AD0000;color:#fff;font-weight:normal;',
30-
serious: 'padding:2px 4px;border-radius:5px;background-color:#333;color:#FFCE85;font-weight:normal;',
31-
minor: 'padding:2px 4px;border-radius:5px;background-color:#333;color:#FFCE85;font-weight:normal;',
32-
title: 'font-color:black;font-weight:bold;',
33-
url: 'font-color:#4D4D4D;font-weight:normal;'
34-
},
35-
plugins: []
36-
}
37-
11+
// merge options
3812
options = merge(defaultOptions, options)
3913

14+
// set config
4015
axeCore.configure({ ...options.config })
4116

4217
// register plugins
@@ -45,36 +20,28 @@ export default function install (Vue, options) {
4520
// vue-axe methods in Vue Instance
4621
Vue.prototype.$axe = {
4722
run ({ clearConsole = options.clearConsoleOnUpdate, element } = {}) {
48-
this.clearConsole(clearConsole)
23+
clear(clearConsole, options)
4924
draf(() => checkAndReport(options, element))
5025
},
51-
plugins: axeCore.plugins,
52-
clearConsole (forceClear = false) {
53-
resetCache()
54-
if (forceClear || options.clearConsoleOnUpdate) {
55-
console.clear()
56-
resetLastNotification()
57-
}
58-
},
59-
debounce: debounce(function () {
60-
resetCache()
61-
draf(() => checkAndReport(options))
62-
}, 1000, { maxWait: 5000 })
26+
plugins: axeCore.plugins
6327
}
6428

6529
// if false, disable automatic verification
6630
if (!options.auto) return
6731

32+
const checkWithDebounce = debounce(function () {
33+
resetCache()
34+
draf(() => checkAndReport(options))
35+
}, 1000, { maxWait: 5000 })
36+
6837
// Rechecking when updating specific component
6938
Vue.mixin({
7039
updated () {
71-
if (firstCheck) return this.$axe.debounce()
72-
firstCheck = true
73-
setTimeout(() => this.$axe.debounce(), options.delay)
40+
checkWithDebounce()
7441
},
7542
// Used for change of route
7643
beforeDestroy () {
77-
this.$axe.clearConsole(true)
44+
clear(true, options)
7845
}
7946
})
8047
}

‎src/utils.js

Lines changed: 31 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,37 @@
1-
import axeCore from 'axe-core'
2-
3-
let cache = {}
4-
let style = {}
5-
let lastNotification = ''
6-
7-
const deferred = {}
8-
const impacts = [...axeCore.constants.impact].reverse()
9-
10-
export function checkAndReport (options, node) {
11-
const deferred = createDeferred()
12-
style = { ...options.style }
13-
14-
axeCore.run(node || document, options.runOptions, (error, results) => {
15-
if (error) deferred.reject(error)
16-
if (results && !results.violations.length) return
17-
if (JSON.stringify(results.violations) === lastNotification) return
18-
19-
if (options.clearConsoleOnUpdate) {
20-
console.clear()
21-
}
22-
23-
options.customResultHandler ? options.customResultHandler(error, results) : standardResultHandler(error, results)
24-
deferred.resolve()
25-
lastNotification = JSON.stringify(results.violations)
26-
})
27-
return deferred.promise
28-
}
29-
30-
const standardResultHandler = function (errorInfo, results) {
31-
results.violations = results.violations.filter(result => {
32-
result.nodes = result.nodes.filter(node => {
33-
const key = node.target.toString() + result.id
34-
const retVal = (!cache[key])
35-
cache[key] = key
36-
return retVal
37-
})
38-
return (!!result.nodes.length)
39-
})
40-
41-
if (results.violations.length) {
42-
const violations = sortViolations(results.violations)
43-
console.group('%cNew axe issues', style.head)
44-
violations.forEach(result => {
45-
console.groupCollapsed('%c%s%c %s %s %c%s', style[result.impact || 'minor'], result.impact, style.title, result.help, '\n', style.url, result.helpUrl)
46-
result.nodes.forEach(node => {
47-
failureSummary(node, 'any')
48-
failureSummary(node, 'none')
49-
})
50-
console.groupEnd()
51-
})
52-
console.groupEnd()
53-
}
54-
}
55-
56-
export function resetCache () {
57-
cache = {}
58-
}
59-
60-
export function resetLastNotification () {
61-
lastNotification = ''
62-
}
1+
import { resetCache, resetLastNotification } from './audit'
632

643
export const draf = (cb) => requestAnimationFrame(() => requestAnimationFrame(cb))
654

66-
function sortViolations (violations) {
67-
let sorted = []
68-
impacts.forEach(impact => {
69-
sorted = [...sorted, ...violations.filter(violation => violation.impact === impact)]
70-
})
71-
return sorted
72-
}
73-
74-
function createDeferred () {
75-
deferred.promise = new Promise((resolve, reject) => {
76-
deferred.resolve = resolve
77-
deferred.reject = reject
78-
})
79-
return deferred
80-
}
81-
82-
function failureSummary (node, key) {
83-
if (node[key].length > 0) {
84-
logElement(node, console.groupCollapsed)
85-
logHtml(node)
86-
logFailureMessage(node, key)
87-
88-
var relatedNodes = []
89-
node[key].forEach(check => {
90-
relatedNodes = relatedNodes.concat(check.relatedNodes)
91-
})
92-
93-
if (relatedNodes.length > 0) {
94-
console.groupCollapsed('Related nodes')
95-
relatedNodes.forEach(relatedNode => {
96-
logElement(relatedNode, console.log)
97-
logHtml(relatedNode)
98-
})
99-
console.groupEnd()
5+
export const defaultOptions = {
6+
auto: true,
7+
clearConsoleOnUpdate: false,
8+
delay: 0,
9+
config: {
10+
branding: {
11+
application: 'vue-axe'
10012
}
101-
console.groupEnd()
13+
},
14+
runOptions: {
15+
reporter: 'v2',
16+
resultTypes: ['violations']
17+
},
18+
style: {
19+
head: 'padding:6px;font-size:20px;color:#333;font-weight:bold;',
20+
boldCourier: 'font-weight:bold;font-family:Courier;',
21+
moderate: 'padding:2px 4px;border-radius:5px;background-color:#FFBA52;color:#222;font-weight:normal;',
22+
critical: 'padding:2px 4px;border-radius:5px;background-color:#AD0000;color:#fff;font-weight:normal;',
23+
serious: 'padding:2px 4px;border-radius:5px;background-color:#333;color:#FFCE85;font-weight:normal;',
24+
minor: 'padding:2px 4px;border-radius:5px;background-color:#333;color:#FFCE85;font-weight:normal;',
25+
title: 'font-color:black;font-weight:bold;',
26+
url: 'font-color:#4D4D4D;font-weight:normal;'
27+
},
28+
plugins: []
29+
}
30+
31+
export function clear (forceClear = false, options) {
32+
resetCache()
33+
if (forceClear || options.clearConsoleOnUpdate) {
34+
console.clear()
35+
resetLastNotification()
10236
}
10337
}
104-
105-
function logElement (node, logFn) {
106-
const el = document.querySelector(node.target.toString())
107-
if (!el) {
108-
return logFn('Selector: %c%s', style.boldCourier, node.target.toString())
109-
}
110-
logFn('Element: %o', el)
111-
}
112-
113-
function logHtml (node) {
114-
console.log('HTML: %c%s', style.boldCourier, node.html)
115-
}
116-
117-
function logFailureMessage (node, key) {
118-
const message = axeCore._audit.data.failureSummaries[key]
119-
.failureMessage(node[key]
120-
.map(function (check) {
121-
return check.message || ''
122-
}))
123-
console.error(message)
124-
}

0 commit comments

Comments
 (0)
Please sign in to comment.