Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: chrome/renderer/resources/json_schema.js

Issue 173263: Change the way json_schema.js is loaded. This is required so (Closed)
Patch Set: New approach using chromeHidden Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ----------------------------------------------------------------------------- 5 // -----------------------------------------------------------------------------
6 // NOTE: If you change this file you need to touch renderer_resources.grd to 6 // NOTE: If you change this file you need to touch renderer_resources.grd to
7 // have your change take effect. 7 // have your change take effect.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 9
10 //============================================================================== 10 //==============================================================================
(...skipping 18 matching lines...) Expand all
29 // - hidden 29 // - hidden
30 // 30 //
31 // There are also these departures from the JSON Schema proposal: 31 // There are also these departures from the JSON Schema proposal:
32 // - function and undefined types are supported 32 // - function and undefined types are supported
33 // - null counts as 'unspecified' for optional values 33 // - null counts as 'unspecified' for optional values
34 // - added the 'choices' property, to allow specifying a list of possible types 34 // - added the 'choices' property, to allow specifying a list of possible types
35 // for a value 35 // for a value
36 // - made additionalProperties default to false 36 // - made additionalProperties default to false
37 //============================================================================== 37 //==============================================================================
38 38
39 var chrome = chrome || {}; 39 (function() {
40 native function GetChromeHidden();
41 var chromeHidden = GetChromeHidden();
40 42
41 /** 43 /**
42 * Validates an instance against a schema and accumulates errors. Usage: 44 * Validates an instance against a schema and accumulates errors. Usage:
43 * 45 *
44 * var validator = new chrome.JSONSchemaValidator(); 46 * var validator = new chromeHidden.JSONSchemaValidator();
45 * validator.validate(inst, schema); 47 * validator.validate(inst, schema);
46 * if (validator.errors.length == 0) 48 * if (validator.errors.length == 0)
47 * console.log("Valid!"); 49 * console.log("Valid!");
48 * else 50 * else
49 * console.log(validator.errors); 51 * console.log(validator.errors);
50 * 52 *
51 * The errors property contains a list of objects. Each object has two 53 * The errors property contains a list of objects. Each object has two
52 * properties: "path" and "message". The "path" property contains the path to 54 * properties: "path" and "message". The "path" property contains the path to
53 * the key that had the problem, and the "message" property contains a sentence 55 * the key that had the problem, and the "message" property contains a sentence
54 * describing the error. 56 * describing the error.
55 */ 57 */
56 chrome.JSONSchemaValidator = function() { 58 chromeHidden.JSONSchemaValidator = function() {
57 this.errors = []; 59 this.errors = [];
58 this.types = []; 60 this.types = [];
59 }; 61 };
60 62
61 chrome.JSONSchemaValidator.messages = { 63 chromeHidden.JSONSchemaValidator.messages = {
62 invalidEnum: "Value must be one of: [*].", 64 invalidEnum: "Value must be one of: [*].",
63 propertyRequired: "Property is required.", 65 propertyRequired: "Property is required.",
64 unexpectedProperty: "Unexpected property.", 66 unexpectedProperty: "Unexpected property.",
65 arrayMinItems: "Array must have at least * items.", 67 arrayMinItems: "Array must have at least * items.",
66 arrayMaxItems: "Array must not have more than * items.", 68 arrayMaxItems: "Array must not have more than * items.",
67 itemRequired: "Item is required.", 69 itemRequired: "Item is required.",
68 stringMinLength: "String must be at least * characters long.", 70 stringMinLength: "String must be at least * characters long.",
69 stringMaxLength: "String must not be more than * characters long.", 71 stringMaxLength: "String must not be more than * characters long.",
70 stringPattern: "String must match the pattern: *.", 72 stringPattern: "String must match the pattern: *.",
71 numberMinValue: "Value must not be less than *.", 73 numberMinValue: "Value must not be less than *.",
72 numberMaxValue: "Value must not be greater than *.", 74 numberMaxValue: "Value must not be greater than *.",
73 numberMaxDecimal: "Value must not have more than * decimal places.", 75 numberMaxDecimal: "Value must not have more than * decimal places.",
74 invalidType: "Expected '*' but got '*'.", 76 invalidType: "Expected '*' but got '*'.",
75 invalidChoice: "Value does not match any valid type choices.", 77 invalidChoice: "Value does not match any valid type choices.",
76 invalidPropertyType: "Missing property type.", 78 invalidPropertyType: "Missing property type.",
77 schemaRequired: "Schema value required.", 79 schemaRequired: "Schema value required.",
78 unknownSchemaReference: "Unknown schema reference: *." 80 unknownSchemaReference: "Unknown schema reference: *."
79 }; 81 };
80 82
81 /** 83 /**
82 * Builds an error message. Key is the property in the |errors| object, and 84 * Builds an error message. Key is the property in the |errors| object, and
83 * |opt_replacements| is an array of values to replace "*" characters with. 85 * |opt_replacements| is an array of values to replace "*" characters with.
84 */ 86 */
85 chrome.JSONSchemaValidator.formatError = function(key, opt_replacements) { 87 chromeHidden.JSONSchemaValidator.formatError = function(key, opt_replacements) {
86 var message = this.messages[key]; 88 var message = this.messages[key];
87 if (opt_replacements) { 89 if (opt_replacements) {
88 for (var i = 0; i < opt_replacements.length; i++) { 90 for (var i = 0; i < opt_replacements.length; i++) {
89 message = message.replace("*", opt_replacements[i]); 91 message = message.replace("*", opt_replacements[i]);
90 } 92 }
91 } 93 }
92 return message; 94 return message;
93 }; 95 };
94 96
95 /** 97 /**
96 * Classifies a value as one of the JSON schema primitive types. Note that we 98 * Classifies a value as one of the JSON schema primitive types. Note that we
97 * don't explicitly disallow 'function', because we want to allow functions in 99 * don't explicitly disallow 'function', because we want to allow functions in
98 * the input values. 100 * the input values.
99 */ 101 */
100 chrome.JSONSchemaValidator.getType = function(value) { 102 chromeHidden.JSONSchemaValidator.getType = function(value) {
101 var s = typeof value; 103 var s = typeof value;
102 104
103 if (s == "object") { 105 if (s == "object") {
104 if (value === null) { 106 if (value === null) {
105 return "null"; 107 return "null";
106 } else if (value instanceof Array || 108 } else if (value instanceof Array ||
107 Object.prototype.toString.call(value) == "[Object Array]") { 109 Object.prototype.toString.call(value) == "[Object Array]") {
108 return "array"; 110 return "array";
109 } 111 }
110 } else if (s == "number") { 112 } else if (s == "number") {
111 if (value % 1 == 0) { 113 if (value % 1 == 0) {
112 return "integer"; 114 return "integer";
113 } 115 }
114 } 116 }
115 117
116 return s; 118 return s;
117 }; 119 };
118 120
119 /** 121 /**
120 * Add types that may be referenced by validated schemas that reference them 122 * Add types that may be referenced by validated schemas that reference them
121 * with "$ref": <typeId>. Each type must be a valid schema and define an 123 * with "$ref": <typeId>. Each type must be a valid schema and define an
122 * "id" property. 124 * "id" property.
123 */ 125 */
124 chrome.JSONSchemaValidator.prototype.addTypes = function(typeOrTypeList) { 126 chromeHidden.JSONSchemaValidator.prototype.addTypes = function(typeOrTypeList) {
125 function addType(validator, type) { 127 function addType(validator, type) {
126 if(!type.id) 128 if(!type.id)
127 throw "Attempt to addType with missing 'id' property"; 129 throw "Attempt to addType with missing 'id' property";
128 validator.types[type.id] = type; 130 validator.types[type.id] = type;
129 } 131 }
130 132
131 if (typeOrTypeList instanceof Array) { 133 if (typeOrTypeList instanceof Array) {
132 for (var i = 0; i < typeOrTypeList.length; i++) { 134 for (var i = 0; i < typeOrTypeList.length; i++) {
133 addType(this, typeOrTypeList[i]); 135 addType(this, typeOrTypeList[i]);
134 } 136 }
135 } else { 137 } else {
136 addType(this, typeOrTypeList); 138 addType(this, typeOrTypeList);
137 } 139 }
138 } 140 }
139 141
140 /** 142 /**
141 * Validates an instance against a schema. The instance can be any JavaScript 143 * Validates an instance against a schema. The instance can be any JavaScript
142 * value and will be validated recursively. When this method returns, the 144 * value and will be validated recursively. When this method returns, the
143 * |errors| property will contain a list of errors, if any. 145 * |errors| property will contain a list of errors, if any.
144 */ 146 */
145 chrome.JSONSchemaValidator.prototype.validate = function(instance, schema, 147 chromeHidden.JSONSchemaValidator.prototype.validate = function(
146 opt_path) { 148 instance, schema, opt_path) {
147 var path = opt_path || ""; 149 var path = opt_path || "";
148 150
149 if (!schema) { 151 if (!schema) {
150 this.addError(path, "schemaRequired"); 152 this.addError(path, "schemaRequired");
151 return; 153 return;
152 } 154 }
153 155
154 // If this schema defines itself as reference type, save it in this.types. 156 // If this schema defines itself as reference type, save it in this.types.
155 if (schema.id) 157 if (schema.id)
156 this.types[schema.id] = schema; 158 this.types[schema.id] = schema;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 this.validateNumber(instance, schema, path); 205 this.validateNumber(instance, schema, path);
204 break; 206 break;
205 } 207 }
206 } 208 }
207 }; 209 };
208 210
209 /** 211 /**
210 * Validates an instance against a choices schema. The instance must match at 212 * Validates an instance against a choices schema. The instance must match at
211 * least one of the provided choices. 213 * least one of the provided choices.
212 */ 214 */
213 chrome.JSONSchemaValidator.prototype.validateChoices = function(instance, 215 chromeHidden.JSONSchemaValidator.prototype.validateChoices = function(
214 schema, 216 instance, schema, path) {
215 path) {
216 var originalErrors = this.errors; 217 var originalErrors = this.errors;
217 218
218 for (var i = 0; i < schema.choices.length; i++) { 219 for (var i = 0; i < schema.choices.length; i++) {
219 this.errors = []; 220 this.errors = [];
220 this.validate(instance, schema.choices[i], path); 221 this.validate(instance, schema.choices[i], path);
221 if (this.errors.length == 0) { 222 if (this.errors.length == 0) {
222 this.errors = originalErrors; 223 this.errors = originalErrors;
223 return; 224 return;
224 } 225 }
225 } 226 }
226 227
227 this.errors = originalErrors; 228 this.errors = originalErrors;
228 this.addError(path, "invalidChoice"); 229 this.addError(path, "invalidChoice");
229 }; 230 };
230 231
231 /** 232 /**
232 * Validates an instance against a schema with an enum type. Populates the 233 * Validates an instance against a schema with an enum type. Populates the
233 * |errors| property, and returns a boolean indicating whether the instance 234 * |errors| property, and returns a boolean indicating whether the instance
234 * validates. 235 * validates.
235 */ 236 */
236 chrome.JSONSchemaValidator.prototype.validateEnum = function(instance, schema, 237 chromeHidden.JSONSchemaValidator.prototype.validateEnum = function(
237 path) { 238 instance, schema, path) {
238 for (var i = 0; i < schema.enum.length; i++) { 239 for (var i = 0; i < schema.enum.length; i++) {
239 if (instance === schema.enum[i]) 240 if (instance === schema.enum[i])
240 return true; 241 return true;
241 } 242 }
242 243
243 this.addError(path, "invalidEnum", [schema.enum.join(", ")]); 244 this.addError(path, "invalidEnum", [schema.enum.join(", ")]);
244 return false; 245 return false;
245 }; 246 };
246 247
247 /** 248 /**
248 * Validates an instance against an object schema and populates the errors 249 * Validates an instance against an object schema and populates the errors
249 * property. 250 * property.
250 */ 251 */
251 chrome.JSONSchemaValidator.prototype.validateObject = function(instance, 252 chromeHidden.JSONSchemaValidator.prototype.validateObject = function(
252 schema, path) { 253 instance, schema, path) {
253 for (var prop in schema.properties) { 254 for (var prop in schema.properties) {
254 var propPath = path ? path + "." + prop : prop; 255 var propPath = path ? path + "." + prop : prop;
255 if (schema.properties[prop] == undefined) { 256 if (schema.properties[prop] == undefined) {
256 this.addError(propPath, "invalidPropertyType"); 257 this.addError(propPath, "invalidPropertyType");
257 } else if (prop in instance && instance[prop] !== null && 258 } else if (prop in instance && instance[prop] !== null &&
258 instance[prop] !== undefined) { 259 instance[prop] !== undefined) {
259 this.validate(instance[prop], schema.properties[prop], propPath); 260 this.validate(instance[prop], schema.properties[prop], propPath);
260 } else if (!schema.properties[prop].optional) { 261 } else if (!schema.properties[prop].optional) {
261 this.addError(propPath, "propertyRequired"); 262 this.addError(propPath, "propertyRequired");
262 } 263 }
(...skipping 11 matching lines...) Expand all
274 this.validate(instance[prop], schema.additionalProperties, propPath); 275 this.validate(instance[prop], schema.additionalProperties, propPath);
275 else 276 else
276 this.addError(propPath, "unexpectedProperty"); 277 this.addError(propPath, "unexpectedProperty");
277 } 278 }
278 }; 279 };
279 280
280 /** 281 /**
281 * Validates an instance against an array schema and populates the errors 282 * Validates an instance against an array schema and populates the errors
282 * property. 283 * property.
283 */ 284 */
284 chrome.JSONSchemaValidator.prototype.validateArray = function(instance, 285 chromeHidden.JSONSchemaValidator.prototype.validateArray = function(
285 schema, path) { 286 instance, schema, path) {
286 var typeOfItems = chrome.JSONSchemaValidator.getType(schema.items); 287 var typeOfItems = chromeHidden.JSONSchemaValidator.getType(schema.items);
287 288
288 if (typeOfItems == 'object') { 289 if (typeOfItems == 'object') {
289 if (schema.minItems && instance.length < schema.minItems) { 290 if (schema.minItems && instance.length < schema.minItems) {
290 this.addError(path, "arrayMinItems", [schema.minItems]); 291 this.addError(path, "arrayMinItems", [schema.minItems]);
291 } 292 }
292 293
293 if (typeof schema.maxItems != "undefined" && 294 if (typeof schema.maxItems != "undefined" &&
294 instance.length > schema.maxItems) { 295 instance.length > schema.maxItems) {
295 this.addError(path, "arrayMaxItems", [schema.maxItems]); 296 this.addError(path, "arrayMaxItems", [schema.maxItems]);
296 } 297 }
(...skipping 24 matching lines...) Expand all
321 if (instance.length > schema.items.length) { 322 if (instance.length > schema.items.length) {
322 this.addError(path, "arrayMaxItems", [schema.items.length]); 323 this.addError(path, "arrayMaxItems", [schema.items.length]);
323 } 324 }
324 } 325 }
325 } 326 }
326 }; 327 };
327 328
328 /** 329 /**
329 * Validates a string and populates the errors property. 330 * Validates a string and populates the errors property.
330 */ 331 */
331 chrome.JSONSchemaValidator.prototype.validateString = function(instance, 332 chromeHidden.JSONSchemaValidator.prototype.validateString = function(
332 schema, path) { 333 instance, schema, path) {
333 if (schema.minLength && instance.length < schema.minLength) 334 if (schema.minLength && instance.length < schema.minLength)
334 this.addError(path, "stringMinLength", [schema.minLength]); 335 this.addError(path, "stringMinLength", [schema.minLength]);
335 336
336 if (schema.maxLength && instance.length > schema.maxLength) 337 if (schema.maxLength && instance.length > schema.maxLength)
337 this.addError(path, "stringMaxLength", [schema.maxLength]); 338 this.addError(path, "stringMaxLength", [schema.maxLength]);
338 339
339 if (schema.pattern && !schema.pattern.test(instance)) 340 if (schema.pattern && !schema.pattern.test(instance))
340 this.addError(path, "stringPattern", [schema.pattern]); 341 this.addError(path, "stringPattern", [schema.pattern]);
341 }; 342 };
342 343
343 /** 344 /**
344 * Validates a number and populates the errors property. The instance is 345 * Validates a number and populates the errors property. The instance is
345 * assumed to be a number. 346 * assumed to be a number.
346 */ 347 */
347 chrome.JSONSchemaValidator.prototype.validateNumber = function(instance, 348 chromeHidden.JSONSchemaValidator.prototype.validateNumber = function(
348 schema, path) { 349 instance, schema, path) {
349 if (schema.minimum && instance < schema.minimum) 350 if (schema.minimum && instance < schema.minimum)
350 this.addError(path, "numberMinValue", [schema.minimum]); 351 this.addError(path, "numberMinValue", [schema.minimum]);
351 352
352 if (schema.maximum && instance > schema.maximum) 353 if (schema.maximum && instance > schema.maximum)
353 this.addError(path, "numberMaxValue", [schema.maximum]); 354 this.addError(path, "numberMaxValue", [schema.maximum]);
354 355
355 if (schema.maxDecimal && instance * Math.pow(10, schema.maxDecimal) % 1) 356 if (schema.maxDecimal && instance * Math.pow(10, schema.maxDecimal) % 1)
356 this.addError(path, "numberMaxDecimal", [schema.maxDecimal]); 357 this.addError(path, "numberMaxDecimal", [schema.maxDecimal]);
357 }; 358 };
358 359
359 /** 360 /**
360 * Validates the primitive type of an instance and populates the errors 361 * Validates the primitive type of an instance and populates the errors
361 * property. Returns true if the instance validates, false otherwise. 362 * property. Returns true if the instance validates, false otherwise.
362 */ 363 */
363 chrome.JSONSchemaValidator.prototype.validateType = function(instance, schema, 364 chromeHidden.JSONSchemaValidator.prototype.validateType = function(
364 path) { 365 instance, schema, path) {
365 var actualType = chrome.JSONSchemaValidator.getType(instance); 366 var actualType = chromeHidden.JSONSchemaValidator.getType(instance);
366 if (schema.type != actualType && !(schema.type == "number" && 367 if (schema.type != actualType && !(schema.type == "number" &&
367 actualType == "integer")) { 368 actualType == "integer")) {
368 this.addError(path, "invalidType", [schema.type, actualType]); 369 this.addError(path, "invalidType", [schema.type, actualType]);
369 return false; 370 return false;
370 } 371 }
371 372
372 return true; 373 return true;
373 }; 374 };
374 375
375 /** 376 /**
376 * Adds an error message. |key| is an index into the |messages| object. 377 * Adds an error message. |key| is an index into the |messages| object.
377 * |replacements| is an array of values to replace '*' characters in the 378 * |replacements| is an array of values to replace '*' characters in the
378 * message. 379 * message.
379 */ 380 */
380 chrome.JSONSchemaValidator.prototype.addError = function(path, key, 381 chromeHidden.JSONSchemaValidator.prototype.addError = function(
381 replacements) { 382 path, key, replacements) {
382 this.errors.push({ 383 this.errors.push({
383 path: path, 384 path: path,
384 message: chrome.JSONSchemaValidator.formatError(key, replacements) 385 message: chromeHidden.JSONSchemaValidator.formatError(key, replacements)
385 }); 386 });
386 }; 387 };
388
389 })();
OLDNEW
« no previous file with comments | « chrome/renderer/resources/extension_process_bindings.js ('k') | chrome/test/render_view_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698