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 | 7 |
8 from compiled_file_system import SingleFile, Unicode | 8 from compiled_file_system import SingleFile, Unicode |
9 from data_source import DataSource | 9 from data_source import DataSource |
10 from extensions_paths import JSON_TEMPLATES | 10 from extensions_paths import JSON_TEMPLATES |
11 from future import Gettable, Future | 11 from future import Gettable, Future |
12 from third_party.json_schema_compiler.json_parse import Parse | 12 from third_party.json_schema_compiler.json_parse import Parse |
13 | 13 |
14 | 14 |
15 def _AddLevels(items, level): | 15 def _AddLevels(items, level): |
16 '''Add a 'level' key to each item in |items|. 'level' corresponds to how deep | 16 '''Add a 'level' key to each item in |items|. 'level' corresponds to how deep |
17 in |items| an item is. |level| sets the starting depth. | 17 in |items| an item is. |level| sets the starting depth. |
18 ''' | 18 ''' |
19 for item in items: | 19 for item in items: |
20 item['level'] = level | 20 item['level'] = level |
21 if 'items' in item: | 21 if 'items' in item: |
22 _AddLevels(item['items'], level + 1) | 22 _AddLevels(item['items'], level + 1) |
23 | 23 |
24 | 24 |
25 def _AddSelected(items, path): | 25 def _AddAnnotations(items, path, parent=None): |
26 '''Add 'selected' and 'child_selected' properties to |items| so that the | 26 '''Add 'selected', 'child_selected' and 'related' properties to |
27 sidenav can be expanded to show which menu item has been selected. Returns | 27 |items| so that the sidenav can be expanded to show which menu item has |
28 True if an item was marked 'selected'. | 28 been selected and the related pages section can be drawn. 'related' |
| 29 is added to all items with the same parent as the selected item. |
| 30 If more than one item exactly matches the path, the deepest one is considered |
| 31 'selected'. A 'parent' property is added to the selected path. |
| 32 |
| 33 Returns True if an item was marked 'selected'. |
29 ''' | 34 ''' |
30 for item in items: | 35 for item in items: |
| 36 if 'items' in item: |
| 37 if _AddAnnotations(item['items'], path, item): |
| 38 item['child_selected'] = True |
| 39 return True |
| 40 |
31 if item.get('href', '') == path: | 41 if item.get('href', '') == path: |
32 item['selected'] = True | 42 item['selected'] = True |
| 43 if parent: |
| 44 item['parent'] = { 'title': parent.get('title', None), |
| 45 'href': parent.get('href', None) } |
| 46 |
| 47 for sibling in items: |
| 48 sibling['related'] = True |
| 49 |
33 return True | 50 return True |
34 if 'items' in item: | |
35 if _AddSelected(item['items'], path): | |
36 item['child_selected'] = True | |
37 return True | |
38 | 51 |
39 return False | 52 return False |
40 | 53 |
41 | 54 |
42 class SidenavDataSource(DataSource): | 55 class SidenavDataSource(DataSource): |
43 '''Provides templates with access to JSON files used to create the side | 56 '''Provides templates with access to JSON files used to create the side |
44 navigation bar. | 57 navigation bar. |
45 ''' | 58 ''' |
46 def __init__(self, server_instance, request): | 59 def __init__(self, server_instance, request): |
47 self._cache = server_instance.compiled_fs_factory.Create( | 60 self._cache = server_instance.compiled_fs_factory.Create( |
(...skipping 23 matching lines...) Expand all Loading... |
71 | 84 |
72 href = item.get('href') | 85 href = item.get('href') |
73 if href is not None and not href.startswith(('http://', 'https://')): | 86 if href is not None and not href.startswith(('http://', 'https://')): |
74 if not href.startswith('/'): | 87 if not href.startswith('/'): |
75 logging.warn('Paths in sidenav must be qualified. %s is not.' % href) | 88 logging.warn('Paths in sidenav must be qualified. %s is not.' % href) |
76 else: | 89 else: |
77 href = href.lstrip('/') | 90 href = href.lstrip('/') |
78 item['href'] = self._server_instance.base_path + href | 91 item['href'] = self._server_instance.base_path + href |
79 | 92 |
80 def Cron(self): | 93 def Cron(self): |
81 futures = [self._cache.GetFromFile('%s/%s_sidenav.json' % | 94 return self._cache.GetFromFile('%s/chrome_sidenav.json' % (JSON_TEMPLATES)) |
82 (JSON_TEMPLATES, platform)) | |
83 for platform in ('apps', 'extensions')] | |
84 return Future(delegate=Gettable(lambda: [f.Get() for f in futures])) | |
85 | 95 |
86 def get(self, key): | 96 def get(self, key): |
87 sidenav = copy.deepcopy(self._cache.GetFromFile( | 97 # TODO(mangini/kalman): Use |key| to decide which sidenav to use, |
88 '%s/%s_sidenav.json' % (JSON_TEMPLATES, key)).Get()) | 98 # which will require a more complex Cron method. |
89 _AddSelected(sidenav, self._server_instance.base_path + self._request.path) | 99 sidenav = self._cache.GetFromFile( |
| 100 '%s/chrome_sidenav.json' % JSON_TEMPLATES).Get() |
| 101 sidenav = copy.deepcopy(sidenav) |
| 102 _AddAnnotations(sidenav, |
| 103 self._server_instance.base_path + self._request.path) |
90 return sidenav | 104 return sidenav |
OLD | NEW |