Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 8 from docs_server_utils import StringIdentity, MarkLast, MarkFirst |
| 9 from extensions_paths import API_PATHS | 9 from extensions_paths import API_PATHS |
| 10 from features_bundle import HasParentFeature | 10 from features_bundle import HasParentFeature, GetParentFeature |
| 11 from file_system import FileNotFoundError | 11 from file_system import FileNotFoundError |
| 12 from future import Collect, Future | 12 from future import Collect, Future |
| 13 from operator import itemgetter | |
| 13 from platform_util import PlatformToExtensionType | 14 from platform_util import PlatformToExtensionType |
| 14 from schema_util import ProcessSchema | 15 from schema_util import ProcessSchema |
| 15 from third_party.json_schema_compiler.json_schema import DeleteNodes | 16 from third_party.json_schema_compiler.json_schema import DeleteNodes |
| 16 from third_party.json_schema_compiler.model import Namespace, UnixName | 17 from third_party.json_schema_compiler.model import Namespace, UnixName |
| 17 | 18 |
| 18 | 19 |
| 20 class ContentScriptAPI(object): | |
| 21 '''Represents an API available to content scripts. | |
| 22 ''' | |
| 23 def __init__(self, name): | |
| 24 self.name = name | |
| 25 self.restrictedTo = [] | |
|
not at google - send to devlin
2014/07/10 17:31:27
I'd rather "nothing restricted" be modelled as Non
| |
| 26 | |
| 27 def get(self, key): | |
|
not at google - send to devlin
2014/07/10 17:31:27
exposing a "get" method is an implementation detai
ahernandez
2014/07/14 18:11:18
If this doesn't have a get() method, how can handl
not at google - send to devlin
2014/07/15 16:26:38
__dict__ returns a dict all of the properties of t
| |
| 28 if key == 'name': | |
| 29 return self.name | |
| 30 if key == 'restrictedTo': | |
| 31 return self.restrictedTo | |
| 32 raise AssertionError('%s: No such attribute' % key) | |
| 33 | |
| 34 def __eq__(self, o): | |
| 35 return self.name == o.name and self.restrictedTo == o.restrictedTo | |
| 36 | |
| 37 | |
| 19 class APIModels(object): | 38 class APIModels(object): |
| 20 '''Tracks APIs and their Models. | 39 '''Tracks APIs and their Models. |
| 21 ''' | 40 ''' |
| 22 | 41 |
| 23 def __init__(self, | 42 def __init__(self, |
| 24 features_bundle, | 43 features_bundle, |
| 25 compiled_fs_factory, | 44 compiled_fs_factory, |
| 26 file_system, | 45 file_system, |
| 46 object_store_creator, | |
| 27 platform): | 47 platform): |
| 28 self._features_bundle = features_bundle | 48 self._features_bundle = features_bundle |
| 29 self._platform = PlatformToExtensionType(platform) | 49 self._platform = PlatformToExtensionType(platform) |
| 30 self._model_cache = compiled_fs_factory.Create( | 50 self._model_cache = compiled_fs_factory.Create( |
| 31 file_system, self._CreateAPIModel, APIModels, category=self._platform) | 51 file_system, self._CreateAPIModel, APIModels, category=self._platform) |
| 52 self._object_store = object_store_creator.Create(APIModels) | |
| 32 | 53 |
| 33 @SingleFile | 54 @SingleFile |
| 34 @Unicode | 55 @Unicode |
| 35 def _CreateAPIModel(self, path, data): | 56 def _CreateAPIModel(self, path, data): |
| 36 def does_not_include_platform(node): | 57 def does_not_include_platform(node): |
| 37 return ('extension_types' in node and | 58 return ('extension_types' in node and |
| 38 node['extension_types'] != 'all' and | 59 node['extension_types'] != 'all' and |
| 39 self._platform not in node['extension_types']) | 60 self._platform not in node['extension_types']) |
| 40 | 61 |
| 41 schema = ProcessSchema(path, data, inline=True)[0] | 62 schema = ProcessSchema(path, data, inline=True)[0] |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 def resolve(): | 111 def resolve(): |
| 91 for future in futures: | 112 for future in futures: |
| 92 try: | 113 try: |
| 93 return future.Get() | 114 return future.Get() |
| 94 # Either the file wasn't found or there was no schema for the file | 115 # Either the file wasn't found or there was no schema for the file |
| 95 except (FileNotFoundError, ValueError): pass | 116 except (FileNotFoundError, ValueError): pass |
| 96 # Propagate the first error if neither were found. | 117 # Propagate the first error if neither were found. |
| 97 futures[0].Get() | 118 futures[0].Get() |
| 98 return Future(callback=resolve) | 119 return Future(callback=resolve) |
| 99 | 120 |
| 121 def GetContentScriptAPIs(self): | |
| 122 '''Creates a dict of APIs and nodes supported by content scripts in | |
| 123 this format: | |
| 124 | |
| 125 { | |
| 126 'extension': <ContentScriptAPI object>, | |
| 127 ... | |
| 128 } | |
| 129 | |
| 130 where a ContentScriptAPI object's restrictedTo attribute items look like: | |
| 131 | |
| 132 { | |
| 133 'parent': 'extension', | |
| 134 'node': 'sendMessage' | |
| 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 feature in api_features.itervalues(): | |
| 147 if 'content_script' not in feature.get('contexts', ()): | |
| 148 continue | |
| 149 parent = GetParentFeature(feature['name'], feature, api_features) | |
| 150 # If it has no parent, then the API is fully supported. | |
| 151 if parent is None: | |
| 152 content_script_apis[feature['name']] = ContentScriptAPI( | |
| 153 feature['name']) | |
| 154 else: | |
| 155 # Creates a dict for the individual node. | |
| 156 node = {'parent': parent, 'node': feature['name'][len(parent) + 1:]} | |
| 157 # Initializes the supportedNodes list if it doesn't exist yet. | |
| 158 if parent not in content_script_apis: | |
| 159 content_script_apis[parent] = ContentScriptAPI(parent) | |
| 160 content_script_apis[parent].restrictedTo.append(node) | |
| 161 | |
| 162 # Sort all of the supportedNodes. | |
|
not at google - send to devlin
2014/07/10 17:31:27
see comment at top of file.
| |
| 163 for content_script_api in content_script_apis.itervalues(): | |
| 164 restricted_nodes = content_script_api.restrictedTo | |
| 165 if restricted_nodes: | |
| 166 restricted_nodes.sort(key=itemgetter('node')) | |
| 167 MarkFirst(restricted_nodes) | |
| 168 MarkLast(restricted_nodes) | |
| 169 | |
| 170 self._object_store.Set('content_script_apis', content_script_apis) | |
| 171 return content_script_apis | |
| 172 return Future(callback=resolve) | |
| 173 | |
| 100 def Cron(self): | 174 def Cron(self): |
| 101 futures = [self.GetModel(name) for name in self.GetNames()] | 175 futures = [self.GetModel(name) for name in self.GetNames()] |
| 102 return Collect(futures, except_pass=(FileNotFoundError, ValueError)) | 176 return Collect(futures, except_pass=(FileNotFoundError, ValueError)) |
| 103 | 177 |
| 104 def IterModels(self): | 178 def IterModels(self): |
| 105 future_models = [(name, self.GetModel(name)) for name in self.GetNames()] | 179 future_models = [(name, self.GetModel(name)) for name in self.GetNames()] |
| 106 for name, future_model in future_models: | 180 for name, future_model in future_models: |
| 107 try: | 181 try: |
| 108 model = future_model.Get() | 182 model = future_model.Get() |
| 109 except FileNotFoundError: | 183 except FileNotFoundError: |
| 110 continue | 184 continue |
| 111 if model: | 185 if model: |
| 112 yield name, model | 186 yield name, model |
| OLD | NEW |