Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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 declarativeContent API.
      6 
      7 var binding = require('binding').Binding.create('declarativeContent');
      8 
      9 var utils = require('utils');
     10 var validate = require('schemaUtils').validate;
     11 var canonicalizeCompoundSelector =
     12     requireNative('css_natives').CanonicalizeCompoundSelector;
     13 var setIcon = require('setIcon').setIcon;
     14 
     15 binding.registerCustomHook( function(api) {
     16   var declarativeContent = api.compiledApi;
     17 
     18   // Returns the schema definition of type |typeId| defined in |namespace|.
     19   function getSchema(typeId) {
     20     return utils.lookup(api.schema.types,
     21                         'id',
     22                         'declarativeContent.' + typeId);
     23   }
     24 
     25   // Helper function for the constructor of concrete datatypes of the
     26   // declarative content API.
     27   // Makes sure that |this| contains the union of parameters and
     28   // {'instanceType': 'declarativeContent.' + typeId} and validates the
     29   // generated union dictionary against the schema for |typeId|.
     30   function setupInstance(instance, parameters, typeId) {
     31     for (var key in parameters) {
     32       if ($Object.hasOwnProperty(parameters, key)) {
     33         instance[key] = parameters[key];
     34       }
     35     }
     36     instance.instanceType = 'declarativeContent.' + typeId;
     37     var schema = getSchema(typeId);
     38     validate([instance], [schema]);
     39   }
     40 
     41   function canonicalizeCssSelectors(selectors) {
     42     for (var i = 0; i < selectors.length; i++) {
     43       var canonicalizedSelector = canonicalizeCompoundSelector(selectors[i]);
     44       if (canonicalizedSelector == '') {
     45         throw new Error(
     46             'Element of \'css\' array must be a ' +
     47             'list of valid compound selectors: ' +
     48             selectors[i]);
     49       }
     50       selectors[i] = canonicalizedSelector;
     51     }
     52   }
     53 
     54   // Setup all data types for the declarative content API.
     55   declarativeContent.PageStateMatcher = function(parameters) {
     56     setupInstance(this, parameters, 'PageStateMatcher');
     57     if ($Object.hasOwnProperty(this, 'css')) {
     58       canonicalizeCssSelectors(this.css);
     59     }
     60   };
     61   declarativeContent.ShowPageAction = function(parameters) {
     62     setupInstance(this, parameters, 'ShowPageAction');
     63   };
     64   declarativeContent.RequestContentScript = function(parameters) {
     65     setupInstance(this, parameters, 'RequestContentScript');
     66   };
     67   // TODO(rockot): Do not expose this in M39 stable. Making this restriction
     68   // possible will take some extra work. See http://crbug.com/415315
     69   declarativeContent.SetIcon = function(parameters) {
     70     setIcon(parameters, function (data) {
     71       setupInstance(this, data, 'SetIcon');
     72     }.bind(this));
     73   };
     74 });
     75 
     76 exports.binding = binding.generate();
     77