Chromium Code Reviews| 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 |