@@ -20,36 +20,140 @@ var assertAccessibility = (tagName, props, children) => {
2020 return failures ;
2121} ;
2222
23- var error = ( id , msg ) => {
24- throw new Error ( '#' + id + ": " + msg ) ;
23+ var filterFailures = ( failureInfo , options ) => {
24+ var failures = failureInfo . failures ;
25+ var filterFn = options . filterFn &&
26+ options . filterFn . bind ( undefined , failureInfo . name , failureInfo . id ) ;
27+
28+ if ( filterFn ) {
29+ failures = failures . filter ( filterFn ) ;
30+ }
31+
32+ return failures ;
2533} ;
2634
27- var warn = ( id , msg ) => {
28- console . warn ( '#' + id , msg ) ;
35+ var throwError = ( failureInfo , options ) => {
36+ var failures = filterFailures ( failureInfo , options ) ;
37+ var msg = failures . pop ( ) ;
38+ var error = [ failureInfo . name , msg ] ;
39+
40+ if ( options . includeSrcNode ) {
41+ error . push ( failureInfo . id ) ;
42+ }
43+
44+ throw new Error ( error . join ( ' ' ) ) ;
45+ } ;
46+
47+ var after = ( host , name , cb ) => {
48+ var originalFn = host [ name ] ;
49+
50+ if ( originalFn ) {
51+ host [ name ] = ( ) => {
52+ originalFn . call ( host ) ;
53+ cb . call ( host ) ;
54+ } ;
55+ } else {
56+ host [ name ] = cb ;
57+ }
58+ } ;
59+
60+ var logAfterRender = ( component , log ) => {
61+ after ( component , 'componentDidMount' , log ) ;
62+ after ( component , 'componentDidUpdate' , log ) ;
63+ } ;
64+
65+ var logWarning = ( component , failureInfo , options ) => {
66+ var includeSrcNode = options . includeSrcNode ;
67+
68+ var warn = ( ) => {
69+ var failures = filterFailures ( failureInfo , options ) ;
70+
71+ failures . forEach ( ( failure ) => {
72+ var msg = failure ;
73+ var warning = [ failureInfo . name , msg ] ;
74+
75+ if ( includeSrcNode ) {
76+ warning . push ( document . getElementById ( failureInfo . id ) ) ;
77+ }
78+
79+ console . warn . apply ( console , warning ) ;
80+ } ) ;
81+
82+ totalFailures . push ( failureInfo ) ;
83+ } ;
84+
85+ if ( component && includeSrcNode ) {
86+ // Cannot log a node reference until the component is in the DOM,
87+ // so defer the document.getElementById call until componentDidMount
88+ // or componentDidUpdate.
89+ logAfterRender ( component . _instance , warn ) ;
90+ } else {
91+ warn ( ) ;
92+ }
2993} ;
3094
3195var nextId = 0 ;
32- module . exports = ( React , options ) => {
96+ var totalFailures ;
97+
98+ var reactA11y = ( React , options ) => {
3399 if ( ! React && ! React . createElement ) {
34100 throw new Error ( 'Missing parameter: React' ) ;
35101 }
36102 assertions . setReact ( React ) ;
37103
104+ totalFailures = [ ] ;
38105 var _createElement = React . createElement ;
39- var log = options && options . throw ? error : warn ;
40- React . createElement = function ( type , _props , ...children ) {
106+ var includeSrcNode = options && ! ! options . includeSrcNode ;
107+
108+ React . createElement = ( type , _props , ...children ) => {
41109 var props = _props || { } ;
110+ var reactEl ;
111+
42112 if ( typeof type === 'string' ) {
43- var failures = assertAccessibility ( type , props , children ) ;
113+ let failures = assertAccessibility ( type , props , children ) ;
44114 if ( failures . length ) {
45115 // Generate an id if one doesn't exist
46116 props . id = ( props . id || 'a11y-' + nextId ++ ) ;
117+ reactEl = _createElement . apply ( this , [ type , props ] . concat ( children ) ) ;
118+
119+ let reactComponent = reactEl . _owner ;
47120
48- for ( var i = 0 ; i < failures . length ; i ++ )
49- log ( props . id , failures [ i ] ) ;
121+ // If a Component instance, use the component's name,
122+ // if a ReactElement instance, use the node DOM + id (e.g. div#foo)
123+ let name = reactComponent && reactComponent . getName ( ) ||
124+ reactEl . type + '#' + props . id ;
125+
126+ let failureInfo = {
127+ 'name' : name ,
128+ 'id' : props . id ,
129+ 'failures' : failures
130+ } ;
131+
132+ let notifyOpts = {
133+ 'includeSrcNode' : includeSrcNode ,
134+ 'filterFn' : options && options . filterFn
135+ } ;
136+
137+ if ( options && options . throw ) {
138+ throwError ( failureInfo , notifyOpts ) ;
139+ } else {
140+ logWarning ( reactComponent , failureInfo , notifyOpts ) ;
141+ }
142+
143+ } else {
144+ reactEl = _createElement . apply ( this , [ type , props ] . concat ( children ) ) ;
50145 }
146+ } else {
147+ reactEl = _createElement . apply ( this , [ type , props ] . concat ( children ) ) ;
51148 }
52- // make sure props with the id is passed down, even if no props were passed in.
53- return _createElement . apply ( this , [ type , props ] . concat ( children ) ) ;
149+
150+ return reactEl ;
54151 } ;
152+
153+ reactA11y . getFailures = ( ) => {
154+ return totalFailures ;
155+ } ;
156+
55157} ;
158+
159+ module . exports = reactA11y ;
0 commit comments