@@ -7,6 +7,8 @@ module.exports = wrapper
7
7
8
8
var own = { } . hasOwnProperty
9
9
10
+ var allData = 'data*'
11
+
10
12
var NODES = {
11
13
root : { children : all } ,
12
14
doctype : handleDoctype ,
@@ -134,48 +136,62 @@ function all(schema, children, node, stack) {
134
136
function handleProperties ( schema , properties , node , stack ) {
135
137
var name = handleTagName ( schema , node . tagName , node , stack )
136
138
var attrs = schema . attributes
139
+ var reqs = schema . required || /* istanbul ignore next */ { }
137
140
var props = properties || { }
138
141
var result = { }
139
142
var allowed
143
+ var required
144
+ var definition
140
145
var prop
141
146
var value
142
147
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
+ )
145
152
146
153
for ( prop in props ) {
147
154
value = props [ prop ]
148
155
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 {
153
161
continue
154
162
}
155
163
156
164
if ( value && typeof value === 'object' && 'length' in value ) {
157
- value = handlePropertyValues ( schema , value , prop )
165
+ value = handlePropertyValues ( schema , value , prop , definition )
158
166
} else {
159
- value = handlePropertyValue ( schema , value , prop )
167
+ value = handlePropertyValue ( schema , value , prop , definition )
160
168
}
161
169
162
170
if ( value !== null && value !== undefined ) {
163
171
result [ prop ] = value
164
172
}
165
173
}
166
174
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
+
167
183
return result
168
184
}
169
185
170
186
// Sanitize a property value which is a list.
171
- function handlePropertyValues ( schema , values , prop ) {
187
+ function handlePropertyValues ( schema , values , prop , definition ) {
172
188
var length = values . length
173
189
var result = [ ]
174
190
var index = - 1
175
191
var value
176
192
177
193
while ( ++ index < length ) {
178
- value = handlePropertyValue ( schema , values [ index ] , prop )
194
+ value = handlePropertyValue ( schema , values [ index ] , prop , definition )
179
195
180
196
if ( value !== null && value !== undefined ) {
181
197
result . push ( value )
@@ -186,7 +202,7 @@ function handlePropertyValues(schema, values, prop) {
186
202
}
187
203
188
204
// Sanitize a property value.
189
- function handlePropertyValue ( schema , value , prop ) {
205
+ function handlePropertyValue ( schema , value , prop , definition ) {
190
206
if (
191
207
typeof value !== 'boolean' &&
192
208
typeof value !== 'number' &&
@@ -199,6 +215,10 @@ function handlePropertyValue(schema, value, prop) {
199
215
return null
200
216
}
201
217
218
+ if ( definition . length !== 0 && definition . indexOf ( value ) === - 1 ) {
219
+ return null
220
+ }
221
+
202
222
if ( schema . clobber . indexOf ( prop ) !== - 1 ) {
203
223
value = schema . clobberPrefix + value
204
224
}
@@ -314,6 +334,26 @@ function handleValue(schema, value) {
314
334
return typeof value === 'string' ? value : ''
315
335
}
316
336
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
+
317
357
// Allow `value`.
318
358
function allow ( schema , value ) {
319
359
return value
0 commit comments