OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 from copy import copy | 5 from copy import copy |
6 import logging | 6 import logging |
7 import posixpath | 7 import posixpath |
8 | 8 |
9 from api_models import GetNodeCategories | 9 from api_models import GetNodeCategories |
10 from api_schema_graph import APINodeCursor | 10 from api_schema_graph import APINodeCursor |
11 from docs_server_utils import MarkFirstAndLast | 11 from docs_server_utils import MarkFirstAndLast |
12 from extensions_paths import JSON_TEMPLATES, PRIVATE_TEMPLATES | 12 from extensions_paths import JSON_TEMPLATES, PRIVATE_TEMPLATES |
13 from operator import itemgetter | 13 from operator import itemgetter |
14 from platform_util import PlatformToExtensionType | 14 from platform_util import PlatformToExtensionType |
15 import third_party.json_schema_compiler.model as model | 15 import third_party.json_schema_compiler.model as model |
16 | 16 |
17 | 17 |
| 18 def CreateSamplesView(samples_list, request): |
| 19 def get_sample_id(sample_name): |
| 20 return sample_name.lower().replace(' ', '-') |
| 21 |
| 22 def get_accepted_languages(request): |
| 23 if request is None: |
| 24 return [] |
| 25 accept_language = request.headers.get('Accept-Language', None) |
| 26 if accept_language is None: |
| 27 return [] |
| 28 return [lang_with_q.split(';')[0].strip() |
| 29 for lang_with_q in accept_language.split(',')] |
| 30 |
| 31 return_list = [] |
| 32 for dict_ in samples_list: |
| 33 name = dict_['name'] |
| 34 description = dict_['description'] |
| 35 if description is None: |
| 36 description = '' |
| 37 if name.startswith('__MSG_') or description.startswith('__MSG_'): |
| 38 try: |
| 39 # Copy the sample dict so we don't change the dict in the cache. |
| 40 sample_data = dict_.copy() |
| 41 name_key = name[len('__MSG_'):-len('__')] |
| 42 description_key = description[len('__MSG_'):-len('__')] |
| 43 locale = sample_data['default_locale'] |
| 44 for lang in get_accepted_languages(request): |
| 45 if lang in sample_data['locales']: |
| 46 locale = lang |
| 47 break |
| 48 locale_data = sample_data['locales'][locale] |
| 49 sample_data['name'] = locale_data[name_key]['message'] |
| 50 sample_data['description'] = locale_data[description_key]['message'] |
| 51 sample_data['id'] = get_sample_id(sample_data['name']) |
| 52 except Exception: |
| 53 logging.error(traceback.format_exc()) |
| 54 # Revert the sample to the original dict. |
| 55 sample_data = dict_ |
| 56 return_list.append(sample_data) |
| 57 else: |
| 58 dict_['id'] = get_sample_id(name) |
| 59 return_list.append(dict_) |
| 60 return return_list |
| 61 |
| 62 |
18 def GetEventByNameFromEvents(events): | 63 def GetEventByNameFromEvents(events): |
19 '''Parses the dictionary |events| to find the definitions of members of the | 64 '''Parses the dictionary |events| to find the definitions of members of the |
20 type Event. Returns a dictionary mapping the name of a member to that | 65 type Event. Returns a dictionary mapping the name of a member to that |
21 member's definition. | 66 member's definition. |
22 ''' | 67 ''' |
23 assert 'types' in events, \ | 68 assert 'types' in events, \ |
24 'The dictionary |events| must contain the key "types".' | 69 'The dictionary |events| must contain the key "types".' |
25 event_list = [t for t in events['types'] if t.get('name') == 'Event'] | 70 event_list = [t for t in events['types'] if t.get('name') == 'Event'] |
26 assert len(event_list) == 1, 'Exactly one type must be called "Event".' | 71 assert len(event_list) == 1, 'Exactly one type must be called "Event".' |
27 return _GetByNameDict(event_list[0]) | 72 return _GetByNameDict(event_list[0]) |
(...skipping 25 matching lines...) Expand all Loading... |
53 return '-'.join([prefix, node.simple_name]) | 98 return '-'.join([prefix, node.simple_name]) |
54 | 99 |
55 | 100 |
56 def _FormatValue(value): | 101 def _FormatValue(value): |
57 '''Inserts commas every three digits for integer values. It is magic. | 102 '''Inserts commas every three digits for integer values. It is magic. |
58 ''' | 103 ''' |
59 s = str(value) | 104 s = str(value) |
60 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) | 105 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) |
61 | 106 |
62 | 107 |
63 class JSCView(object): | 108 class _JSCViewBuilder(object): |
64 '''Uses a Model from the JSON Schema Compiler and generates a dict that | 109 '''Uses a Model from the JSON Schema Compiler and generates a dict that |
65 a Motemplate template can use for a data source. | 110 a Motemplate template can use for a data source. |
66 ''' | 111 ''' |
67 | 112 |
68 def __init__(self, | 113 def __init__(self, |
69 content_script_apis, | 114 content_script_apis, |
70 jsc_model, | 115 jsc_model, |
71 availability_finder, | 116 availability_finder, |
72 json_cache, | 117 json_cache, |
73 template_cache, | 118 template_cache, |
74 features_bundle, | 119 features_bundle, |
75 event_byname_future, | 120 event_byname_future, |
76 platform): | 121 platform, |
| 122 samples): |
77 self._content_script_apis = content_script_apis | 123 self._content_script_apis = content_script_apis |
78 self._availability = availability_finder.GetAPIAvailability(jsc_model.name) | 124 self._availability = availability_finder.GetAPIAvailability(jsc_model.name) |
79 self._current_node = APINodeCursor(availability_finder, jsc_model.name) | 125 self._current_node = APINodeCursor(availability_finder, jsc_model.name) |
80 self._api_availabilities = json_cache.GetFromFile( | 126 self._api_availabilities = json_cache.GetFromFile( |
81 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) | 127 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) |
82 self._intro_tables = json_cache.GetFromFile( | 128 self._intro_tables = json_cache.GetFromFile( |
83 posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) | 129 posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) |
84 self._api_features = features_bundle.GetAPIFeatures() | 130 self._api_features = features_bundle.GetAPIFeatures() |
85 self._template_cache = template_cache | 131 self._template_cache = template_cache |
86 self._event_byname_future = event_byname_future | 132 self._event_byname_future = event_byname_future |
87 self._jsc_model = jsc_model | 133 self._jsc_model = jsc_model |
88 self._platform = platform | 134 self._platform = platform |
| 135 self._samples = samples |
89 | 136 |
90 def _GetLink(self, link): | 137 def _GetLink(self, link): |
91 ref = link if '.' in link else (self._jsc_model.name + '.' + link) | 138 ref = link if '.' in link else (self._jsc_model.name + '.' + link) |
92 return { 'ref': ref, 'text': link, 'name': link } | 139 return { 'ref': ref, 'text': link, 'name': link } |
93 | 140 |
94 def ToDict(self): | 141 def ToDict(self, request): |
95 '''Returns a dictionary representation of |self._jsc_model|, which | 142 '''Returns a dictionary representation of |self._jsc_model|, which |
96 is a Namespace object from JSON Schema Compiler. | 143 is a Namespace object from JSON Schema Compiler. |
97 ''' | 144 ''' |
98 assert self._jsc_model is not None | 145 assert self._jsc_model is not None |
99 chrome_dot_name = 'chrome.%s' % self._jsc_model.name | 146 chrome_dot_name = 'chrome.%s' % self._jsc_model.name |
100 as_dict = { | 147 as_dict = { |
| 148 'channelWarning': self._GetChannelWarning(), |
| 149 'documentationOptions': self._jsc_model.documentation_options, |
| 150 'domEvents': self._GenerateDomEvents(self._jsc_model.events), |
| 151 'events': self._GenerateEvents(self._jsc_model.events), |
| 152 'functions': self._GenerateFunctions(self._jsc_model.functions), |
| 153 'introList': self._GetIntroTableList(), |
101 'name': self._jsc_model.name, | 154 'name': self._jsc_model.name, |
102 'namespace': self._jsc_model.documentation_options.get('namespace', | 155 'namespace': self._jsc_model.documentation_options.get('namespace', |
103 chrome_dot_name), | 156 chrome_dot_name), |
| 157 'properties': self._GenerateProperties(self._jsc_model.properties), |
| 158 'samples': CreateSamplesView(self._samples, request), |
104 'title': self._jsc_model.documentation_options.get('title', | 159 'title': self._jsc_model.documentation_options.get('title', |
105 chrome_dot_name), | 160 chrome_dot_name), |
106 'documentationOptions': self._jsc_model.documentation_options, | |
107 'types': self._GenerateTypes(self._jsc_model.types.values()), | 161 'types': self._GenerateTypes(self._jsc_model.types.values()), |
108 'functions': self._GenerateFunctions(self._jsc_model.functions), | |
109 'events': self._GenerateEvents(self._jsc_model.events), | |
110 'domEvents': self._GenerateDomEvents(self._jsc_model.events), | |
111 'properties': self._GenerateProperties(self._jsc_model.properties), | |
112 'introList': self._GetIntroTableList(), | |
113 'channelWarning': self._GetChannelWarning(), | |
114 } | 162 } |
115 if self._jsc_model.deprecated: | 163 if self._jsc_model.deprecated: |
116 as_dict['deprecated'] = self._jsc_model.deprecated | 164 as_dict['deprecated'] = self._jsc_model.deprecated |
117 | 165 |
118 as_dict['byName'] = _GetByNameDict(as_dict) | 166 as_dict['byName'] = _GetByNameDict(as_dict) |
119 | 167 |
120 return as_dict | 168 return as_dict |
121 | 169 |
122 def _IsExperimental(self): | 170 def _IsExperimental(self): |
123 return self._jsc_model.name.startswith('experimental') | 171 return self._jsc_model.name.startswith('experimental') |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 # converted to a Motemplate object, transform it to a template. | 605 # converted to a Motemplate object, transform it to a template. |
558 if 'partial' in node: | 606 if 'partial' in node: |
559 # Note: it's enough to copy() not deepcopy() because only a single | 607 # Note: it's enough to copy() not deepcopy() because only a single |
560 # top-level key is being modified. | 608 # top-level key is being modified. |
561 node = copy(node) | 609 node = copy(node) |
562 node['partial'] = self._template_cache.GetFromFile( | 610 node['partial'] = self._template_cache.GetFromFile( |
563 posixpath.join(PRIVATE_TEMPLATES, node['partial'])).Get() | 611 posixpath.join(PRIVATE_TEMPLATES, node['partial'])).Get() |
564 content.append(node) | 612 content.append(node) |
565 misc_rows.append({ 'title': category, 'content': content }) | 613 misc_rows.append({ 'title': category, 'content': content }) |
566 return misc_rows | 614 return misc_rows |
| 615 |
| 616 def CreateJSCView(content_script_apis, |
| 617 jsc_model, |
| 618 availability_finder, |
| 619 json_cache, |
| 620 template_cache, |
| 621 features_bundle, |
| 622 event_byname_future, |
| 623 platform, |
| 624 samples, |
| 625 request): |
| 626 return _JSCViewBuilder(content_script_apis, |
| 627 jsc_model, |
| 628 availability_finder, |
| 629 json_cache, |
| 630 template_cache, |
| 631 features_bundle, |
| 632 event_byname_future, |
| 633 platform, |
| 634 samples).ToDict(request) |
OLD | NEW |