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

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

Issue 11315018: Extensions Docs Server: Generalize $ref's to work for any schema node (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup Created 8 years, 1 month 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 | Annotate | Revision Log
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 import copy 5 import copy
6 import json 6 import json
7 import logging
7 import os 8 import os
8 9
9 from docs_server_utils import GetLinkToRefType
10 import compiled_file_system as compiled_fs 10 import compiled_file_system as compiled_fs
11 from file_system import FileNotFoundError 11 from file_system import FileNotFoundError
12 import third_party.json_schema_compiler.json_comment_eater as json_comment_eater 12 import third_party.json_schema_compiler.json_comment_eater as json_comment_eater
13 import third_party.json_schema_compiler.model as model 13 import third_party.json_schema_compiler.model as model
14 import third_party.json_schema_compiler.idl_schema as idl_schema 14 import third_party.json_schema_compiler.idl_schema as idl_schema
15 import third_party.json_schema_compiler.idl_parser as idl_parser 15 import third_party.json_schema_compiler.idl_parser as idl_parser
16 16
17 # Increment this version when there are changes to the data stored in any of 17 # Increment this version when there are changes to the data stored in any of
18 # the caches used by APIDataSource. This allows the cache to be invalidated 18 # the caches used by APIDataSource. This allows the cache to be invalidated
19 # without having to flush memcache on the production server. 19 # without having to flush memcache on the production server.
20 _VERSION = 2 20 _VERSION = 3
21 21
22 def _RemoveNoDocs(item): 22 def _RemoveNoDocs(item):
23 if type(item) == dict: 23 if type(item) == dict:
24 if item.get('nodoc', False): 24 if item.get('nodoc', False):
25 return True 25 return True
26 to_remove = [] 26 to_remove = []
27 for key, value in item.items(): 27 for key, value in item.items():
28 if _RemoveNoDocs(value): 28 if _RemoveNoDocs(value):
29 to_remove.append(key) 29 to_remove.append(key)
30 for k in to_remove: 30 for k in to_remove:
(...skipping 11 matching lines...) Expand all
42 if node.parent is not None and not isinstance(node.parent, model.Namespace): 42 if node.parent is not None and not isinstance(node.parent, model.Namespace):
43 return '-'.join([prefix, node.parent.simple_name, node.simple_name]) 43 return '-'.join([prefix, node.parent.simple_name, node.simple_name])
44 return '-'.join([prefix, node.simple_name]) 44 return '-'.join([prefix, node.simple_name])
45 45
46 def _FormatValue(value): 46 def _FormatValue(value):
47 """Inserts commas every three digits for integer values. It is magic. 47 """Inserts commas every three digits for integer values. It is magic.
48 """ 48 """
49 s = str(value) 49 s = str(value)
50 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) 50 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1])
51 51
52 class _JscModel(object): 52 class _JSCModel(object):
53 """Uses a Model from the JSON Schema Compiler and generates a dict that 53 """Uses a Model from the JSON Schema Compiler and generates a dict that
54 a Handlebar template can use for a data source. 54 a Handlebar template can use for a data source.
55 """ 55 """
56 def __init__(self, json): 56 def __init__(self, json, ref_resolver, disable_refs):
57 self._ref_resolver = ref_resolver
58 self._disable_refs = disable_refs
57 clean_json = copy.deepcopy(json) 59 clean_json = copy.deepcopy(json)
58 if _RemoveNoDocs(clean_json): 60 if _RemoveNoDocs(clean_json):
59 self._namespace = None 61 self._namespace = None
60 else: 62 else:
61 self._namespace = model.Namespace(clean_json, clean_json['namespace']) 63 self._namespace = model.Namespace(clean_json, clean_json['namespace'])
62 64
65 def _GetLink(self, ref):
66 if not self._disable_refs:
67 ref_data = self._ref_resolver.GetLink(self._namespace.name, ref)
68 if ref_data is not None:
69 return ref_data
70 logging.error('$ref %s could not be resolved.' % ref)
71 if '.' in ref:
72 type_name = ref.rsplit('.', 1)[-1]
73 else:
74 type_name = ref
75 return { 'href': '#type-%s' % type_name, 'text': ref }
76
63 def _FormatDescription(self, description): 77 def _FormatDescription(self, description):
64 if description is None or '$ref:' not in description: 78 if description is None or '$ref:' not in description:
65 return description 79 return description
66 refs = description.split('$ref:') 80 refs = description.split('$ref:')
67 formatted_description = [refs[0]] 81 formatted_description = [refs[0]]
68 for ref in refs[1:]: 82 for ref in refs[1:]:
69 parts = ref.split(' ', 1) 83 parts = ref.split(' ', 1)
70 if len(parts) == 1: 84 if len(parts) == 1:
71 ref = parts[0] 85 ref = parts[0]
72 rest = '' 86 rest = ''
73 else: 87 else:
74 ref, rest = parts 88 ref, rest = parts
75 rest = ' ' + rest 89 rest = ' ' + rest
76 if not ref[-1].isalnum(): 90 if not ref[-1].isalnum():
77 rest = ref[-1] + rest 91 rest = ref[-1] + rest
78 ref = ref[:-1] 92 ref = ref[:-1]
79 ref_dict = GetLinkToRefType(self._namespace.name, ref) 93 ref_dict = self._GetLink(ref)
80 formatted_description.append('<a href="%(href)s">%(text)s</a>%(rest)s' % 94 formatted_description.append('<a href="%(href)s">%(text)s</a>%(rest)s' %
81 { 'href': ref_dict['href'], 'text': ref_dict['text'], 'rest': rest }) 95 { 'href': ref_dict['href'], 'text': ref_dict['text'], 'rest': rest })
82 return ''.join(formatted_description) 96 return ''.join(formatted_description)
83 97
84 def ToDict(self): 98 def ToDict(self):
85 if self._namespace is None: 99 if self._namespace is None:
86 return {} 100 return {}
87 return { 101 return {
88 'name': self._namespace.name, 102 'name': self._namespace.name,
89 'types': [self._GenerateType(t) for t in self._namespace.types.values() 103 'types': [self._GenerateType(t) for t in self._namespace.types.values()
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 function_dict['parameters'][-1]['last'] = True 146 function_dict['parameters'][-1]['last'] = True
133 return function_dict 147 return function_dict
134 148
135 def _GenerateEvents(self, events): 149 def _GenerateEvents(self, events):
136 return [self._GenerateEvent(e) for e in events.values()] 150 return [self._GenerateEvent(e) for e in events.values()]
137 151
138 def _GenerateEvent(self, event): 152 def _GenerateEvent(self, event):
139 event_dict = { 153 event_dict = {
140 'name': event.simple_name, 154 'name': event.simple_name,
141 'description': self._FormatDescription(event.description), 155 'description': self._FormatDescription(event.description),
142 'parameters': map(self._GenerateProperty, event.params), 156 'parameters': [self._GenerateProperty(p) for p in event.params],
143 'callback': self._GenerateCallback(event.callback), 157 'callback': self._GenerateCallback(event.callback),
144 'conditions': [GetLinkToRefType(self._namespace.name, c) 158 'filters': [self._GenerateProperty(f) for f in event.filters],
145 for c in event.conditions], 159 'conditions': [self._GetLink(condition)
146 'actions': [GetLinkToRefType(self._namespace.name, a) 160 for condition in event.conditions],
147 for a in event.actions], 161 'actions': [self._GetLink(action) for action in event.actions],
148 'filters': map(self._GenerateProperty, event.filters),
149 'supportsRules': event.supports_rules, 162 'supportsRules': event.supports_rules,
150 'id': _CreateId(event, 'event') 163 'id': _CreateId(event, 'event')
151 } 164 }
152 if (event.parent is not None and 165 if (event.parent is not None and
153 not isinstance(event.parent, model.Namespace)): 166 not isinstance(event.parent, model.Namespace)):
154 event_dict['parent_name'] = event.parent.simple_name 167 event_dict['parent_name'] = event.parent.simple_name
155 else: 168 else:
156 event_dict['parent_name'] = None 169 event_dict['parent_name'] = None
157 if event_dict['callback']: 170 if event_dict['callback']:
158 event_dict['parameters'].append(event_dict['callback']) 171 event_dict['parameters'].append(event_dict['callback'])
(...skipping 20 matching lines...) Expand all
179 def _GenerateProperties(self, properties): 192 def _GenerateProperties(self, properties):
180 return [self._GenerateProperty(v) for v in properties.values() 193 return [self._GenerateProperty(v) for v in properties.values()
181 if v.type_ != model.PropertyType.ADDITIONAL_PROPERTIES] 194 if v.type_ != model.PropertyType.ADDITIONAL_PROPERTIES]
182 195
183 def _GenerateProperty(self, property_): 196 def _GenerateProperty(self, property_):
184 property_dict = { 197 property_dict = {
185 'name': property_.simple_name, 198 'name': property_.simple_name,
186 'optional': property_.optional, 199 'optional': property_.optional,
187 'description': self._FormatDescription(property_.description), 200 'description': self._FormatDescription(property_.description),
188 'properties': self._GenerateProperties(property_.properties), 201 'properties': self._GenerateProperties(property_.properties),
202 'functions': self._GenerateFunctions(property_.functions),
189 'parameters': [], 203 'parameters': [],
190 'functions': self._GenerateFunctions(property_.functions),
191 'returns': None, 204 'returns': None,
192 'id': _CreateId(property_, 'property') 205 'id': _CreateId(property_, 'property')
193 } 206 }
194 for param in property_.params: 207 for param in property_.params:
195 property_dict['parameters'].append(self._GenerateProperty(param)) 208 property_dict['parameters'].append(self._GenerateProperty(param))
196 if property_.returns: 209 if property_.returns:
197 property_dict['returns'] = self._GenerateProperty(property_.returns) 210 property_dict['returns'] = self._GenerateProperty(property_.returns)
198 if (property_.parent is not None and 211 if (property_.parent is not None and
199 not isinstance(property_.parent, model.Namespace)): 212 not isinstance(property_.parent, model.Namespace)):
200 property_dict['parent_name'] = property_.parent.simple_name 213 property_dict['parent_name'] = property_.parent.simple_name
201 else: 214 else:
202 property_dict['parent_name'] = None 215 property_dict['parent_name'] = None
203 if property_.has_value: 216 if property_.has_value:
204 if isinstance(property_.value, int): 217 if isinstance(property_.value, int):
205 property_dict['value'] = _FormatValue(property_.value) 218 property_dict['value'] = _FormatValue(property_.value)
206 else: 219 else:
207 property_dict['value'] = property_.value 220 property_dict['value'] = property_.value
208 else: 221 else:
209 self._RenderTypeInformation(property_, property_dict) 222 self._RenderTypeInformation(property_, property_dict)
210 return property_dict 223 return property_dict
211 224
212 def _RenderTypeInformation(self, property_, dst_dict): 225 def _RenderTypeInformation(self, property_, dst_dict):
213 if property_.type_ == model.PropertyType.CHOICES: 226 if property_.type_ == model.PropertyType.CHOICES:
214 dst_dict['choices'] = map(self._GenerateProperty, 227 dst_dict['choices'] = [self._GenerateProperty(c)
215 property_.choices.values()) 228 for c in property_.choices.values()]
216 # We keep track of which is last for knowing when to add "or" between 229 # We keep track of which is last for knowing when to add "or" between
217 # choices in templates. 230 # choices in templates.
218 if len(dst_dict['choices']) > 0: 231 if len(dst_dict['choices']) > 0:
219 dst_dict['choices'][-1]['last'] = True 232 dst_dict['choices'][-1]['last'] = True
220 elif property_.type_ == model.PropertyType.REF: 233 elif property_.type_ == model.PropertyType.REF:
221 dst_dict['link'] = GetLinkToRefType(self._namespace.name, 234 dst_dict['link'] = self._GetLink(property_.ref_type)
222 property_.ref_type)
223 elif property_.type_ == model.PropertyType.ARRAY: 235 elif property_.type_ == model.PropertyType.ARRAY:
224 dst_dict['array'] = self._GenerateProperty(property_.item_type) 236 dst_dict['array'] = self._GenerateProperty(property_.item_type)
225 elif property_.type_ == model.PropertyType.ENUM: 237 elif property_.type_ == model.PropertyType.ENUM:
226 dst_dict['enum_values'] = [] 238 dst_dict['enum_values'] = []
227 for enum_value in property_.enum_values: 239 for enum_value in property_.enum_values:
228 dst_dict['enum_values'].append({'name': enum_value}) 240 dst_dict['enum_values'].append({'name': enum_value})
229 if len(dst_dict['enum_values']) > 0: 241 if len(dst_dict['enum_values']) > 0:
230 dst_dict['enum_values'][-1]['last'] = True 242 dst_dict['enum_values'][-1]['last'] = True
231 elif property_.instance_of is not None: 243 elif property_.instance_of is not None:
232 dst_dict['simple_type'] = property_.instance_of.lower() 244 dst_dict['simple_type'] = property_.instance_of.lower()
233 else: 245 else:
234 dst_dict['simple_type'] = property_.type_.name.lower() 246 dst_dict['simple_type'] = property_.type_.name.lower()
235 247
236 class _LazySamplesGetter(object): 248 class _LazySamplesGetter(object):
237 """This class is needed so that an extensions API page does not have to fetch 249 """This class is needed so that an extensions API page does not have to fetch
238 the apps samples page and vice versa. 250 the apps samples page and vice versa.
239 """ 251 """
240 def __init__(self, api_name, samples): 252 def __init__(self, api_name, samples):
241 self._api_name = api_name 253 self._api_name = api_name
242 self._samples = samples 254 self._samples = samples
243 255
244 def get(self, key): 256 def get(self, key):
245 return self._samples.FilterSamples(key, self._api_name) 257 return self._samples.FilterSamples(key, self._api_name)
246 258
247 class APIDataSource(object): 259 class APIDataSource(object):
248 """This class fetches and loads JSON APIs from the FileSystem passed in with 260 """This class fetches and loads JSON APIs from the FileSystem passed in with
249 |cache_factory|, so the APIs can be plugged into templates. 261 |cache_factory|, so the APIs can be plugged into templates.
250 """ 262 """
251 class Factory(object): 263 class Factory(object):
252 def __init__(self, cache_factory, base_path, samples_factory): 264 def __init__(self,
265 cache_factory,
266 base_path):
253 self._permissions_cache = cache_factory.Create(self._LoadPermissions, 267 self._permissions_cache = cache_factory.Create(self._LoadPermissions,
254 compiled_fs.PERMS, 268 compiled_fs.PERMS,
255 version=_VERSION) 269 version=_VERSION)
256 self._json_cache = cache_factory.Create(self._LoadJsonAPI, 270 self._json_cache = cache_factory.Create(
257 compiled_fs.JSON, 271 lambda api: self._LoadJsonAPI(api, False),
258 version=_VERSION) 272 compiled_fs.JSON,
259 self._idl_cache = cache_factory.Create(self._LoadIdlAPI, 273 version=_VERSION)
260 compiled_fs.IDL, 274 self._idl_cache = cache_factory.Create(
261 version=_VERSION) 275 lambda api: self._LoadIdlAPI(api, False),
276 compiled_fs.IDL,
277 version=_VERSION)
278
279 # These caches are used if an APIDataSource does not want to resolve the
280 # $refs in an API. This is needed to prevent infinite recursion in
281 # ReferenceResolver.
282 self._json_cache_no_refs = cache_factory.Create(
283 lambda api: self._LoadJsonAPI(api, True),
284 compiled_fs.JSON_NO_REFS,
285 version=_VERSION)
286 self._idl_cache_no_refs = cache_factory.Create(
287 lambda api: self._LoadIdlAPI(api, True),
288 compiled_fs.IDL_NO_REFS,
289 version=_VERSION)
262 self._idl_names_cache = cache_factory.Create(self._GetIDLNames, 290 self._idl_names_cache = cache_factory.Create(self._GetIDLNames,
263 compiled_fs.IDL_NAMES, 291 compiled_fs.IDL_NAMES,
264 version=_VERSION) 292 version=_VERSION)
265 self._samples_factory = samples_factory 293 self._names_cache = cache_factory.Create(self._GetAllNames,
294 compiled_fs.NAMES,
295 version=_VERSION)
266 self._base_path = base_path 296 self._base_path = base_path
267 297
268 def Create(self, request): 298 # These must be set later via the SetFooDataSourceFactory methods.
299 self._ref_resolver_factory = None
300 self._samples_data_source_factory = None
301
302 def SetSamplesDataSourceFactory(self, samples_data_source_factory):
303 self._samples_data_source_factory = samples_data_source_factory
304
305 def SetReferenceResolverFactory(self, ref_resolver_factory):
306 self._ref_resolver_factory = ref_resolver_factory
307
308 def Create(self, request, disable_refs=False):
309 """Create an APIDataSource. |disable_refs| specifies whether $ref's in
310 APIs being processed by the |ToDict| method of _JSCModel follows $ref's
311 in the API. This prevents endless recursion in ReferenceResolver.
312 """
313 if self._samples_data_source_factory is None:
314 # Only error if there is a request, which means this APIDataSource is
315 # actually being used to render a page.
316 if request is not None:
317 logging.error('SamplesDataSource.Factory was never set in '
318 'APIDataSource.Factory.')
319 samples = None
320 else:
321 samples = self._samples_data_source_factory.Create(request)
322 if not disable_refs and self._ref_resolver_factory is None:
323 logging.error('ReferenceResolver.Factory was never set in '
324 'APIDataSource.Factory.')
269 return APIDataSource(self._permissions_cache, 325 return APIDataSource(self._permissions_cache,
270 self._json_cache, 326 self._json_cache,
271 self._idl_cache, 327 self._idl_cache,
328 self._json_cache_no_refs,
329 self._idl_cache_no_refs,
330 self._names_cache,
272 self._idl_names_cache, 331 self._idl_names_cache,
273 self._base_path, 332 self._base_path,
274 self._samples_factory.Create(request)) 333 samples,
334 disable_refs)
275 335
276 def _LoadPermissions(self, json_str): 336 def _LoadPermissions(self, json_str):
277 return json.loads(json_comment_eater.Nom(json_str)) 337 return json.loads(json_comment_eater.Nom(json_str))
278 338
279 def _LoadJsonAPI(self, api): 339 def _LoadJsonAPI(self, api, disable_refs):
280 return _JscModel(json.loads(json_comment_eater.Nom(api))[0]) 340 return _JSCModel(
341 json.loads(json_comment_eater.Nom(api))[0],
342 self._ref_resolver_factory.Create() if not disable_refs else None,
343 disable_refs).ToDict()
281 344
282 def _LoadIdlAPI(self, api): 345 def _LoadIdlAPI(self, api, disable_refs):
283 idl = idl_parser.IDLParser().ParseData(api) 346 idl = idl_parser.IDLParser().ParseData(api)
284 return _JscModel(idl_schema.IDLSchema(idl).process()[0]) 347 return _JSCModel(
348 idl_schema.IDLSchema(idl).process()[0],
349 self._ref_resolver_factory.Create() if not disable_refs else None,
350 disable_refs).ToDict()
285 351
286 def _GetIDLNames(self, apis): 352 def _GetIDLNames(self, apis):
287 return [model.UnixName(os.path.splitext(api.split('/')[-1])[0]) 353 return [
288 for api in apis if api.endswith('.idl')] 354 model.UnixName(os.path.splitext(api[len('%s/' % self._base_path):])[0])
355 for api in apis if api.endswith('.idl')
356 ]
357
358 def _GetAllNames(self, apis):
359 return [
360 model.UnixName(os.path.splitext(api[len('%s/' % self._base_path):])[0])
361 for api in apis
362 ]
289 363
290 def __init__(self, 364 def __init__(self,
291 permissions_cache, 365 permissions_cache,
292 json_cache, 366 json_cache,
293 idl_cache, 367 idl_cache,
368 json_cache_no_refs,
369 idl_cache_no_refs,
370 names_cache,
294 idl_names_cache, 371 idl_names_cache,
295 base_path, 372 base_path,
296 samples): 373 samples,
374 disable_refs):
297 self._base_path = base_path 375 self._base_path = base_path
298 self._permissions_cache = permissions_cache 376 self._permissions_cache = permissions_cache
299 self._json_cache = json_cache 377 self._json_cache = json_cache
300 self._idl_cache = idl_cache 378 self._idl_cache = idl_cache
379 self._json_cache_no_refs = json_cache_no_refs
380 self._idl_cache_no_refs = idl_cache_no_refs
381 self._names_cache = names_cache
301 self._idl_names_cache = idl_names_cache 382 self._idl_names_cache = idl_names_cache
302 self._samples = samples 383 self._samples = samples
384 self._disable_refs = disable_refs
303 385
304 def _GetPermsFromFile(self, filename): 386 def _GetPermsFromFile(self, filename):
305 try: 387 try:
306 perms = self._permissions_cache.GetFromFile('%s/%s' % 388 perms = self._permissions_cache.GetFromFile('%s/%s' %
307 (self._base_path, filename)) 389 (self._base_path, filename))
308 return dict((model.UnixName(k), v) for k, v in perms.iteritems()) 390 return dict((model.UnixName(k), v) for k, v in perms.iteritems())
309 except FileNotFoundError: 391 except FileNotFoundError:
310 return {} 392 return {}
311 393
312 def _GetFeature(self, path): 394 def _GetFeature(self, path):
313 # Remove 'experimental_' from path name to match the keys in 395 # Remove 'experimental_' from path name to match the keys in
314 # _permissions_features.json. 396 # _permissions_features.json.
315 path = model.UnixName(path.replace('experimental_', '')) 397 path = model.UnixName(path.replace('experimental_', ''))
316 for filename in ['_permission_features.json', '_manifest_features.json']: 398 for filename in ['_permission_features.json', '_manifest_features.json']:
317 api_perms = self._GetPermsFromFile(filename).get(path, None) 399 api_perms = self._GetPermsFromFile(filename).get(path, None)
318 if api_perms is not None: 400 if api_perms is not None:
319 break 401 break
320 if api_perms and api_perms['channel'] in ('trunk', 'dev', 'beta'): 402 if api_perms and api_perms['channel'] in ('trunk', 'dev', 'beta'):
321 api_perms[api_perms['channel']] = True 403 api_perms[api_perms['channel']] = True
322 return api_perms 404 return api_perms
323 405
324 def _GenerateHandlebarContext(self, handlebar, path): 406 def _GenerateHandlebarContext(self, handlebar_dict, path):
325 return_dict = { 407 return_dict = {
326 'permissions': self._GetFeature(path), 408 'permissions': self._GetFeature(path),
327 'samples': _LazySamplesGetter(path, self._samples) 409 'samples': _LazySamplesGetter(path, self._samples)
328 } 410 }
329 return_dict.update(handlebar.ToDict()) 411 return_dict.update(handlebar_dict)
330 return return_dict 412 return return_dict
331 413
332 def __getitem__(self, key): 414 def _GetAsSubdirectory(self, name):
333 return self.get(key) 415 if name.startswith('experimental_'):
416 parts = name[len('experimental_'):].split('_', 1)
417 parts[1] = 'experimental_%s' % parts[1]
418 return '/'.join(parts)
419 return name.replace('_', '/', 1)
334 420
335 def get(self, key): 421 def get(self, key):
336 path, ext = os.path.splitext(key) 422 if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'):
423 path, ext = os.path.splitext(key)
424 else:
425 path = key
337 unix_name = model.UnixName(path) 426 unix_name = model.UnixName(path)
338 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path) 427 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path)
339 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else 428 names = self._names_cache.GetFromFileListing(self._base_path)
340 (self._json_cache, '.json')) 429 if unix_name not in names and self._GetAsSubdirectory(unix_name) in names:
430 unix_name = self._GetAsSubdirectory(unix_name)
431
432 if self._disable_refs:
433 cache, ext = (
434 (self._idl_cache_no_refs, '.idl') if (unix_name in idl_names) else
435 (self._json_cache_no_refs, '.json'))
436 else:
437 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else
438 (self._json_cache, '.json'))
341 return self._GenerateHandlebarContext( 439 return self._GenerateHandlebarContext(
342 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)), 440 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)),
343 path) 441 path)
OLDNEW
« no previous file with comments | « chrome/common/extensions/api/privacy.json ('k') | chrome/common/extensions/docs/server2/api_data_source_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698