| 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 json | 6 import json |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 from collections import defaultdict, Mapping | 9 from collections import defaultdict, Mapping |
| 10 | 10 |
| 11 from environment import IsPreviewServer | 11 from environment import IsPreviewServer |
| 12 import svn_constants | 12 from extensions_paths import ( |
| 13 API, API_FEATURES, JSON_TEMPLATES, PRIVATE_TEMPLATES) |
| 13 import third_party.json_schema_compiler.json_parse as json_parse | 14 import third_party.json_schema_compiler.json_parse as json_parse |
| 14 import third_party.json_schema_compiler.model as model | 15 import third_party.json_schema_compiler.model as model |
| 15 import third_party.json_schema_compiler.idl_schema as idl_schema | 16 import third_party.json_schema_compiler.idl_schema as idl_schema |
| 16 import third_party.json_schema_compiler.idl_parser as idl_parser | 17 import third_party.json_schema_compiler.idl_parser as idl_parser |
| 17 from schema_util import RemoveNoDocs, DetectInlineableTypes, InlineDocs | 18 from schema_util import RemoveNoDocs, DetectInlineableTypes, InlineDocs |
| 18 from third_party.handlebar import Handlebar | 19 from third_party.handlebar import Handlebar |
| 19 | 20 |
| 20 | 21 |
| 21 def _CreateId(node, prefix): | 22 def _CreateId(node, prefix): |
| 22 if node.parent is not None and not isinstance(node.parent, model.Namespace): | 23 if node.parent is not None and not isinstance(node.parent, model.Namespace): |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 branch_utility, | 78 branch_utility, |
| 78 parse_cache, | 79 parse_cache, |
| 79 template_cache, | 80 template_cache, |
| 80 event_byname_function, | 81 event_byname_function, |
| 81 idl=False): | 82 idl=False): |
| 82 self._ref_resolver = ref_resolver | 83 self._ref_resolver = ref_resolver |
| 83 self._disable_refs = disable_refs | 84 self._disable_refs = disable_refs |
| 84 self._availability_finder = availability_finder | 85 self._availability_finder = availability_finder |
| 85 self._branch_utility = branch_utility | 86 self._branch_utility = branch_utility |
| 86 self._api_availabilities = parse_cache.GetFromFile( | 87 self._api_availabilities = parse_cache.GetFromFile( |
| 87 '%s/api_availabilities.json' % svn_constants.JSON_PATH) | 88 '%s/api_availabilities.json' % JSON_TEMPLATES) |
| 88 self._intro_tables = parse_cache.GetFromFile( | 89 self._intro_tables = parse_cache.GetFromFile( |
| 89 '%s/intro_tables.json' % svn_constants.JSON_PATH) | 90 '%s/intro_tables.json' % JSON_TEMPLATES) |
| 90 self._api_features = parse_cache.GetFromFile( | 91 self._api_features = parse_cache.GetFromFile(API_FEATURES) |
| 91 '%s/_api_features.json' % svn_constants.API_PATH) | |
| 92 self._template_cache = template_cache | 92 self._template_cache = template_cache |
| 93 self._event_byname_function = event_byname_function | 93 self._event_byname_function = event_byname_function |
| 94 clean_json = copy.deepcopy(json) | 94 clean_json = copy.deepcopy(json) |
| 95 if RemoveNoDocs(clean_json): | 95 if RemoveNoDocs(clean_json): |
| 96 self._namespace = None | 96 self._namespace = None |
| 97 else: | 97 else: |
| 98 if idl: | 98 if idl: |
| 99 DetectInlineableTypes(clean_json) | 99 DetectInlineableTypes(clean_json) |
| 100 InlineDocs(clean_json) | 100 InlineDocs(clean_json) |
| 101 self._namespace = model.Namespace(clean_json, clean_json['namespace']) | 101 self._namespace = model.Namespace(clean_json, clean_json['namespace']) |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 version = None | 394 version = None |
| 395 else: | 395 else: |
| 396 availability = self._GetApiAvailability() | 396 availability = self._GetApiAvailability() |
| 397 status = availability.channel | 397 status = availability.channel |
| 398 version = availability.version | 398 version = availability.version |
| 399 return { | 399 return { |
| 400 'title': 'Availability', | 400 'title': 'Availability', |
| 401 'content': [{ | 401 'content': [{ |
| 402 'partial': self._template_cache.GetFromFile( | 402 'partial': self._template_cache.GetFromFile( |
| 403 '%s/intro_tables/%s_message.html' % | 403 '%s/intro_tables/%s_message.html' % |
| 404 (svn_constants.PRIVATE_TEMPLATE_PATH, status)).Get(), | 404 (PRIVATE_TEMPLATES, status)).Get(), |
| 405 'version': version | 405 'version': version |
| 406 }] | 406 }] |
| 407 } | 407 } |
| 408 | 408 |
| 409 def _GetIntroDependencyRows(self): | 409 def _GetIntroDependencyRows(self): |
| 410 # Devtools aren't in _api_features. If we're dealing with devtools, bail. | 410 # Devtools aren't in _api_features. If we're dealing with devtools, bail. |
| 411 if 'devtools' in self._namespace.name: | 411 if 'devtools' in self._namespace.name: |
| 412 return [] | 412 return [] |
| 413 feature = self._api_features.Get().get(self._namespace.name) | 413 feature = self._api_features.Get().get(self._namespace.name) |
| 414 assert feature, ('"%s" not found in _api_features.json.' | 414 assert feature, ('"%s" not found in _api_features.json.' |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 if table_info is None: | 467 if table_info is None: |
| 468 return misc_rows | 468 return misc_rows |
| 469 | 469 |
| 470 for category in table_info.keys(): | 470 for category in table_info.keys(): |
| 471 content = copy.deepcopy(table_info[category]) | 471 content = copy.deepcopy(table_info[category]) |
| 472 for node in content: | 472 for node in content: |
| 473 # If there is a 'partial' argument and it hasn't already been | 473 # If there is a 'partial' argument and it hasn't already been |
| 474 # converted to a Handlebar object, transform it to a template. | 474 # converted to a Handlebar object, transform it to a template. |
| 475 if 'partial' in node: | 475 if 'partial' in node: |
| 476 node['partial'] = self._template_cache.GetFromFile('%s/%s' % | 476 node['partial'] = self._template_cache.GetFromFile('%s/%s' % |
| 477 (svn_constants.PRIVATE_TEMPLATE_PATH, node['partial'])).Get() | 477 (PRIVATE_TEMPLATES, node['partial'])).Get() |
| 478 misc_rows.append({ 'title': category, 'content': content }) | 478 misc_rows.append({ 'title': category, 'content': content }) |
| 479 return misc_rows | 479 return misc_rows |
| 480 | 480 |
| 481 | 481 |
| 482 class _LazySamplesGetter(object): | 482 class _LazySamplesGetter(object): |
| 483 '''This class is needed so that an extensions API page does not have to fetch | 483 '''This class is needed so that an extensions API page does not have to fetch |
| 484 the apps samples page and vice versa. | 484 the apps samples page and vice versa. |
| 485 ''' | 485 ''' |
| 486 | 486 |
| 487 def __init__(self, api_name, samples): | 487 def __init__(self, api_name, samples): |
| 488 self._api_name = api_name | 488 self._api_name = api_name |
| 489 self._samples = samples | 489 self._samples = samples |
| 490 | 490 |
| 491 def get(self, key): | 491 def get(self, key): |
| 492 return self._samples.FilterSamples(key, self._api_name) | 492 return self._samples.FilterSamples(key, self._api_name) |
| 493 | 493 |
| 494 | 494 |
| 495 class APIDataSource(object): | 495 class APIDataSource(object): |
| 496 '''This class fetches and loads JSON APIs from the FileSystem passed in with | 496 '''This class fetches and loads JSON APIs from the FileSystem passed in with |
| 497 |compiled_fs_factory|, so the APIs can be plugged into templates. | 497 |compiled_fs_factory|, so the APIs can be plugged into templates. |
| 498 ''' | 498 ''' |
| 499 | 499 |
| 500 class Factory(object): | 500 class Factory(object): |
| 501 def __init__(self, | 501 def __init__(self, |
| 502 compiled_fs_factory, | 502 compiled_fs_factory, |
| 503 file_system, | 503 file_system, |
| 504 base_path, | |
| 505 availability_finder, | 504 availability_finder, |
| 506 branch_utility): | 505 branch_utility): |
| 507 def create_compiled_fs(fn, category): | 506 def create_compiled_fs(fn, category): |
| 508 return compiled_fs_factory.Create( | 507 return compiled_fs_factory.Create( |
| 509 file_system, fn, APIDataSource, category=category) | 508 file_system, fn, APIDataSource, category=category) |
| 510 | 509 |
| 511 self._json_cache = create_compiled_fs( | 510 self._json_cache = create_compiled_fs( |
| 512 lambda api_name, api: self._LoadJsonAPI(api, False), | 511 lambda api_name, api: self._LoadJsonAPI(api, False), |
| 513 'json') | 512 'json') |
| 514 self._idl_cache = create_compiled_fs( | 513 self._idl_cache = create_compiled_fs( |
| 515 lambda api_name, api: self._LoadIdlAPI(api, False), | 514 lambda api_name, api: self._LoadIdlAPI(api, False), |
| 516 'idl') | 515 'idl') |
| 517 | 516 |
| 518 # These caches are used if an APIDataSource does not want to resolve the | 517 # These caches are used if an APIDataSource does not want to resolve the |
| 519 # $refs in an API. This is needed to prevent infinite recursion in | 518 # $refs in an API. This is needed to prevent infinite recursion in |
| 520 # ReferenceResolver. | 519 # ReferenceResolver. |
| 521 self._json_cache_no_refs = create_compiled_fs( | 520 self._json_cache_no_refs = create_compiled_fs( |
| 522 lambda api_name, api: self._LoadJsonAPI(api, True), | 521 lambda api_name, api: self._LoadJsonAPI(api, True), |
| 523 'json-no-refs') | 522 'json-no-refs') |
| 524 self._idl_cache_no_refs = create_compiled_fs( | 523 self._idl_cache_no_refs = create_compiled_fs( |
| 525 lambda api_name, api: self._LoadIdlAPI(api, True), | 524 lambda api_name, api: self._LoadIdlAPI(api, True), |
| 526 'idl-no-refs') | 525 'idl-no-refs') |
| 527 | 526 |
| 528 self._idl_names_cache = create_compiled_fs(self._GetIDLNames, 'idl-names') | 527 self._idl_names_cache = create_compiled_fs(self._GetIDLNames, 'idl-names') |
| 529 self._names_cache = create_compiled_fs(self._GetAllNames, 'names') | 528 self._names_cache = create_compiled_fs(self._GetAllNames, 'names') |
| 530 | 529 |
| 531 self._base_path = base_path | |
| 532 self._availability_finder = availability_finder | 530 self._availability_finder = availability_finder |
| 533 self._branch_utility = branch_utility | 531 self._branch_utility = branch_utility |
| 534 | 532 |
| 535 self._parse_cache = compiled_fs_factory.ForJson(file_system) | 533 self._parse_cache = compiled_fs_factory.ForJson(file_system) |
| 536 self._template_cache = compiled_fs_factory.ForTemplates(file_system) | 534 self._template_cache = compiled_fs_factory.ForTemplates(file_system) |
| 537 | 535 |
| 538 # These must be set later via the SetFooDataSourceFactory methods. | 536 # These must be set later via the SetFooDataSourceFactory methods. |
| 539 self._ref_resolver_factory = None | 537 self._ref_resolver_factory = None |
| 540 self._samples_data_source_factory = None | 538 self._samples_data_source_factory = None |
| 541 | 539 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 559 'APIDataSource.Factory.') | 557 'APIDataSource.Factory.') |
| 560 samples = None | 558 samples = None |
| 561 else: | 559 else: |
| 562 samples = self._samples_data_source_factory.Create(request) | 560 samples = self._samples_data_source_factory.Create(request) |
| 563 return APIDataSource(self._json_cache, | 561 return APIDataSource(self._json_cache, |
| 564 self._idl_cache, | 562 self._idl_cache, |
| 565 self._json_cache_no_refs, | 563 self._json_cache_no_refs, |
| 566 self._idl_cache_no_refs, | 564 self._idl_cache_no_refs, |
| 567 self._names_cache, | 565 self._names_cache, |
| 568 self._idl_names_cache, | 566 self._idl_names_cache, |
| 569 self._base_path, | |
| 570 samples) | 567 samples) |
| 571 | 568 |
| 572 def _LoadEventByName(self): | 569 def _LoadEventByName(self): |
| 573 """ All events have some members in common. We source their description | 570 """ All events have some members in common. We source their description |
| 574 from Event in events.json. | 571 from Event in events.json. |
| 575 """ | 572 """ |
| 576 if self._event_byname is None: | 573 if self._event_byname is None: |
| 577 events_json = self._json_cache.GetFromFile( | 574 events_json = self._json_cache.GetFromFile('%s/events.json' % API).Get() |
| 578 '%s/events.json' % self._base_path).Get() | |
| 579 self._event_byname = _GetEventByNameFromEvents(events_json) | 575 self._event_byname = _GetEventByNameFromEvents(events_json) |
| 580 return self._event_byname | 576 return self._event_byname |
| 581 | 577 |
| 582 def _LoadJsonAPI(self, api, disable_refs): | 578 def _LoadJsonAPI(self, api, disable_refs): |
| 583 return _JSCModel( | 579 return _JSCModel( |
| 584 json_parse.Parse(api)[0], | 580 json_parse.Parse(api)[0], |
| 585 self._ref_resolver_factory.Create() if not disable_refs else None, | 581 self._ref_resolver_factory.Create() if not disable_refs else None, |
| 586 disable_refs, | 582 disable_refs, |
| 587 self._availability_finder, | 583 self._availability_finder, |
| 588 self._branch_utility, | 584 self._branch_utility, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 613 return [model.UnixName(os.path.splitext(api)[0]) for api in apis | 609 return [model.UnixName(os.path.splitext(api)[0]) for api in apis |
| 614 if os.path.splitext(api)[1][1:] in exts] | 610 if os.path.splitext(api)[1][1:] in exts] |
| 615 | 611 |
| 616 def __init__(self, | 612 def __init__(self, |
| 617 json_cache, | 613 json_cache, |
| 618 idl_cache, | 614 idl_cache, |
| 619 json_cache_no_refs, | 615 json_cache_no_refs, |
| 620 idl_cache_no_refs, | 616 idl_cache_no_refs, |
| 621 names_cache, | 617 names_cache, |
| 622 idl_names_cache, | 618 idl_names_cache, |
| 623 base_path, | |
| 624 samples): | 619 samples): |
| 625 self._base_path = base_path | |
| 626 self._json_cache = json_cache | 620 self._json_cache = json_cache |
| 627 self._idl_cache = idl_cache | 621 self._idl_cache = idl_cache |
| 628 self._json_cache_no_refs = json_cache_no_refs | 622 self._json_cache_no_refs = json_cache_no_refs |
| 629 self._idl_cache_no_refs = idl_cache_no_refs | 623 self._idl_cache_no_refs = idl_cache_no_refs |
| 630 self._names_cache = names_cache | 624 self._names_cache = names_cache |
| 631 self._idl_names_cache = idl_names_cache | 625 self._idl_names_cache = idl_names_cache |
| 632 self._samples = samples | 626 self._samples = samples |
| 633 | 627 |
| 634 def _GenerateHandlebarContext(self, handlebar_dict): | 628 def _GenerateHandlebarContext(self, handlebar_dict): |
| 635 # Parsing samples on the preview server takes seconds and doesn't add | 629 # Parsing samples on the preview server takes seconds and doesn't add |
| (...skipping 12 matching lines...) Expand all Loading... |
| 648 return '/'.join(parts) | 642 return '/'.join(parts) |
| 649 return '%s/%s' % (parts[0], name) | 643 return '%s/%s' % (parts[0], name) |
| 650 return name.replace('_', '/', 1) | 644 return name.replace('_', '/', 1) |
| 651 | 645 |
| 652 def get(self, key, disable_refs=False): | 646 def get(self, key, disable_refs=False): |
| 653 if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'): | 647 if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'): |
| 654 path, ext = os.path.splitext(key) | 648 path, ext = os.path.splitext(key) |
| 655 else: | 649 else: |
| 656 path = key | 650 path = key |
| 657 unix_name = model.UnixName(path) | 651 unix_name = model.UnixName(path) |
| 658 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path).Get() | 652 idl_names = self._idl_names_cache.GetFromFileListing(API).Get() |
| 659 names = self._names_cache.GetFromFileListing(self._base_path).Get() | 653 names = self._names_cache.GetFromFileListing(API).Get() |
| 660 if unix_name not in names and self._GetAsSubdirectory(unix_name) in names: | 654 if unix_name not in names and self._GetAsSubdirectory(unix_name) in names: |
| 661 unix_name = self._GetAsSubdirectory(unix_name) | 655 unix_name = self._GetAsSubdirectory(unix_name) |
| 662 | 656 |
| 663 if disable_refs: | 657 if disable_refs: |
| 664 cache, ext = ( | 658 cache, ext = ( |
| 665 (self._idl_cache_no_refs, '.idl') if (unix_name in idl_names) else | 659 (self._idl_cache_no_refs, '.idl') if (unix_name in idl_names) else |
| 666 (self._json_cache_no_refs, '.json')) | 660 (self._json_cache_no_refs, '.json')) |
| 667 else: | 661 else: |
| 668 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else | 662 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else |
| 669 (self._json_cache, '.json')) | 663 (self._json_cache, '.json')) |
| 670 return self._GenerateHandlebarContext( | 664 return self._GenerateHandlebarContext( |
| 671 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)).Get()) | 665 cache.GetFromFile('%s/%s%s' % (API, unix_name, ext)).Get()) |
| OLD | NEW |