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
3 # found in the LICENSE file.
9 from compiled_file_system
import Cache
, SingleFile
, Unicode
10 from data_source
import DataSource
11 from extensions_paths
import JSON_TEMPLATES
12 from future
import Future
13 from third_party
.json_schema_compiler
.json_parse
import Parse
16 def _AddLevels(items
, level
):
17 '''Add a 'level' key to each item in |items|. 'level' corresponds to how deep
18 in |items| an item is. |level| sets the starting depth.
23 _AddLevels(item
['items'], level
+ 1)
26 def _AddAnnotations(items
, path
, parent
=None):
27 '''Add 'selected', 'child_selected' and 'related' properties to
28 |items| so that the sidenav can be expanded to show which menu item has
29 been selected and the related pages section can be drawn. 'related'
30 is added to all items with the same parent as the selected item.
31 If more than one item exactly matches the path, the deepest one is considered
32 'selected'. A 'parent' property is added to the selected path.
34 Returns True if an item was marked 'selected'.
38 if _AddAnnotations(item
['items'], path
, item
):
39 item
['child_selected'] = True
42 if item
.get('href', '') == path
:
43 item
['selected'] = True
45 item
['parent'] = { 'title': parent
.get('title', None),
46 'href': parent
.get('href', None) }
49 sibling
['related'] = True
56 class SidenavDataSource(DataSource
):
57 '''Provides templates with access to JSON files used to create the side
60 def __init__(self
, server_instance
, request
):
61 self
._cache
= server_instance
.compiled_fs_factory
.Create(
62 server_instance
.host_file_system_provider
.GetMaster(),
63 self
._CreateSidenavDict
,
65 self
._server
_instance
= server_instance
66 self
._request
= request
71 def _CreateSidenavDict(self
, _
, content
):
72 items
= Parse(content
)
73 # Start at level 2, the top <ul> element is level 1.
74 _AddLevels(items
, level
=2)
75 self
._QualifyHrefs
(items
)
78 def _QualifyHrefs(self
, items
):
79 '''Force hrefs in |items| to either be absolute (http://...) or qualified
80 (beginning with /, in which case it will be moved relative to |base_path|).
81 Relative hrefs emit a warning and should be updated.
85 self
._QualifyHrefs
(item
['items'])
87 href
= item
.get('href')
88 if href
is not None and not href
.startswith(('http://', 'https://')):
89 if not href
.startswith('/'):
90 logging
.warn('Paths in sidenav must be qualified. %s is not.' % href
)
92 href
= href
.lstrip('/')
93 item
['href'] = self
._server
_instance
.base_path
+ href
96 return self
._cache
.GetFromFile(
97 posixpath
.join(JSON_TEMPLATES
, 'chrome_sidenav.json'))
100 # TODO(mangini/kalman): Use |key| to decide which sidenav to use,
101 # which will require a more complex Refresh method.
102 sidenav
= self
._cache
.GetFromFile(
103 posixpath
.join(JSON_TEMPLATES
, 'chrome_sidenav.json')).Get()
104 sidenav
= copy
.deepcopy(sidenav
)
105 _AddAnnotations(sidenav
,
106 self
._server
_instance
.base_path
+ self
._request
.path
)