OLD | NEW |
---|---|
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 logging | 6 import logging |
7 import os | 7 import os |
8 import posixpath | 8 import posixpath |
9 | 9 |
10 from environment import IsPreviewServer | 10 from environment import IsPreviewServer |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 | 61 |
62 | 62 |
63 class _JSCModel(object): | 63 class _JSCModel(object): |
64 '''Uses a Model from the JSON Schema Compiler and generates a dict that | 64 '''Uses a Model from the JSON Schema Compiler and generates a dict that |
65 a Handlebar template can use for a data source. | 65 a Handlebar template can use for a data source. |
66 ''' | 66 ''' |
67 | 67 |
68 def __init__(self, | 68 def __init__(self, |
69 api_name, | 69 api_name, |
70 api_models, | 70 api_models, |
71 ref_resolver, | |
72 disable_refs, | 71 disable_refs, |
73 availability_finder, | 72 availability_finder, |
74 json_cache, | 73 json_cache, |
75 template_cache, | 74 template_cache, |
76 features_bundle, | 75 features_bundle, |
77 event_byname_function): | 76 event_byname_function): |
78 self._ref_resolver = ref_resolver | |
79 self._disable_refs = disable_refs | 77 self._disable_refs = disable_refs |
80 self._availability_finder = availability_finder | 78 self._availability_finder = availability_finder |
81 self._api_availabilities = json_cache.GetFromFile( | 79 self._api_availabilities = json_cache.GetFromFile( |
82 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) | 80 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) |
83 self._intro_tables = json_cache.GetFromFile( | 81 self._intro_tables = json_cache.GetFromFile( |
84 posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) | 82 posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) |
85 self._api_features = features_bundle.GetAPIFeatures() | 83 self._api_features = features_bundle.GetAPIFeatures() |
86 self._template_cache = template_cache | 84 self._template_cache = template_cache |
87 self._event_byname_function = event_byname_function | 85 self._event_byname_function = event_byname_function |
88 self._namespace = api_models.GetModel(api_name).Get() | 86 self._namespace = api_models.GetModel(api_name).Get() |
89 | 87 |
90 def _FormatDescription(self, description): | |
91 if self._disable_refs: | |
92 return description | |
93 return self._ref_resolver.ResolveAllLinks(description, | |
94 namespace=self._namespace.name) | |
95 | |
96 def _GetLink(self, link): | 88 def _GetLink(self, link): |
97 if self._disable_refs: | 89 text = link |
98 type_name = link.split('.', 1)[-1] | 90 if '.' not in link: |
99 return { 'href': '#type-%s' % type_name, 'text': link, 'name': link } | 91 link = self._namespace.name + '.' + link |
100 return self._ref_resolver.SafeGetLink(link, namespace=self._namespace.name) | 92 return { 'ref': link, 'text': text, 'name': text } |
ahernandez
2014/03/28 22:47:30
Is this what we want?
not at google - send to devlin
2014/03/28 23:02:18
are you sure that 'ref' shouldn't be 'href'?
the
ahernandez
2014/03/28 23:10:55
ReferenceResolver needs the 'name' field for some
ahernandez
2014/03/28 23:13:56
I'm pretty sure that same link stuff is used here:
not at google - send to devlin
2014/03/28 23:24:30
I see. Yes that looks like the case. Usually this
| |
101 | 93 |
102 def ToDict(self): | 94 def ToDict(self): |
103 if self._namespace is None: | 95 if self._namespace is None: |
104 return {} | 96 return {} |
105 chrome_dot_name = 'chrome.%s' % self._namespace.name | 97 chrome_dot_name = 'chrome.%s' % self._namespace.name |
106 as_dict = { | 98 as_dict = { |
107 'name': self._namespace.name, | 99 'name': self._namespace.name, |
108 'namespace': self._namespace.documentation_options.get('namespace', | 100 'namespace': self._namespace.documentation_options.get('namespace', |
109 chrome_dot_name), | 101 chrome_dot_name), |
110 'title': self._namespace.documentation_options.get('title', | 102 'title': self._namespace.documentation_options.get('title', |
(...skipping 27 matching lines...) Expand all Loading... | |
138 | 130 |
139 def _IsExperimental(self): | 131 def _IsExperimental(self): |
140 return self._namespace.name.startswith('experimental') | 132 return self._namespace.name.startswith('experimental') |
141 | 133 |
142 def _GenerateTypes(self, types): | 134 def _GenerateTypes(self, types): |
143 return [self._GenerateType(t) for t in types] | 135 return [self._GenerateType(t) for t in types] |
144 | 136 |
145 def _GenerateType(self, type_): | 137 def _GenerateType(self, type_): |
146 type_dict = { | 138 type_dict = { |
147 'name': type_.simple_name, | 139 'name': type_.simple_name, |
148 'description': self._FormatDescription(type_.description), | 140 'description': type_.description, |
149 'properties': self._GenerateProperties(type_.properties), | 141 'properties': self._GenerateProperties(type_.properties), |
150 'functions': self._GenerateFunctions(type_.functions), | 142 'functions': self._GenerateFunctions(type_.functions), |
151 'events': self._GenerateEvents(type_.events), | 143 'events': self._GenerateEvents(type_.events), |
152 'id': _CreateId(type_, 'type') | 144 'id': _CreateId(type_, 'type') |
153 } | 145 } |
154 self._RenderTypeInformation(type_, type_dict) | 146 self._RenderTypeInformation(type_, type_dict) |
155 return type_dict | 147 return type_dict |
156 | 148 |
157 def _GenerateFunctions(self, functions): | 149 def _GenerateFunctions(self, functions): |
158 return [self._GenerateFunction(f) for f in functions.values()] | 150 return [self._GenerateFunction(f) for f in functions.values()] |
159 | 151 |
160 def _GenerateFunction(self, function): | 152 def _GenerateFunction(self, function): |
161 function_dict = { | 153 function_dict = { |
162 'name': function.simple_name, | 154 'name': function.simple_name, |
163 'description': self._FormatDescription(function.description), | 155 'description': function.description, |
164 'callback': self._GenerateCallback(function.callback), | 156 'callback': self._GenerateCallback(function.callback), |
165 'parameters': [], | 157 'parameters': [], |
166 'returns': None, | 158 'returns': None, |
167 'id': _CreateId(function, 'method') | 159 'id': _CreateId(function, 'method') |
168 } | 160 } |
169 self._AddCommonProperties(function_dict, function) | 161 self._AddCommonProperties(function_dict, function) |
170 if function.returns: | 162 if function.returns: |
171 function_dict['returns'] = self._GenerateType(function.returns) | 163 function_dict['returns'] = self._GenerateType(function.returns) |
172 for param in function.params: | 164 for param in function.params: |
173 function_dict['parameters'].append(self._GenerateProperty(param)) | 165 function_dict['parameters'].append(self._GenerateProperty(param)) |
174 if function.callback is not None: | 166 if function.callback is not None: |
175 # Show the callback as an extra parameter. | 167 # Show the callback as an extra parameter. |
176 function_dict['parameters'].append( | 168 function_dict['parameters'].append( |
177 self._GenerateCallbackProperty(function.callback)) | 169 self._GenerateCallbackProperty(function.callback)) |
178 if len(function_dict['parameters']) > 0: | 170 if len(function_dict['parameters']) > 0: |
179 function_dict['parameters'][-1]['last'] = True | 171 function_dict['parameters'][-1]['last'] = True |
180 return function_dict | 172 return function_dict |
181 | 173 |
182 def _GenerateEvents(self, events): | 174 def _GenerateEvents(self, events): |
183 return [self._GenerateEvent(e) for e in events.values() | 175 return [self._GenerateEvent(e) for e in events.values() |
184 if not e.supports_dom] | 176 if not e.supports_dom] |
185 | 177 |
186 def _GenerateDomEvents(self, events): | 178 def _GenerateDomEvents(self, events): |
187 return [self._GenerateEvent(e) for e in events.values() | 179 return [self._GenerateEvent(e) for e in events.values() |
188 if e.supports_dom] | 180 if e.supports_dom] |
189 | 181 |
190 def _GenerateEvent(self, event): | 182 def _GenerateEvent(self, event): |
191 event_dict = { | 183 event_dict = { |
192 'name': event.simple_name, | 184 'name': event.simple_name, |
193 'description': self._FormatDescription(event.description), | 185 'description': event.description, |
194 'filters': [self._GenerateProperty(f) for f in event.filters], | 186 'filters': [self._GenerateProperty(f) for f in event.filters], |
195 'conditions': [self._GetLink(condition) | 187 'conditions': [self._GetLink(condition) |
196 for condition in event.conditions], | 188 for condition in event.conditions], |
197 'actions': [self._GetLink(action) for action in event.actions], | 189 'actions': [self._GetLink(action) for action in event.actions], |
198 'supportsRules': event.supports_rules, | 190 'supportsRules': event.supports_rules, |
199 'supportsListeners': event.supports_listeners, | 191 'supportsListeners': event.supports_listeners, |
200 'properties': [], | 192 'properties': [], |
201 'id': _CreateId(event, 'event'), | 193 'id': _CreateId(event, 'event'), |
202 'byName': {}, | 194 'byName': {}, |
203 } | 195 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 # Make sure we generate property info for arrays, too. | 252 # Make sure we generate property info for arrays, too. |
261 # TODO(kalman): what about choices? | 253 # TODO(kalman): what about choices? |
262 if type_.property_type == model.PropertyType.ARRAY: | 254 if type_.property_type == model.PropertyType.ARRAY: |
263 properties = type_.item_type.properties | 255 properties = type_.item_type.properties |
264 else: | 256 else: |
265 properties = type_.properties | 257 properties = type_.properties |
266 | 258 |
267 property_dict = { | 259 property_dict = { |
268 'name': property_.simple_name, | 260 'name': property_.simple_name, |
269 'optional': property_.optional, | 261 'optional': property_.optional, |
270 'description': self._FormatDescription(property_.description), | 262 'description': property_.description, |
271 'properties': self._GenerateProperties(type_.properties), | 263 'properties': self._GenerateProperties(type_.properties), |
272 'functions': self._GenerateFunctions(type_.functions), | 264 'functions': self._GenerateFunctions(type_.functions), |
273 'parameters': [], | 265 'parameters': [], |
274 'returns': None, | 266 'returns': None, |
275 'id': _CreateId(property_, 'property') | 267 'id': _CreateId(property_, 'property') |
276 } | 268 } |
277 self._AddCommonProperties(property_dict, property_) | 269 self._AddCommonProperties(property_dict, property_) |
278 | 270 |
279 if type_.property_type == model.PropertyType.FUNCTION: | 271 if type_.property_type == model.PropertyType.FUNCTION: |
280 function = type_.function | 272 function = type_.function |
281 for param in function.params: | 273 for param in function.params: |
282 property_dict['parameters'].append(self._GenerateProperty(param)) | 274 property_dict['parameters'].append(self._GenerateProperty(param)) |
283 if function.returns: | 275 if function.returns: |
284 property_dict['returns'] = self._GenerateType(function.returns) | 276 property_dict['returns'] = self._GenerateType(function.returns) |
285 | 277 |
286 value = property_.value | 278 value = property_.value |
287 if value is not None: | 279 if value is not None: |
288 if isinstance(value, int): | 280 if isinstance(value, int): |
289 property_dict['value'] = _FormatValue(value) | 281 property_dict['value'] = _FormatValue(value) |
290 else: | 282 else: |
291 property_dict['value'] = value | 283 property_dict['value'] = value |
292 else: | 284 else: |
293 self._RenderTypeInformation(type_, property_dict) | 285 self._RenderTypeInformation(type_, property_dict) |
294 | 286 |
295 return property_dict | 287 return property_dict |
296 | 288 |
297 def _GenerateCallbackProperty(self, callback): | 289 def _GenerateCallbackProperty(self, callback): |
298 property_dict = { | 290 property_dict = { |
299 'name': callback.simple_name, | 291 'name': callback.simple_name, |
300 'description': self._FormatDescription(callback.description), | 292 'description': callback.description, |
301 'optional': callback.optional, | 293 'optional': callback.optional, |
302 'is_callback': True, | 294 'is_callback': True, |
303 'id': _CreateId(callback, 'property'), | 295 'id': _CreateId(callback, 'property'), |
304 'simple_type': 'function', | 296 'simple_type': 'function', |
305 } | 297 } |
306 if (callback.parent is not None and | 298 if (callback.parent is not None and |
307 not isinstance(callback.parent, model.Namespace)): | 299 not isinstance(callback.parent, model.Namespace)): |
308 property_dict['parentName'] = callback.parent.simple_name | 300 property_dict['parentName'] = callback.parent.simple_name |
309 return property_dict | 301 return property_dict |
310 | 302 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 intro_rows.append(misc_row) | 342 intro_rows.append(misc_row) |
351 | 343 |
352 return intro_rows | 344 return intro_rows |
353 | 345 |
354 def _GetIntroDescriptionRow(self): | 346 def _GetIntroDescriptionRow(self): |
355 ''' Generates the 'Description' row data for an API intro table. | 347 ''' Generates the 'Description' row data for an API intro table. |
356 ''' | 348 ''' |
357 return { | 349 return { |
358 'title': 'Description', | 350 'title': 'Description', |
359 'content': [ | 351 'content': [ |
360 { 'text': self._FormatDescription(self._namespace.description) } | 352 { 'text': self._namespace.description } |
361 ] | 353 ] |
362 } | 354 } |
363 | 355 |
364 def _GetIntroAvailabilityRow(self): | 356 def _GetIntroAvailabilityRow(self): |
365 ''' Generates the 'Availability' row data for an API intro table. | 357 ''' Generates the 'Availability' row data for an API intro table. |
366 ''' | 358 ''' |
367 if self._IsExperimental(): | 359 if self._IsExperimental(): |
368 status = 'experimental' | 360 status = 'experimental' |
369 version = None | 361 version = None |
370 else: | 362 else: |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 # If there is a 'partial' argument and it hasn't already been | 440 # If there is a 'partial' argument and it hasn't already been |
449 # converted to a Handlebar object, transform it to a template. | 441 # converted to a Handlebar object, transform it to a template. |
450 if 'partial' in node: | 442 if 'partial' in node: |
451 node['partial'] = self._template_cache.GetFromFile( | 443 node['partial'] = self._template_cache.GetFromFile( |
452 posixpath.join(PRIVATE_TEMPLATES, node['partial'])).Get() | 444 posixpath.join(PRIVATE_TEMPLATES, node['partial'])).Get() |
453 misc_rows.append({ 'title': category, 'content': content }) | 445 misc_rows.append({ 'title': category, 'content': content }) |
454 return misc_rows | 446 return misc_rows |
455 | 447 |
456 def _AddCommonProperties(self, target, src): | 448 def _AddCommonProperties(self, target, src): |
457 if src.deprecated is not None: | 449 if src.deprecated is not None: |
458 target['deprecated'] = self._FormatDescription( | 450 target['deprecated'] = src.deprecated |
459 src.deprecated) | |
460 if (src.parent is not None and | 451 if (src.parent is not None and |
461 not isinstance(src.parent, model.Namespace)): | 452 not isinstance(src.parent, model.Namespace)): |
462 target['parentName'] = src.parent.simple_name | 453 target['parentName'] = src.parent.simple_name |
463 | 454 |
464 | 455 |
465 class _LazySamplesGetter(object): | 456 class _LazySamplesGetter(object): |
466 '''This class is needed so that an extensions API page does not have to fetch | 457 '''This class is needed so that an extensions API page does not have to fetch |
467 the apps samples page and vice versa. | 458 the apps samples page and vice versa. |
468 ''' | 459 ''' |
469 | 460 |
(...skipping 22 matching lines...) Expand all Loading... | |
492 self._template_cache = compiled_fs_factory.ForTemplates(file_system) | 483 self._template_cache = compiled_fs_factory.ForTemplates(file_system) |
493 self._availability_finder = availability_finder | 484 self._availability_finder = availability_finder |
494 self._api_models = api_models | 485 self._api_models = api_models |
495 self._features_bundle = features_bundle | 486 self._features_bundle = features_bundle |
496 self._model_cache_refs = object_store_creator.Create( | 487 self._model_cache_refs = object_store_creator.Create( |
497 APIDataSource, 'model-cache-refs') | 488 APIDataSource, 'model-cache-refs') |
498 self._model_cache_no_refs = object_store_creator.Create( | 489 self._model_cache_no_refs = object_store_creator.Create( |
499 APIDataSource, 'model-cache-no-refs') | 490 APIDataSource, 'model-cache-no-refs') |
500 | 491 |
501 # These must be set later via the SetFooDataSourceFactory methods. | 492 # These must be set later via the SetFooDataSourceFactory methods. |
502 self._ref_resolver_factory = None | |
503 self._samples_data_source_factory = None | 493 self._samples_data_source_factory = None |
504 | 494 |
505 # This caches the result of _LoadEventByName. | 495 # This caches the result of _LoadEventByName. |
506 self._event_byname = None | 496 self._event_byname = None |
507 | 497 |
508 def SetSamplesDataSourceFactory(self, samples_data_source_factory): | 498 def SetSamplesDataSourceFactory(self, samples_data_source_factory): |
509 self._samples_data_source_factory = samples_data_source_factory | 499 self._samples_data_source_factory = samples_data_source_factory |
510 | 500 |
511 def SetReferenceResolverFactory(self, ref_resolver_factory): | |
512 self._ref_resolver_factory = ref_resolver_factory | |
513 | |
514 def Create(self, request): | 501 def Create(self, request): |
515 '''Creates an APIDataSource. | 502 '''Creates an APIDataSource. |
516 ''' | 503 ''' |
517 if self._samples_data_source_factory is None: | 504 if self._samples_data_source_factory is None: |
518 # Only error if there is a request, which means this APIDataSource is | 505 # Only error if there is a request, which means this APIDataSource is |
519 # actually being used to render a page. | 506 # actually being used to render a page. |
520 if request is not None: | 507 if request is not None: |
521 logging.error('SamplesDataSource.Factory was never set in ' | 508 logging.error('SamplesDataSource.Factory was never set in ' |
522 'APIDataSource.Factory.') | 509 'APIDataSource.Factory.') |
523 samples = None | 510 samples = None |
(...skipping 16 matching lines...) Expand all Loading... | |
540 return self._model_cache_refs | 527 return self._model_cache_refs |
541 | 528 |
542 def _GetSchemaModel(self, api_name, disable_refs): | 529 def _GetSchemaModel(self, api_name, disable_refs): |
543 jsc_model = self._GetModelCache(disable_refs).Get(api_name).Get() | 530 jsc_model = self._GetModelCache(disable_refs).Get(api_name).Get() |
544 if jsc_model is not None: | 531 if jsc_model is not None: |
545 return jsc_model | 532 return jsc_model |
546 | 533 |
547 jsc_model = _JSCModel( | 534 jsc_model = _JSCModel( |
548 api_name, | 535 api_name, |
549 self._api_models, | 536 self._api_models, |
550 self._ref_resolver_factory.Create() if not disable_refs else None, | |
551 disable_refs, | 537 disable_refs, |
552 self._availability_finder, | 538 self._availability_finder, |
553 self._json_cache, | 539 self._json_cache, |
554 self._template_cache, | 540 self._template_cache, |
555 self._features_bundle, | 541 self._features_bundle, |
556 self._LoadEventByName).ToDict() | 542 self._LoadEventByName).ToDict() |
557 | 543 |
558 self._GetModelCache(disable_refs).Set(api_name, jsc_model) | 544 self._GetModelCache(disable_refs).Set(api_name, jsc_model) |
559 return jsc_model | 545 return jsc_model |
560 | 546 |
561 def __init__(self, get_schema_model, samples): | 547 def __init__(self, get_schema_model, samples): |
562 self._get_schema_model = get_schema_model | 548 self._get_schema_model = get_schema_model |
563 self._samples = samples | 549 self._samples = samples |
564 | 550 |
565 def _GenerateHandlebarContext(self, handlebar_dict): | 551 def _GenerateHandlebarContext(self, handlebar_dict): |
566 # Parsing samples on the preview server takes seconds and doesn't add | 552 # Parsing samples on the preview server takes seconds and doesn't add |
567 # anything. Don't do it. | 553 # anything. Don't do it. |
568 if not IsPreviewServer(): | 554 if not IsPreviewServer(): |
569 handlebar_dict['samples'] = _LazySamplesGetter( | 555 handlebar_dict['samples'] = _LazySamplesGetter( |
570 handlebar_dict['name'], | 556 handlebar_dict['name'], |
571 self._samples) | 557 self._samples) |
572 return handlebar_dict | 558 return handlebar_dict |
573 | 559 |
574 def get(self, api_name, disable_refs=False): | 560 def get(self, api_name, disable_refs=False): |
575 return self._GenerateHandlebarContext( | 561 return self._GenerateHandlebarContext( |
576 self._get_schema_model(api_name, disable_refs)) | 562 self._get_schema_model(api_name, disable_refs)) |
OLD | NEW |