forEach(properties, function(propertyName, propertyDef) { if (propertyName in m) return; // TODO(kalman): be strict like functions/events somehow. if (!isSchemaNodeSupported(propertyDef, platform, manifestVersion)) return; if (!GetAvailability(schema.namespace + "." + propertyName).is_available || (checkUnprivileged && !isSchemaAccessAllowed(propertyDef))) { return; } // |value| is eventually added to |m|, the exposed API. Make copies // of everything from the schema. (The schema is also frozen, so as long // as we don't make any modifications, shallow copies are fine.) var value; if ($Array.isArray(propertyDef.value)) value = $Array.slice(propertyDef.value); else if (typeof propertyDef.value === 'object') value = $Object.assign({}, propertyDef.value); else value = propertyDef.value; if (value) { // Values may just have raw types as defined in the JSON, such // as "WINDOW_ID_NONE": { "value": -1 }. We handle this here. // TODO(kalman): enforce that things with a "value" property can't // define their own types. var type = propertyDef.type || typeof(value); if (type === 'integer' || type === 'number') { value = parseInt(value); } else if (type === 'boolean') { value = value === 'true'; } else if (propertyDef['$ref']) { var ref = propertyDef['$ref']; var type = utils.loadTypeSchema(propertyDef['$ref'], schema); logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found'); var constructor = createCustomType(type); var args = value; logging.DCHECK($Array.isArray(args)); $Array.push(args, type); // For an object propertyDef, |value| is an array of constructor // arguments, but we want to pass the arguments directly (i.e. // not as an array), so we have to fake calling |new| on the // constructor. value = { __proto__: constructor.prototype }; $Function.apply(constructor, value, args); // Recursively add properties. addProperties(value, propertyDef); } else if (type === 'object') { // Recursively add properties. addProperties(value, propertyDef); } else if (type !== 'string') { throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + 'Cannot parse values for type "' + type + '"'); } m[propertyName] = value; } });
forEach(properties, function(propertyName, propertyDef) { if (propertyName in m) return; // TODO(kalman): be strict like functions/events somehow. if (!isSchemaNodeSupported(propertyDef, platform, manifestVersion)) return; if (!isSchemaAccessAllowed(propertyDef)) { addUnprivilegedAccessGetter(m, propertyName); return; } var value = propertyDef.value; if (value) { // Values may just have raw types as defined in the JSON, such // as "WINDOW_ID_NONE": { "value": -1 }. We handle this here. // TODO(kalman): enforce that things with a "value" property can't // define their own types. var type = propertyDef.type || typeof(value); if (type === 'integer' || type === 'number') { value = parseInt(value); } else if (type === 'boolean') { value = value === 'true'; } else if (propertyDef['$ref']) { var ref = propertyDef['$ref']; var type = utils.loadTypeSchema(propertyDef['$ref'], schema); CHECK(type, 'Schema for $ref type ' + ref + ' not found'); var constructor = createCustomType(type); var args = value; // For an object propertyDef, |value| is an array of constructor // arguments, but we want to pass the arguments directly (i.e. // not as an array), so we have to fake calling |new| on the // constructor. value = { __proto__: constructor.prototype }; constructor.apply(value, args); // Recursively add properties. addProperties(value, propertyDef); } else if (type === 'object') { // Recursively add properties. addProperties(value, propertyDef); } else if (type !== 'string') { throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + 'Cannot parse values for type "' + type + '"'); } m[propertyName] = value; } });
JSONSchemaValidator.prototype.getOrAddType = function(typeName) { if (!this.types[typeName]) this.types[typeName] = utils.loadTypeSchema(typeName); return this.types[typeName]; };