15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from copy import copy 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import logging 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import posixpath 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from api_models import GetNodeCategories 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from api_schema_graph import APINodeCursor 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from docs_server_utils import MarkFirstAndLast 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from extensions_paths import JSON_TEMPLATES, PRIVATE_TEMPLATES 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from operator import itemgetter 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from platform_util import PlatformToExtensionType 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import third_party.json_schema_compiler.model as model 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def GetEventByNameFromEvents(events): 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Parses the dictionary |events| to find the definitions of members of the 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type Event. Returns a dictionary mapping the name of a member to that 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) member's definition. 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert 'types' in events, \ 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'The dictionary |events| must contain the key "types".' 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_list = [t for t in events['types'] if t.get('name') == 'Event'] 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert len(event_list) == 1, 'Exactly one type must be called "Event".' 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return _GetByNameDict(event_list[0]) 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def _GetByNameDict(namespace): 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary mapping names to named items from |namespace|. 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This lets us render specific API entities rather than the whole thing at once, 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for example {{apis.manifestTypes.byName.ExternallyConnectable}}. 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Includes items from namespace['types'], namespace['functions'], 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) namespace['events'], and namespace['properties']. 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) by_name = {} 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for item_type in GetNodeCategories(): 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if item_type in namespace: 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_size = len(by_name) 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) by_name.update( 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (item['name'], item) for item in namespace[item_type]) 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert len(by_name) == old_size + len(namespace[item_type]), ( 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'Duplicate name in %r' % namespace) 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return by_name 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def _CreateId(node, prefix): 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node.parent is not None and not isinstance(node.parent, model.Namespace): 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return '-'.join([prefix, node.parent.simple_name, node.simple_name]) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return '-'.join([prefix, node.simple_name]) 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def _FormatValue(value): 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Inserts commas every three digits for integer values. It is magic. 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) s = str(value) 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class JSCView(object): 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Uses a Model from the JSON Schema Compiler and generates a dict that 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) a Motemplate template can use for a data source. 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content_script_apis, 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) jsc_model, 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) availability_finder, 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) json_cache, 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_cache, 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) features_bundle, 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_byname_future, 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) platform): 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._content_script_apis = content_script_apis 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._availability = availability_finder.GetAPIAvailability(jsc_model.name) 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._current_node = APINodeCursor(availability_finder, jsc_model.name) 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._api_availabilities = json_cache.GetFromFile( 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._intro_tables = json_cache.GetFromFile( 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._api_features = features_bundle.GetAPIFeatures() 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._template_cache = template_cache 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._event_byname_future = event_byname_future 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._jsc_model = jsc_model 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._platform = platform 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetLink(self, link): 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ref = link if '.' in link else (self._jsc_model.name + '.' + link) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 'ref': ref, 'text': link, 'name': link } 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def ToDict(self): 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of |self._jsc_model|, which 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is a Namespace object from JSON Schema Compiler. 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert self._jsc_model is not None 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chrome_dot_name = 'chrome.%s' % self._jsc_model.name 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) as_dict = { 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': self._jsc_model.name, 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'namespace': self._jsc_model.documentation_options.get('namespace', 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chrome_dot_name), 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'title': self._jsc_model.documentation_options.get('title', 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chrome_dot_name), 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'documentationOptions': self._jsc_model.documentation_options, 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'types': self._GenerateTypes(self._jsc_model.types.values()), 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'functions': self._GenerateFunctions(self._jsc_model.functions), 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'events': self._GenerateEvents(self._jsc_model.events), 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'domEvents': self._GenerateDomEvents(self._jsc_model.events), 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'properties': self._GenerateProperties(self._jsc_model.properties), 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'introList': self._GetIntroTableList(), 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'channelWarning': self._GetChannelWarning(), 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self._jsc_model.deprecated: 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) as_dict['deprecated'] = self._jsc_model.deprecated 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) as_dict['byName'] = _GetByNameDict(as_dict) 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return as_dict 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _IsExperimental(self): 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self._jsc_model.name.startswith('experimental') 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetChannelWarning(self): 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self._IsExperimental(): 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._availability.channel_info.channel: True 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateCallback(self, callback): 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of a callback suitable 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for consumption by templates. 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not callback: 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_dict = { 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': callback.simple_name, 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'simple_type': {'simple_type': 'function'}, 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'optional': callback.optional, 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'parameters': [] 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('parameters', 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback.simple_name, 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'parameters'): 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for param in callback.params: 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_dict['parameters'].append(self._GenerateProperty(param)) 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (len(callback_dict['parameters']) > 0): 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_dict['parameters'][-1]['last'] = True 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return callback_dict 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateCallbackProperty(self, callback, callback_dict): 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of a callback property 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) suitable for consumption by templates. 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict = { 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': callback.simple_name, 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'description': callback.description, 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'optional': callback.optional, 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'isCallback': True, 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'asFunction': callback_dict, 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'id': _CreateId(callback, 'property'), 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'simple_type': 'function', 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (callback.parent is not None and 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not isinstance(callback.parent, model.Namespace)): 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict['parentName'] = callback.parent.simple_name 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return property_dict 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateTypes(self, types): 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a list of dictionaries representing this Model's types. 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('types'): 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [self._GenerateType(t) for t in types] 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateType(self, type_): 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of a type from JSON Schema Compiler. 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(type_.simple_name): 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_dict = { 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': type_.simple_name, 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'description': type_.description, 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'properties': self._GenerateProperties(type_.properties), 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'functions': self._GenerateFunctions(type_.functions), 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'events': self._GenerateEvents(type_.events), 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'id': _CreateId(type_, 'type'), 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'availability': self._GetAvailabilityTemplate() 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._RenderTypeInformation(type_, type_dict) 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return type_dict 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateFunctions(self, functions): 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a list of dictionaries representing this Model's functions. 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('functions'): 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [self._GenerateFunction(f) for f in functions.values()] 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateFunction(self, function): 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of a function from 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) JSON Schema Compiler. 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # When ignoring types, properties must be ignored as well. 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(function.simple_name, 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ignore=('types', 'properties')): 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function_dict = { 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': function.simple_name, 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'description': function.description, 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'callback': self._GenerateCallback(function.callback), 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'parameters': [], 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'returns': None, 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'id': _CreateId(function, 'method'), 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'availability': self._GetAvailabilityTemplate() 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._AddCommonProperties(function_dict, function) 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if function.returns: 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function_dict['returns'] = self._GenerateType(function.returns) 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(function.simple_name, 'parameters'): 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for param in function.params: 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function_dict['parameters'].append(self._GenerateProperty(param)) 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if function.callback is not None: 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Show the callback as an extra parameter. 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function_dict['parameters'].append( 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._GenerateCallbackProperty(function.callback, 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function_dict['callback'])) 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(function_dict['parameters']) > 0: 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function_dict['parameters'][-1]['last'] = True 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return function_dict 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateEvents(self, events): 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a list of dictionaries representing this Model's events. 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('events'): 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [self._GenerateEvent(e) for e in events.values() 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not e.supports_dom] 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateDomEvents(self, events): 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a list of dictionaries representing this Model's DOM events. 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('events'): 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [self._GenerateEvent(e) for e in events.values() 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if e.supports_dom] 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateEvent(self, event): 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of an event from 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) JSON Schema Compiler. Note that although events are modeled as functions 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in JSON Schema Compiler, we model them differently for the templates. 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(event.simple_name, ignore=('properties',)): 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_dict = { 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': event.simple_name, 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'description': event.description, 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'filters': [self._GenerateProperty(f) for f in event.filters], 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'conditions': [self._GetLink(condition) 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for condition in event.conditions], 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'actions': [self._GetLink(action) for action in event.actions], 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'supportsRules': event.supports_rules, 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'supportsListeners': event.supports_listeners, 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'properties': [], 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'id': _CreateId(event, 'event'), 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'byName': {}, 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'availability': self._GetAvailabilityTemplate() 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._AddCommonProperties(event_dict, event) 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Add the Event members to each event in this object. 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self._event_byname_future: 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_dict['byName'].update(self._event_byname_future.Get()) 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # We need to create the method description for addListener based on the 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # information stored in |event|. 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if event.supports_listeners: 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_object = model.Function(parent=event, 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name='callback', 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) json={}, 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) namespace=event.parent, 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) origin='') 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_object.params = event.params 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if event.callback: 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_object.callback = event.callback 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(event.simple_name): 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback = self._GenerateFunction(callback_object) 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_parameter = self._GenerateCallbackProperty(callback_object, 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback) 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_parameter['last'] = True 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_dict['byName']['addListener'] = { 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': 'addListener', 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'callback': callback, 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'parameters': [callback_parameter] 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if event.supports_dom: 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Treat params as properties of the custom Event object associated with 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # this DOM Event. 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(event.simple_name, 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ignore=('properties',)): 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_dict['properties'] += [self._GenerateProperty(param) 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for param in event.params] 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return event_dict 2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateProperties(self, properties): 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a list of dictionaries representing this Model's properites. 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('properties'): 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [self._GenerateProperty(v) for v in properties.values()] 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GenerateProperty(self, property_): 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns a dictionary representation of a property from 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) JSON Schema Compiler. 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not hasattr(property_, 'type_'): 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for d in dir(property_): 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not d.startswith('_'): 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) print ('%s -> %s' % (d, getattr(property_, d))) 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_ = property_.type_ 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Make sure we generate property info for arrays, too. 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # TODO(kalman): what about choices? 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type_.property_type == model.PropertyType.ARRAY: 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) properties = type_.item_type.properties 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) properties = type_.properties 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(property_.simple_name): 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict = { 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'name': property_.simple_name, 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'optional': property_.optional, 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'description': property_.description, 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'properties': self._GenerateProperties(type_.properties), 3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'functions': self._GenerateFunctions(type_.functions), 3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'parameters': [], 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'returns': None, 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'id': _CreateId(property_, 'property'), 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'availability': self._GetAvailabilityTemplate() 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._AddCommonProperties(property_dict, property_) 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type_.property_type == model.PropertyType.FUNCTION: 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function = type_.function 3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend('parameters'): 3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for param in function.params: 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict['parameters'].append(self._GenerateProperty(param)) 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if function.returns: 3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(ignore=('types', 'properties')): 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict['returns'] = self._GenerateType(function.returns) 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value = property_.value 3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if value is not None: 3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(value, int): 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict['value'] = _FormatValue(value) 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) property_dict['value'] = value 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._RenderTypeInformation(type_, property_dict) 3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return property_dict 3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _AddCommonProperties(self, target, src): 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if src.deprecated is not None: 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target['deprecated'] = src.deprecated 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (src.parent is not None and 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not isinstance(src.parent, model.Namespace)): 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target['parentName'] = src.parent.simple_name 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _RenderTypeInformation(self, type_, dst_dict): 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with self._current_node.Descend(ignore=('types', 'properties')): 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['is_object'] = type_.property_type == model.PropertyType.OBJECT 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type_.property_type == model.PropertyType.CHOICES: 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['choices'] = self._GenerateTypes(type_.choices) 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # We keep track of which == last for knowing when to add "or" between 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # choices in templates. 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(dst_dict['choices']) > 0: 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['choices'][-1]['last'] = True 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type_.property_type == model.PropertyType.REF: 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['link'] = self._GetLink(type_.ref_type) 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type_.property_type == model.PropertyType.ARRAY: 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['array'] = self._GenerateType(type_.item_type) 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type_.property_type == model.PropertyType.ENUM: 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['enum_values'] = [ 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) {'name': value.name, 'description': value.description} 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for value in type_.enum_values] 3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(dst_dict['enum_values']) > 0: 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['enum_values'][-1]['last'] = True 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type_.instance_of is not None: 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['simple_type'] = type_.instance_of 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dst_dict['simple_type'] = type_.property_type.name 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _CreateAvailabilityTemplate(self, status, scheduled, version): 3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Returns an object suitable for use in templates to display availability 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) information. 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # TODO(rockot): Temporary hack. Remove this very soon. 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if status == 'master': 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci status = 'trunk' 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'partial': self._template_cache.GetFromFile( 3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '%sintro_tables/%s_message.html' % (PRIVATE_TEMPLATES, status)).Get(), 3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'scheduled': scheduled, 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'version': version 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetAvailabilityTemplate(self): 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Gets availability for the current node and returns an appropriate 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template object. 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Displaying deprecated status takes precedence over when the API 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # became stable. 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) availability_info = self._current_node.GetDeprecated() 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if availability_info is not None: 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = 'deprecated' 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) availability_info = self._current_node.GetAvailability() 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if availability_info is None: 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = availability_info.channel_info.channel 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self._CreateAvailabilityTemplate( 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status, 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) availability_info.scheduled, 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) availability_info.channel_info.version) 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetIntroTableList(self): 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Create a generic data structure that can be traversed by the templates 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) to create an API intro table. 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) intro_rows = [ 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._GetIntroDescriptionRow(), 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._GetIntroAvailabilityRow() 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ] + self._GetIntroDependencyRows() + self._GetIntroContentScriptRow() 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Add rows using data from intro_tables.json, overriding any existing rows 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if they share the same 'title' attribute. 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) row_titles = [row['title'] for row in intro_rows] 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for misc_row in self._GetMiscIntroRows(): 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if misc_row['title'] in row_titles: 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) intro_rows[row_titles.index(misc_row['title'])] = misc_row 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) intro_rows.append(misc_row) 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return intro_rows 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetIntroContentScriptRow(self): 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '''Generates the 'Content Script' row data for an API intro table. 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content_script_support = self._content_script_apis.get(self._jsc_model.name) 4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if content_script_support is None: 4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [] 4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if content_script_support.restrictedTo: 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content_script_support.restrictedTo.sort(key=itemgetter('node')) 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MarkFirstAndLast(content_script_support.restrictedTo) 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [{ 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'title': 'Content Scripts', 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'content': [{ 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'partial': self._template_cache.GetFromFile( 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) posixpath.join(PRIVATE_TEMPLATES, 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'intro_tables', 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'content_scripts.html')).Get(), 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'contentScriptSupport': content_script_support.__dict__ 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }] 4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }] 4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetIntroDescriptionRow(self): 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' Generates the 'Description' row data for an API intro table. 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'title': 'Description', 4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'content': [ 4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 'text': self._jsc_model.description } 4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ] 4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetIntroAvailabilityRow(self): 4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' Generates the 'Availability' row data for an API intro table. 4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self._IsExperimental(): 4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = 'experimental' 4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scheduled = None 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version = None 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = self._availability.channel_info.channel 4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scheduled = self._availability.scheduled 4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version = self._availability.channel_info.version 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'title': 'Availability', 4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'content': [ 4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._CreateAvailabilityTemplate(status, scheduled, version) 4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ] 4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetIntroDependencyRows(self): 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Devtools aren't in _api_features. If we're dealing with devtools, bail. 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if 'devtools' in self._jsc_model.name: 4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [] 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api_feature = self._api_features.Get().get(self._jsc_model.name) 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not api_feature: 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logging.error('"%s" not found in _api_features.json' % 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._jsc_model.name) 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return [] 4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) permissions_content = [] 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) manifest_content = [] 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def categorize_dependency(dependency): 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def make_code_node(text): 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 'class': 'code', 'text': text } 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context, name = dependency.split(':', 1) 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if context == 'permission': 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) permissions_content.append(make_code_node('"%s"' % name)) 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif context == 'manifest': 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) manifest_content.append(make_code_node('"%s": {...}' % name)) 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif context == 'api': 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) transitive_dependencies = ( 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._api_features.Get().get(name, {}).get('dependencies', [])) 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for transitive_dependency in transitive_dependencies: 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) categorize_dependency(transitive_dependency) 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logging.error('Unrecognized dependency for %s: %s' % 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self._jsc_model.name, context)) 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for dependency in api_feature.get('dependencies', ()): 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) categorize_dependency(dependency) 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dependency_rows = [] 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if permissions_content: 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dependency_rows.append({ 5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'title': 'Permissions', 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'content': permissions_content 5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }) 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if manifest_content: 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dependency_rows.append({ 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'title': 'Manifest', 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'content': manifest_content 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }) 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return dependency_rows 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _GetMiscIntroRows(self): 5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' Generates miscellaneous intro table row data, such as 'Permissions', 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'Samples', and 'Learn More', using intro_tables.json. 5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ''' 5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) misc_rows = [] 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Look up the API name in intro_tables.json, which is structured 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # similarly to the data structure being created. If the name is found, loop 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # through the attributes and add them to this structure. 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) table_info = self._intro_tables.Get().get(self._jsc_model.name) 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if table_info is None: 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return misc_rows 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for category in table_info.iterkeys(): 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content = [] 5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for node in table_info[category]: 5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ext_type = PlatformToExtensionType(self._platform) 5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Don't display nodes restricted to a different platform. 5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ext_type not in node.get('extension_types', (ext_type,)): 5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If there is a 'partial' argument and it hasn't already been 55703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) # converted to a Motemplate object, transform it to a template. 5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if 'partial' in node: 5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Note: it's enough to copy() not deepcopy() because only a single 5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # top-level key is being modified. 5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = copy(node) 5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node['partial'] = self._template_cache.GetFromFile( 5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) posixpath.join(PRIVATE_TEMPLATES, node['partial'])).Get() 5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content.append(node) 5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) misc_rows.append({ 'title': category, 'content': content }) 5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return misc_rows 567