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

Side by Side Diff: chrome/renderer/resources/extensions/declarative_content_custom_bindings.js

Issue 2853023002: [Extensions Bindings] Add native declarativeContent verification (Closed)
Patch Set: jbroman's Created 3 years, 7 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) 2012 The Chromium Authors. All rights reserved. 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 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 // Custom binding for the declarativeContent API. 5 // Custom binding for the declarativeContent API.
6 6
7 var binding = 7 var binding =
8 apiBridge || require('binding').Binding.create('declarativeContent'); 8 apiBridge || require('binding').Binding.create('declarativeContent');
9 9
10 var utils = require('utils'); 10 if (!apiBridge) {
11 var validate = require('schemaUtils').validate; 11 var utils = require('utils');
12 var canonicalizeCompoundSelector = 12 var validate = require('schemaUtils').validate;
13 requireNative('css_natives').CanonicalizeCompoundSelector; 13 var canonicalizeCompoundSelector =
14 requireNative('css_natives').CanonicalizeCompoundSelector;
15 }
16
14 var setIcon = require('setIcon').setIcon; 17 var setIcon = require('setIcon').setIcon;
15 18
16 binding.registerCustomHook(function(api) { 19 binding.registerCustomHook(function(api) {
17 var declarativeContent = api.compiledApi; 20 var declarativeContent = api.compiledApi;
18 21
22 if (apiBridge) {
23 // Validation for most types is done in the native C++ with native bindings,
24 // but setIcon is funny (and sadly broken). Ideally, we can move this
25 // validation entirely into the native code, and this whole file can go
26 // away.
27 var nativeSetIcon = declarativeContent.SetIcon;
28 declarativeContent.SetIcon = function(parameters) {
29 // TODO(devlin): This is very, very wrong. setIcon() is potentially
30 // asynchronous (in the case of a path being specified), which means this
31 // becomes an "asynchronous constructor". Errors can be thrown *after* the
32 // `new declarativeContent.SetIcon(...)` call, and in the async cases,
33 // this wouldn't work when we immediately add the action via an API call
34 // (e.g.,
35 // chrome.declarativeContent.onPageChange.addRules(
36 // [{conditions: ..., actions: [ new SetIcon(...) ]}]);
37 // ). Some of this is tracked in http://crbug.com/415315.
38 setIcon(parameters, $Function.bind(function (data) {
39 // Fake calling the original function as a constructor.
jbroman 2017/05/02 18:36:33 Yeah, eww. Can't think of something better, short
Devlin 2017/05/02 20:51:43 Yep. :/ See also the note in declarative_content_
40 this.__proto__ = nativeSetIcon.prototype;
jbroman 2017/05/02 18:36:33 This can run author script, like this: Object.def
Devlin 2017/05/02 20:51:43 Wild. Wouldn't have expected that. Fixed; thanks
41 $Function.apply(nativeSetIcon, this, [data]);
42 }, this));
43 };
44 return;
45 }
46
19 // Returns the schema definition of type |typeId| defined in |namespace|. 47 // Returns the schema definition of type |typeId| defined in |namespace|.
20 function getSchema(typeId) { 48 function getSchema(typeId) {
21 return utils.lookup(api.schema.types, 49 return utils.lookup(api.schema.types,
22 'id', 50 'id',
23 'declarativeContent.' + typeId); 51 'declarativeContent.' + typeId);
24 } 52 }
25 53
26 // Helper function for the constructor of concrete datatypes of the 54 // Helper function for the constructor of concrete datatypes of the
27 // declarative content API. 55 // declarative content API.
28 // Makes sure that |this| contains the union of parameters and 56 // Makes sure that |this| contains the union of parameters and
29 // {'instanceType': 'declarativeContent.' + typeId} and validates the 57 // {'instanceType': 'declarativeContent.' + typeId} and validates the
30 // generated union dictionary against the schema for |typeId|. 58 // generated union dictionary against the schema for |typeId|.
31 function setupInstance(instance, parameters, typeId) { 59 function setupInstance(instance, parameters, typeId) {
32 for (var key in parameters) { 60 for (var key in parameters) {
33 if ($Object.hasOwnProperty(parameters, key)) { 61 if ($Object.hasOwnProperty(parameters, key)) {
34 instance[key] = parameters[key]; 62 instance[key] = parameters[key];
35 } 63 }
36 } 64 }
37 instance.instanceType = 'declarativeContent.' + typeId; 65 instance.instanceType = 'declarativeContent.' + typeId;
38 // TODO(devlin): This is wrong. It means we don't validate the construction 66 var schema = getSchema(typeId);
39 // of the instance (which really only matters for PageStateMatcher). 67 validate([instance], [schema]);
40 // Currently, we don't pass the schema to JS with native bindings because
41 // validation should be done natively. We'll need to fix this by either
42 // allowing some validation to occur in JS, or by moving the instantiation
43 // of these types to native code.
44 if (!apiBridge) {
45 var schema = getSchema(typeId);
46 validate([instance], [schema]);
47 }
48 } 68 }
49 69
50 function canonicalizeCssSelectors(selectors) { 70 function canonicalizeCssSelectors(selectors) {
51 for (var i = 0; i < selectors.length; i++) { 71 for (var i = 0; i < selectors.length; i++) {
52 var canonicalizedSelector = canonicalizeCompoundSelector(selectors[i]); 72 var canonicalizedSelector = canonicalizeCompoundSelector(selectors[i]);
53 if (canonicalizedSelector == '') { 73 if (canonicalizedSelector == '') {
54 throw new Error( 74 throw new Error(
55 'Element of \'css\' array must be a ' + 75 'Element of \'css\' array must be a ' +
56 'list of valid compound selectors: ' + 76 'list of valid compound selectors: ' +
57 selectors[i]); 77 selectors[i]);
(...skipping 10 matching lines...) Expand all
68 } 88 }
69 }; 89 };
70 declarativeContent.ShowPageAction = function(parameters) { 90 declarativeContent.ShowPageAction = function(parameters) {
71 setupInstance(this, parameters, 'ShowPageAction'); 91 setupInstance(this, parameters, 'ShowPageAction');
72 }; 92 };
73 declarativeContent.RequestContentScript = function(parameters) { 93 declarativeContent.RequestContentScript = function(parameters) {
74 setupInstance(this, parameters, 'RequestContentScript'); 94 setupInstance(this, parameters, 'RequestContentScript');
75 }; 95 };
76 // TODO(rockot): Do not expose this in M39 stable. Making this restriction 96 // TODO(rockot): Do not expose this in M39 stable. Making this restriction
77 // possible will take some extra work. See http://crbug.com/415315 97 // possible will take some extra work. See http://crbug.com/415315
98 // Note: See also the SetIcon wrapper above for more issues.
78 declarativeContent.SetIcon = function(parameters) { 99 declarativeContent.SetIcon = function(parameters) {
79 setIcon(parameters, function (data) { 100 setIcon(parameters, $Function.bind(function(data) {
jbroman 2017/05/02 18:36:33 Good catch. :)
80 setupInstance(this, data, 'SetIcon'); 101 setupInstance(this, data, 'SetIcon');
81 }.bind(this)); 102 }, this));
82 }; 103 };
83 }); 104 });
84 105
85 if (!apiBridge) 106 if (!apiBridge)
86 exports.$set('binding', binding.generate()); 107 exports.$set('binding', binding.generate());
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698