@@ -7,6 +7,8 @@ module.exports = wrapper
77
88var own = { } . hasOwnProperty
99
10+ var allData = 'data*'
11+
1012var NODES = {
1113 root : { children : all } ,
1214 doctype : handleDoctype ,
@@ -134,48 +136,62 @@ function all(schema, children, node, stack) {
134136function handleProperties ( schema , properties , node , stack ) {
135137 var name = handleTagName ( schema , node . tagName , node , stack )
136138 var attrs = schema . attributes
139+ var reqs = schema . required || /* istanbul ignore next */ { }
137140 var props = properties || { }
138141 var result = { }
139142 var allowed
143+ var required
144+ var definition
140145 var prop
141146 var value
142147
143- allowed = own . call ( attrs , name ) ? attrs [ name ] : [ ]
144- allowed = [ ] . concat ( allowed , attrs [ '*' ] )
148+ allowed = xtend (
149+ toPropertyValueMap ( attrs [ '*' ] ) ,
150+ toPropertyValueMap ( own . call ( attrs , name ) ? attrs [ name ] : [ ] )
151+ )
145152
146153 for ( prop in props ) {
147154 value = props [ prop ]
148155
149- if (
150- allowed . indexOf ( prop ) === - 1 &&
151- ! ( data ( prop ) && allowed . indexOf ( 'data*' ) !== - 1 )
152- ) {
156+ if ( own . call ( allowed , prop ) ) {
157+ definition = allowed [ prop ]
158+ } else if ( data ( prop ) && own . call ( allowed , allData ) ) {
159+ definition = allowed [ allData ]
160+ } else {
153161 continue
154162 }
155163
156164 if ( value && typeof value === 'object' && 'length' in value ) {
157- value = handlePropertyValues ( schema , value , prop )
165+ value = handlePropertyValues ( schema , value , prop , definition )
158166 } else {
159- value = handlePropertyValue ( schema , value , prop )
167+ value = handlePropertyValue ( schema , value , prop , definition )
160168 }
161169
162170 if ( value !== null && value !== undefined ) {
163171 result [ prop ] = value
164172 }
165173 }
166174
175+ required = own . call ( reqs , name ) ? reqs [ name ] : { }
176+
177+ for ( prop in required ) {
178+ if ( ! own . call ( result , prop ) ) {
179+ result [ prop ] = required [ prop ]
180+ }
181+ }
182+
167183 return result
168184}
169185
170186// Sanitize a property value which is a list.
171- function handlePropertyValues ( schema , values , prop ) {
187+ function handlePropertyValues ( schema , values , prop , definition ) {
172188 var length = values . length
173189 var result = [ ]
174190 var index = - 1
175191 var value
176192
177193 while ( ++ index < length ) {
178- value = handlePropertyValue ( schema , values [ index ] , prop )
194+ value = handlePropertyValue ( schema , values [ index ] , prop , definition )
179195
180196 if ( value !== null && value !== undefined ) {
181197 result . push ( value )
@@ -186,7 +202,7 @@ function handlePropertyValues(schema, values, prop) {
186202}
187203
188204// Sanitize a property value.
189- function handlePropertyValue ( schema , value , prop ) {
205+ function handlePropertyValue ( schema , value , prop , definition ) {
190206 if (
191207 typeof value !== 'boolean' &&
192208 typeof value !== 'number' &&
@@ -199,6 +215,10 @@ function handlePropertyValue(schema, value, prop) {
199215 return null
200216 }
201217
218+ if ( definition . length !== 0 && definition . indexOf ( value ) === - 1 ) {
219+ return null
220+ }
221+
202222 if ( schema . clobber . indexOf ( prop ) !== - 1 ) {
203223 value = schema . clobberPrefix + value
204224 }
@@ -314,6 +334,26 @@ function handleValue(schema, value) {
314334 return typeof value === 'string' ? value : ''
315335}
316336
337+ // Create a map from a list of props or a list of properties and values.
338+ function toPropertyValueMap ( values ) {
339+ var result = { }
340+ var length = values . length
341+ var index = - 1
342+ var value
343+
344+ while ( ++ index < length ) {
345+ value = values [ index ]
346+
347+ if ( value && typeof value === 'object' && 'length' in value ) {
348+ result [ value [ 0 ] ] = value . slice ( 1 )
349+ } else {
350+ result [ value ] = [ ]
351+ }
352+ }
353+
354+ return result
355+ }
356+
317357// Allow `value`.
318358function allow ( schema , value ) {
319359 return value
0 commit comments