Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1598)

Unified Diff: chrome/common/extensions/docs/server2/api_data_source.py

Issue 354073004: Docserver: Add template support for object level availability (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/common/extensions/docs/server2/api_data_source_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/common/extensions/docs/server2/api_data_source.py
diff --git a/chrome/common/extensions/docs/server2/api_data_source.py b/chrome/common/extensions/docs/server2/api_data_source.py
index f81dbf2eee63e7b7100b0d15605bed44cc994e22..166faf0c89d3843bb38483ce5febd186adf8b499 100644
--- a/chrome/common/extensions/docs/server2/api_data_source.py
+++ b/chrome/common/extensions/docs/server2/api_data_source.py
@@ -65,6 +65,127 @@ def _GetEventByNameFromEvents(events):
return _GetByNameDict(event_list[0])
+class _APINodeCursor(object):
not at google - send to devlin 2014/06/28 00:21:02 use of this class would be nicer if you used the w
+ '''An abstract representation of a node in an APISchemaGraph.
+ The current position in the graph is represented by a path into the
+ underlying dictionary. So if the APISchemaGraph is:
+
+ {
+ 'tabs': {
+ 'types': {
+ 'Tab': {
+ 'properties': {
+ 'url': {
+ ...
+ }
+ }
+ }
+ }
+ }
+ }
+
+ then the 'url' property would be represented by:
+
+ ['tabs', 'types', 'Tab', 'properties', 'url']
+ '''
+ def __init__(self, availability_finder, namespace_name):
+ # The cursor begins life at the root.
+ self._lookup_path = [namespace_name]
+ self._node_availabilities = availability_finder.GetAPINodeAvailability(
+ namespace_name)
+ self._namespace_name = namespace_name
+
+ def _GetParentPath(self):
+ '''Returns the path pointing to this node's parent.
+ '''
+ assert len(self._lookup_path) > 2, \
+ 'Tried to look up parent for the top-level node.'
+
+ # lookup_path[-1] is the name of the current node.
+ # lookup_path[-2] is this node's category (e.g. types, events, etc.).
+ # Thus, the parent node is described by lookup_path[:-2].
+ return self._lookup_path[:-2]
+
+ def _LookupNodeAvailability(self):
+ '''Returns the ChannelInfo object for this node.
+ '''
+ return self._node_availabilities.Lookup(*self._lookup_path).annotation
+
+ def _LookupParentNodeAvailability(self):
+ '''Returns the ChannelInfo object for this node's parent.
+ '''
+ return self._node_availabilities.Lookup(*self._GetParentPath()).annotation
+
+ def _CheckNamespacePrefix(self):
+ '''API schemas may prepend the namespace name to top-level types
+ (e.g. declarativeWebRequest > types > declarativeWebRequest.IgnoreRules),
+ but just the base name (here, 'IgnoreRules') will be in the |lookup_path|.
+ Try creating an alternate |lookup_path| by adding the namespace name.
+ '''
+ # lookup_path[0] is always the API namespace, and
+ # lookup_path[1] is always the node category (e.g. types, functions, etc.).
+ # Thus, lookup_path[2] is always the top-level node name.
+ base_name = self._lookup_path[2]
+ self._lookup_path[2] = '%s.%s' % (self._namespace_name, base_name)
+ node_availability = self._LookupNodeAvailability()
+ if node_availability is not None:
+ return node_availability
+ # We want to maintain a working lookup_path, so only restore it
+ # if modifying the lookup_path did not work.
+ self._lookup_path[2] = base_name
+ return None
+
+ def _CheckEventCallback(self):
+ '''Within API schemas, an event has a list of 'properties' that the event's
+ callback expects. The callback itself is not explicitly represented in the
+ schema. However, when creating an event node in _JSCModel, a callback node
+ is generated and acts as the parent for the event's properties.
+ Modify |lookup_path| to check the original schema format.
+ '''
+ if 'events' in self._lookup_path and 'callback' in self._lookup_path:
+ lookup_path_copy = copy(self._lookup_path)
+ self._lookup_path.remove('callback')
+ node_availability = self._LookupNodeAvailability()
+ self._lookup_path = lookup_path_copy
+ return node_availability
+ return None
+
+ def GetAvailability(self):
+ '''Returns availability information for this node.
+ '''
+ if self._lookup_path[0] != self._namespace_name:
+ # |lookup_path| won't be lookup up if it doesn't start with the API name.
+ return None
+
+ for lookup in (self._LookupNodeAvailability,
+ self._CheckEventCallback,
+ self._CheckNamespacePrefix):
+ node_availability = lookup()
+ if node_availability is not None:
+ break
+
+ if node_availability is None:
+ logging.warning('No availability found for: %s' % ' > '.join(
+ self._lookup_path))
+ return None
+
+ # Only render this node's availability if it differs from the parent
+ # node's availability.
+ if node_availability == self._LookupParentNodeAvailability():
+ return None
+ return node_availability
+
+ def DescendTo(self, *path):
+ '''Moves down the APISchemaGraph, following |path|.
+ '''
+ self._lookup_path.extend(path)
+
+ def Ascend(self):
+ '''Moves up one node.
+ '''
+ self._lookup_path = self._lookup_path[:-1]
+
+
class _JSCModel(object):
'''Uses a Model from the JSON Schema Compiler and generates a dict that
a Handlebar template can use for a data source.
@@ -72,12 +193,13 @@ class _JSCModel(object):
def __init__(self,
namespace,
- availability,
+ availability_finder,
json_cache,
template_cache,
features_bundle,
event_byname_future):
- self._availability = availability
+ self._availability = availability_finder.GetAPIAvailability(namespace.name)
+ self._current_node = _APINodeCursor(availability_finder, namespace.name)
self._api_availabilities = json_cache.GetFromFile(
posixpath.join(JSON_TEMPLATES, 'api_availabilities.json'))
self._intro_tables = json_cache.GetFromFile(
@@ -127,31 +249,41 @@ class _JSCModel(object):
return self._namespace.name.startswith('experimental')
def _GenerateTypes(self, types):
- return [self._GenerateType(t) for t in types]
+ self._current_node.DescendTo('types')
+ types_ = [self._GenerateType(t) for t in types]
+ self._current_node.Ascend()
+ return types_
def _GenerateType(self, type_):
+ self._current_node.DescendTo(type_.simple_name)
type_dict = {
'name': type_.simple_name,
'description': type_.description,
'properties': self._GenerateProperties(type_.properties),
'functions': self._GenerateFunctions(type_.functions),
'events': self._GenerateEvents(type_.events),
- 'id': _CreateId(type_, 'type')
+ 'id': _CreateId(type_, 'type'),
}
self._RenderTypeInformation(type_, type_dict)
+ self._current_node.Ascend()
return type_dict
def _GenerateFunctions(self, functions):
- return [self._GenerateFunction(f) for f in functions.values()]
+ self._current_node.DescendTo('functions')
+ fns = [self._GenerateFunction(f) for f in functions.values()]
+ self._current_node.Ascend()
+ return fns
def _GenerateFunction(self, function):
+ self._current_node.DescendTo(function.simple_name)
function_dict = {
'name': function.simple_name,
'description': function.description,
'callback': self._GenerateCallback(function.callback),
'parameters': [],
'returns': None,
- 'id': _CreateId(function, 'method')
+ 'id': _CreateId(function, 'method'),
+ 'availability': self._GetAvailabilityTemplate()
}
self._AddCommonProperties(function_dict, function)
if function.returns:
@@ -164,17 +296,25 @@ class _JSCModel(object):
self._GenerateCallbackProperty(function.callback))
if len(function_dict['parameters']) > 0:
function_dict['parameters'][-1]['last'] = True
+ self._current_node.Ascend()
return function_dict
def _GenerateEvents(self, events):
- return [self._GenerateEvent(e) for e in events.values()
- if not e.supports_dom]
+ self._current_node.DescendTo('events')
+ events_ = [self._GenerateEvent(e) for e in events.values()
+ if not e.supports_dom]
+ self._current_node.Ascend()
+ return events_
def _GenerateDomEvents(self, events):
- return [self._GenerateEvent(e) for e in events.values()
- if e.supports_dom]
+ self._current_node.DescendTo('events')
+ events_ = [self._GenerateEvent(e) for e in events.values()
+ if e.supports_dom]
+ self._current_node.Ascend()
+ return events_
def _GenerateEvent(self, event):
+ self._current_node.DescendTo(event.simple_name)
event_dict = {
'name': event.simple_name,
'description': event.description,
@@ -215,6 +355,7 @@ class _JSCModel(object):
# this DOM Event.
event_dict['properties'] += [self._GenerateProperty(param)
for param in event.params]
+ self._current_node.Ascend()
return event_dict
def _GenerateCallback(self, callback):
@@ -336,6 +477,23 @@ class _JSCModel(object):
return intro_rows
+ def _GetAvailabilityTemplate(self, status=None, version=None, scheduled=None):
+ '''Returns an object that the templates use to display availability
+ information.
+ '''
+ if status is None:
+ availability_info = self._current_node.GetAvailability()
+ if availability_info is None:
+ return None
+ status = availability_info.channel
+ version = availability_info.version
+ return {
+ 'partial': self._template_cache.GetFromFile(
+ '%sintro_tables/%s_message.html' % (PRIVATE_TEMPLATES, status)).Get(),
+ 'version': version,
+ 'scheduled': scheduled
+ }
+
def _GetIntroDescriptionRow(self):
''' Generates the 'Description' row data for an API intro table.
'''
@@ -359,14 +517,11 @@ class _JSCModel(object):
scheduled = self._availability.scheduled
return {
'title': 'Availability',
- 'content': [{
- 'partial': self._template_cache.GetFromFile(
- posixpath.join(PRIVATE_TEMPLATES,
- 'intro_tables',
- '%s_message.html' % status)).Get(),
- 'version': version,
- 'scheduled': scheduled
- }]
+ 'content': [
+ self._GetAvailabilityTemplate(status=status,
+ version=version,
+ scheduled=scheduled)
+ ]
}
def _GetIntroDependencyRows(self):
@@ -506,8 +661,7 @@ class APIDataSource(DataSource):
if jsc_model is None:
jsc_model = _JSCModel(
model_future.Get(),
- self._platform_bundle.GetAvailabilityFinder(
- platform).GetAPIAvailability(api_name),
+ self._platform_bundle.GetAvailabilityFinder(platform),
self._json_cache,
self._template_cache,
self._platform_bundle.GetFeaturesBundle(platform),
« no previous file with comments | « no previous file | chrome/common/extensions/docs/server2/api_data_source_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698