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