Home | History | Annotate | Download | only in resources
      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 
      7 var binding = require('binding').Binding.create('permissions');
      8 
      9 var 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.
     18 binding.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 
     97 exports.binding = binding.generate();
     98