1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Custom binding for the Permissions API. 6 7var binding = require('binding').Binding.create('permissions'); 8 9var Event = require('event_bindings').Event; 10 11// These custom binding are only necessary because it is not currently 12// possible to have a union of types as the type of the items in an array. 13// Once that is fixed, this entire file should go away. 14// See, 15// https://code.google.com/p/chromium/issues/detail?id=162044 16// https://code.google.com/p/chromium/issues/detail?id=162042 17// TODO(bryeung): delete this file. 18binding.registerCustomHook(function(api) { 19 var apiFunctions = api.apiFunctions; 20 var permissions = api.compiledApi; 21 22 function maybeConvertToObject(str) { 23 var parts = $String.split(str, '|'); 24 if (parts.length != 2) 25 return str; 26 27 var ret = {}; 28 ret[parts[0]] = JSON.parse(parts[1]); 29 return ret; 30 } 31 32 function convertObjectPermissionsToStrings() { 33 if (arguments.length < 1) 34 return arguments; 35 36 var args = arguments[0].permissions; 37 if (!args) 38 return arguments; 39 40 for (var i = 0; i < args.length; i += 1) { 41 if (typeof(args[i]) == 'object') { 42 var a = args[i]; 43 var keys = $Object.keys(a); 44 if (keys.length != 1) { 45 throw new Error("Too many keys in object-style permission."); 46 } 47 arguments[0].permissions[i] = keys[0] + '|' + 48 JSON.stringify(a[keys[0]]); 49 } 50 } 51 52 return arguments; 53 } 54 55 // Convert complex permissions to strings so they validate against the schema 56 apiFunctions.setUpdateArgumentsPreValidate( 57 'contains', convertObjectPermissionsToStrings); 58 apiFunctions.setUpdateArgumentsPreValidate( 59 'remove', convertObjectPermissionsToStrings); 60 apiFunctions.setUpdateArgumentsPreValidate( 61 'request', convertObjectPermissionsToStrings); 62 63 // Convert complex permissions back to objects 64 apiFunctions.setCustomCallback('getAll', 65 function(name, request, response) { 66 for (var i = 0; i < response.permissions.length; i += 1) { 67 response.permissions[i] = 68 maybeConvertToObject(response.permissions[i]); 69 } 70 71 // Since the schema says Permissions.permissions contains strings and 72 // not objects, validation will fail after the for-loop above. This 73 // skips validation and calls the callback directly, then clears it so 74 // that handleResponse doesn't call it again. 75 try { 76 if (request.callback) 77 $Function.apply(request.callback, request, [response]); 78 } finally { 79 delete request.callback; 80 } 81 }); 82 83 // Also convert complex permissions back to objects for events. The 84 // dispatchToListener call happens after argument validation, which works 85 // around the problem that Permissions.permissions is supposed to be a list 86 // of strings. 87 permissions.onAdded.dispatchToListener = function(callback, args) { 88 for (var i = 0; i < args[0].permissions.length; i += 1) { 89 args[0].permissions[i] = maybeConvertToObject(args[0].permissions[i]); 90 } 91 $Function.call(Event.prototype.dispatchToListener, this, callback, args); 92 }; 93 permissions.onRemoved.dispatchToListener = 94 permissions.onAdded.dispatchToListener; 95}); 96 97exports.binding = binding.generate(); 98