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

Side by Side Diff: chrome/common/extensions/docs/server2/api_models.py

Issue 375133002: Docserver: Display API features that are available to content scripts (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nits Created 6 years, 5 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 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 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 import posixpath 5 import posixpath
6 6
7 from compiled_file_system import SingleFile, Unicode 7 from compiled_file_system import SingleFile, Unicode
8 from docs_server_utils import StringIdentity
9 from extensions_paths import API_PATHS 8 from extensions_paths import API_PATHS
10 from features_bundle import HasParentFeature 9 from features_bundle import HasParent, GetParentName
11 from file_system import FileNotFoundError 10 from file_system import FileNotFoundError
12 from future import Collect, Future 11 from future import Collect, Future
12 from operator import itemgetter
13 from platform_util import PlatformToExtensionType 13 from platform_util import PlatformToExtensionType
14 from schema_util import ProcessSchema 14 from schema_util import ProcessSchema
15 from third_party.json_schema_compiler.json_schema import DeleteNodes 15 from third_party.json_schema_compiler.json_schema import DeleteNodes
16 from third_party.json_schema_compiler.model import Namespace, UnixName 16 from third_party.json_schema_compiler.model import Namespace, UnixName
17 17
18 18
19 class ContentScriptAPI(object):
20 '''Represents an API available to content scripts.
21
22 |name| is the name of the API or API node this object represents.
23 |restrictedTo| is a list of dictionaries representing the nodes
24 of this API that are available to content scripts, or None if the
25 entire API is available to content scripts.
26 '''
27 def __init__(self, name):
28 self.name = name
29 self.restrictedTo = None
30
31 def __eq__(self, o):
32 return self.name == o.name and self.restrictedTo == o.restrictedTo
33
34 def __ne__(self, o):
35 return not (self == o)
36
37 def __repr__(self):
38 return '<ContentScriptAPI name=%s, restrictedTo=%s>' % (name, restrictedTo)
39
40 def __str__(self):
41 return repr(self)
42
43
19 class APIModels(object): 44 class APIModels(object):
20 '''Tracks APIs and their Models. 45 '''Tracks APIs and their Models.
21 ''' 46 '''
22 47
23 def __init__(self, 48 def __init__(self,
24 features_bundle, 49 features_bundle,
25 compiled_fs_factory, 50 compiled_fs_factory,
26 file_system, 51 file_system,
52 object_store_creator,
27 platform): 53 platform):
28 self._features_bundle = features_bundle 54 self._features_bundle = features_bundle
29 self._platform = PlatformToExtensionType(platform) 55 self._platform = PlatformToExtensionType(platform)
30 self._model_cache = compiled_fs_factory.Create( 56 self._model_cache = compiled_fs_factory.Create(
31 file_system, self._CreateAPIModel, APIModels, category=self._platform) 57 file_system, self._CreateAPIModel, APIModels, category=self._platform)
58 self._object_store = object_store_creator.Create(APIModels)
32 59
33 @SingleFile 60 @SingleFile
34 @Unicode 61 @Unicode
35 def _CreateAPIModel(self, path, data): 62 def _CreateAPIModel(self, path, data):
36 def does_not_include_platform(node): 63 def does_not_include_platform(node):
37 return ('extension_types' in node and 64 return ('extension_types' in node and
38 node['extension_types'] != 'all' and 65 node['extension_types'] != 'all' and
39 self._platform not in node['extension_types']) 66 self._platform not in node['extension_types'])
40 67
41 schema = ProcessSchema(path, data)[0] 68 schema = ProcessSchema(path, data)[0]
42 if not schema: 69 if not schema:
43 raise ValueError('No schema for %s' % path) 70 raise ValueError('No schema for %s' % path)
44 return Namespace(DeleteNodes( 71 return Namespace(DeleteNodes(
45 schema, matcher=does_not_include_platform), schema['namespace']) 72 schema, matcher=does_not_include_platform), schema['namespace'])
46 73
47 def GetNames(self): 74 def GetNames(self):
48 # API names appear alongside some of their methods/events/etc in the 75 # API names appear alongside some of their methods/events/etc in the
49 # features file. APIs are those which either implicitly or explicitly have 76 # features file. APIs are those which either implicitly or explicitly have
50 # no parent feature (e.g. app, app.window, and devtools.inspectedWindow are 77 # no parent feature (e.g. app, app.window, and devtools.inspectedWindow are
51 # APIs; runtime.onConnectNative is not). 78 # APIs; runtime.onConnectNative is not).
52 api_features = self._features_bundle.GetAPIFeatures().Get() 79 api_features = self._features_bundle.GetAPIFeatures().Get()
53 return [name for name, feature in api_features.iteritems() 80 return [name for name, feature in api_features.iteritems()
54 if not HasParentFeature(name, feature, api_features)] 81 if not HasParent(name, feature, api_features)]
55 82
56 def GetModel(self, api_name): 83 def GetModel(self, api_name):
57 # By default |api_name| is assumed to be given without a path or extension, 84 # By default |api_name| is assumed to be given without a path or extension,
58 # so combinations of known paths and extension types will be searched. 85 # so combinations of known paths and extension types will be searched.
59 api_extensions = ('.json', '.idl') 86 api_extensions = ('.json', '.idl')
60 api_paths = API_PATHS 87 api_paths = API_PATHS
61 88
62 # Callers sometimes include a file extension and/or prefix path with the 89 # Callers sometimes include a file extension and/or prefix path with the
63 # |api_name| argument. We believe them and narrow the search space 90 # |api_name| argument. We believe them and narrow the search space
64 # accordingly. 91 # accordingly.
(...skipping 25 matching lines...) Expand all
90 def resolve(): 117 def resolve():
91 for future in futures: 118 for future in futures:
92 try: 119 try:
93 return future.Get() 120 return future.Get()
94 # Either the file wasn't found or there was no schema for the file 121 # Either the file wasn't found or there was no schema for the file
95 except (FileNotFoundError, ValueError): pass 122 except (FileNotFoundError, ValueError): pass
96 # Propagate the first error if neither were found. 123 # Propagate the first error if neither were found.
97 futures[0].Get() 124 futures[0].Get()
98 return Future(callback=resolve) 125 return Future(callback=resolve)
99 126
127 def GetContentScriptAPIs(self):
128 '''Creates a dict of APIs and nodes supported by content scripts in
129 this format:
130
131 {
132 'extension': '<ContentScriptAPI name='extension',
133 restrictedTo=[{'node': 'onRequest'}]>',
134 ...
135 }
136 '''
137 content_script_apis_future = self._object_store.Get('content_script_apis')
138 api_features_future = self._features_bundle.GetAPIFeatures()
139 def resolve():
140 content_script_apis = content_script_apis_future.Get()
141 if content_script_apis is not None:
142 return content_script_apis
143
144 api_features = api_features_future.Get()
145 content_script_apis = {}
146 for name, feature in api_features.iteritems():
147 if 'content_script' not in feature.get('contexts', ()):
148 continue
149 parent = GetParentName(name, feature, api_features)
150 if parent is None:
151 content_script_apis[name] = ContentScriptAPI(name)
152 else:
153 # Creates a dict for the individual node.
154 node = {'node': name[len(parent) + 1:]}
155 if parent not in content_script_apis:
156 content_script_apis[parent] = ContentScriptAPI(parent)
157 if content_script_apis[parent].restrictedTo:
158 content_script_apis[parent].restrictedTo.append(node)
159 else:
160 content_script_apis[parent].restrictedTo = [node]
161
162 self._object_store.Set('content_script_apis', content_script_apis)
163 return content_script_apis
164 return Future(callback=resolve)
165
100 def Cron(self): 166 def Cron(self):
101 futures = [self.GetModel(name) for name in self.GetNames()] 167 futures = [self.GetModel(name) for name in self.GetNames()]
102 return Collect(futures, except_pass=(FileNotFoundError, ValueError)) 168 return Collect(futures, except_pass=(FileNotFoundError, ValueError))
103 169
104 def IterModels(self): 170 def IterModels(self):
105 future_models = [(name, self.GetModel(name)) for name in self.GetNames()] 171 future_models = [(name, self.GetModel(name)) for name in self.GetNames()]
106 for name, future_model in future_models: 172 for name, future_model in future_models:
107 try: 173 try:
108 model = future_model.Get() 174 model = future_model.Get()
109 except FileNotFoundError: 175 except FileNotFoundError:
110 continue 176 continue
111 if model: 177 if model:
112 yield name, model 178 yield name, model
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698