15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import copy 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import logging 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)from environment import IsPreviewServer 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)from extensions_paths import ( 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) API, API_FEATURES, JSON_TEMPLATES, PRIVATE_TEMPLATES) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import third_party.json_schema_compiler.json_parse as json_parse 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import third_party.json_schema_compiler.model as model 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)from environment import IsPreviewServer 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)from third_party.json_schema_compiler.memoize import memoize 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _CreateId(node, prefix): 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.parent is not None and not isinstance(node.parent, model.Namespace): 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '-'.join([prefix, node.parent.simple_name, node.simple_name]) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '-'.join([prefix, node.simple_name]) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _FormatValue(value): 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) '''Inserts commas every three digits for integer values. It is magic. 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = str(value) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)def _GetByNameDict(namespace): 320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) '''Returns a dictionary mapping names to named items from |namespace|. 330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) This lets us render specific API entities rather than the whole thing at once, 350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for example {{apis.manifestTypes.byName.ExternallyConnectable}}. 360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Includes items from namespace['types'], namespace['functions'], 380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) namespace['events'], and namespace['properties']. 390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ''' 400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) by_name = {} 410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for item_type in ('types', 'functions', 'events', 'properties'): 420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if item_type in namespace: 430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) old_size = len(by_name) 440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) by_name.update( 450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) (item['name'], item) for item in namespace[item_type]) 460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) assert len(by_name) == old_size + len(namespace[item_type]), ( 470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'Duplicate name in %r' % namespace) 480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return by_name 490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)def _GetEventByNameFromEvents(events): 520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) '''Parses the dictionary |events| to find the definitions of members of the 530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) type Event. Returns a dictionary mapping the name of a member to that 540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) member's definition. 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert 'types' in events, \ 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'The dictionary |events| must contain the key "types".' 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_list = [t for t in events['types'] if t.get('name') == 'Event'] 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert len(event_list) == 1, 'Exactly one type must be called "Event".' 600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return _GetByNameDict(event_list[0]) 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class _JSCModel(object): 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) '''Uses a Model from the JSON Schema Compiler and generates a dict that 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a Handlebar template can use for a data source. 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def __init__(self, 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api_name, 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api_models, 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ref_resolver, 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch disable_refs, 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch availability_finder, 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) json_cache, 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) template_cache, 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_byname_function): 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver = ref_resolver 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._disable_refs = disable_refs 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch self._availability_finder = availability_finder 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_availabilities = json_cache.GetFromFile( 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '%s/api_availabilities.json' % JSON_TEMPLATES) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._intro_tables = json_cache.GetFromFile( 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '%s/intro_tables.json' % JSON_TEMPLATES) 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_features = json_cache.GetFromFile(API_FEATURES) 850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._template_cache = template_cache 860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._event_byname_function = event_byname_function 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._namespace = api_models.GetModel(api_name).Get() 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _FormatDescription(self, description): 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._disable_refs: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._ref_resolver.ResolveAllLinks(description, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) namespace=self._namespace.name) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GetLink(self, link): 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._disable_refs: 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_name = link.split('.', 1)[-1] 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return { 'href': '#type-%s' % type_name, 'text': link, 'name': link } 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._ref_resolver.SafeGetLink(link, namespace=self._namespace.name) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ToDict(self): 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._namespace is None: 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return {} 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome_dot_name = 'chrome.%s' % self._namespace.name 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) as_dict = { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': self._namespace.name, 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 'namespace': self._namespace.documentation_options.get('namespace', 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome_dot_name), 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 'title': self._namespace.documentation_options.get('title', 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome_dot_name), 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'documentationOptions': self._namespace.documentation_options, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'types': self._GenerateTypes(self._namespace.types.values()), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'functions': self._GenerateFunctions(self._namespace.functions), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'events': self._GenerateEvents(self._namespace.events), 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'domEvents': self._GenerateDomEvents(self._namespace.events), 116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'properties': self._GenerateProperties(self._namespace.properties), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # Rendering the intro list is really expensive and there's no point doing it 1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # unless we're rending the page - and disable_refs=True implies we're not. 1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if not self._disable_refs: 1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) as_dict.update({ 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'introList': self._GetIntroTableList(), 1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'channelWarning': self._GetChannelWarning(), 1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) }) 1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) as_dict['byName'] = _GetByNameDict(as_dict) 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return as_dict 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def _GetApiAvailability(self): 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return self._availability_finder.GetApiAvailability(self._namespace.name) 130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def _GetChannelWarning(self): 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if not self._IsExperimental(): 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return { self._GetApiAvailability().channel: True } 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return None 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def _IsExperimental(self): 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._namespace.name.startswith('experimental') 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateTypes(self, types): 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [self._GenerateType(t) for t in types] 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateType(self, type_): 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_dict = { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': type_.simple_name, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(type_.description), 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'properties': self._GenerateProperties(type_.properties), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'functions': self._GenerateFunctions(type_.functions), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'events': self._GenerateEvents(type_.events), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(type_, 'type') 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._RenderTypeInformation(type_, type_dict) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type_dict 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateFunctions(self, functions): 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self._GenerateFunction(f) for f in functions.values()] 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateFunction(self, function): 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict = { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': function.simple_name, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(function.description), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'callback': self._GenerateCallback(function.callback), 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [], 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'returns': None, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(function, 'method') 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._AddCommonProperties(function_dict, function) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if function.returns: 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function_dict['returns'] = self._GenerateType(function.returns) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for param in function.params: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parameters'].append(self._GenerateProperty(param)) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if function.callback is not None: 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Show the callback as an extra parameter. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function_dict['parameters'].append( 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GenerateCallbackProperty(function.callback)) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(function_dict['parameters']) > 0: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parameters'][-1]['last'] = True 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return function_dict 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateEvents(self, events): 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return [self._GenerateEvent(e) for e in events.values() 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if not e.supports_dom] 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _GenerateDomEvents(self, events): 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return [self._GenerateEvent(e) for e in events.values() 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if e.supports_dom] 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateEvent(self, event): 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dict = { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': event.simple_name, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(event.description), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'filters': [self._GenerateProperty(f) for f in event.filters], 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'conditions': [self._GetLink(condition) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for condition in event.conditions], 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'actions': [self._GetLink(action) for action in event.actions], 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'supportsRules': event.supports_rules, 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'supportsListeners': event.supports_listeners, 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'properties': [], 1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'id': _CreateId(event, 'event'), 1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'byName': {}, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._AddCommonProperties(event_dict, event) 2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # Add the Event members to each event in this object. 2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # If refs are disabled then don't worry about this, since it's only needed 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # for rendering, and disable_refs=True implies we're not rendering. 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if self._event_byname_function and not self._disable_refs: 2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) event_dict['byName'].update(self._event_byname_function()) 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # We need to create the method description for addListener based on the 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # information stored in |event|. 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if event.supports_listeners: 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_object = model.Function(parent=event, 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) name='callback', 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) json={}, 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) namespace=event.parent, 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) origin='') 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_object.params = event.params 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if event.callback: 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_object.callback = event.callback 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_parameters = self._GenerateCallbackProperty(callback_object) 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_parameters['last'] = True 2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) event_dict['byName']['addListener'] = { 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'name': 'addListener', 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'callback': self._GenerateFunction(callback_object), 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'parameters': [callback_parameters] 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if event.supports_dom: 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Treat params as properties of the custom Event object associated with 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # this DOM Event. 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) event_dict['properties'] += [self._GenerateProperty(param) 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for param in event.params] 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event_dict 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateCallback(self, callback): 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not callback: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_dict = { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': callback.simple_name, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'simple_type': {'simple_type': 'function'}, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'optional': callback.optional, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [] 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for param in callback.params: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_dict['parameters'].append(self._GenerateProperty(param)) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len(callback_dict['parameters']) > 0): 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_dict['parameters'][-1]['last'] = True 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return callback_dict 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateProperties(self, properties): 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [self._GenerateProperty(v) for v in properties.values()] 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateProperty(self, property_): 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not hasattr(property_, 'type_'): 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for d in dir(property_): 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not d.startswith('_'): 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) print ('%s -> %s' % (d, getattr(property_, d))) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_ = property_.type_ 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Make sure we generate property info for arrays, too. 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(kalman): what about choices? 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type == model.PropertyType.ARRAY: 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) properties = type_.item_type.properties 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) properties = type_.properties 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict = { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': property_.simple_name, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'optional': property_.optional, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(property_.description), 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'properties': self._GenerateProperties(type_.properties), 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'functions': self._GenerateFunctions(type_.functions), 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [], 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'returns': None, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(property_, 'property') 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._AddCommonProperties(property_dict, property_) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type == model.PropertyType.FUNCTION: 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function = type_.function 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for param in function.params: 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_dict['parameters'].append(self._GenerateProperty(param)) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if function.returns: 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_dict['returns'] = self._GenerateType(function.returns) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value = property_.value 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if value is not None: 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if isinstance(value, int): 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_dict['value'] = _FormatValue(value) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_dict['value'] = value 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._RenderTypeInformation(type_, property_dict) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return property_dict 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateCallbackProperty(self, callback): 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_dict = { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'name': callback.simple_name, 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'description': self._FormatDescription(callback.description), 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'optional': callback.optional, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'id': _CreateId(callback, 'property'), 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'simple_type': 'function', 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (callback.parent is not None and 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) not isinstance(callback.parent, model.Namespace)): 304bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch property_dict['parentName'] = callback.parent.simple_name 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return property_dict 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _RenderTypeInformation(self, type_, dst_dict): 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dst_dict['is_object'] = type_.property_type == model.PropertyType.OBJECT 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type == model.PropertyType.CHOICES: 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dst_dict['choices'] = self._GenerateTypes(type_.choices) 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # We keep track of which == last for knowing when to add "or" between 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # choices in templates. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(dst_dict['choices']) > 0: 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['choices'][-1]['last'] = True 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif type_.property_type == model.PropertyType.REF: 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dst_dict['link'] = self._GetLink(type_.ref_type) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif type_.property_type == model.PropertyType.ARRAY: 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dst_dict['array'] = self._GenerateType(type_.item_type) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif type_.property_type == model.PropertyType.ENUM: 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) dst_dict['enum_values'] = [ 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) {'name': value.name, 'description': value.description} 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for value in type_.enum_values] 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(dst_dict['enum_values']) > 0: 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['enum_values'][-1]['last'] = True 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif type_.instance_of is not None: 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dst_dict['simple_type'] = type_.instance_of.lower() 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dst_dict['simple_type'] = type_.property_type.name.lower() 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def _GetIntroTableList(self): 331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) '''Create a generic data structure that can be traversed by the templates 332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) to create an API intro table. 333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) intro_rows = [ 335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) self._GetIntroDescriptionRow(), 336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) self._GetIntroAvailabilityRow() 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ] + self._GetIntroDependencyRows() 338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # Add rows using data from intro_tables.json, overriding any existing rows 340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # if they share the same 'title' attribute. 341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) row_titles = [row['title'] for row in intro_rows] 342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for misc_row in self._GetMiscIntroRows(): 343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if misc_row['title'] in row_titles: 344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) intro_rows[row_titles.index(misc_row['title'])] = misc_row 345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else: 346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) intro_rows.append(misc_row) 347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return intro_rows 349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def _GetIntroDescriptionRow(self): 351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' Generates the 'Description' row data for an API intro table. 352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return { 354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'title': 'Description', 355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'content': [ 356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) { 'text': self._FormatDescription(self._namespace.description) } 357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ] 358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def _GetIntroAvailabilityRow(self): 361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' Generates the 'Availability' row data for an API intro table. 362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if self._IsExperimental(): 364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) status = 'experimental' 365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) version = None 366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else: 367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) availability = self._GetApiAvailability() 368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) status = availability.channel 369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) version = availability.version 370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return { 371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'title': 'Availability', 372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'content': [{ 3730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'partial': self._template_cache.GetFromFile( 3740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) '%s/intro_tables/%s_message.html' % 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (PRIVATE_TEMPLATES, status)).Get(), 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'version': version 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }] 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def _GetIntroDependencyRows(self): 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # Devtools aren't in _api_features. If we're dealing with devtools, bail. 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if 'devtools' in self._namespace.name: 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return [] 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) feature = self._api_features.Get().get(self._namespace.name) 385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) assert feature, ('"%s" not found in _api_features.json.' 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) % self._namespace.name) 387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dependencies = feature.get('dependencies') 389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if dependencies is None: 390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return [] 391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def make_code_node(text): 393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return { 'class': 'code', 'text': text } 394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) permissions_content = [] 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) manifest_content = [] 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def categorize_dependency(dependency): 399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) context, name = dependency.split(':', 1) 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if context == 'permission': 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) permissions_content.append(make_code_node('"%s"' % name)) 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) elif context == 'manifest': 403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) manifest_content.append(make_code_node('"%s": {...}' % name)) 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) elif context == 'api': 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) transitive_dependencies = ( 4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._api_features.Get().get(name, {}).get('dependencies', [])) 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for transitive_dependency in transitive_dependencies: 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) categorize_dependency(transitive_dependency) 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else: 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) raise ValueError('Unrecognized dependency for %s: %s' % ( 411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) self._namespace.name, context)) 412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for dependency in dependencies: 414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) categorize_dependency(dependency) 415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dependency_rows = [] 417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if permissions_content: 418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dependency_rows.append({ 419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'title': 'Permissions', 420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'content': permissions_content 421424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }) 422424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if manifest_content: 423424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dependency_rows.append({ 424424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'title': 'Manifest', 425424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'content': manifest_content 426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }) 427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return dependency_rows 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) def _GetMiscIntroRows(self): 430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' Generates miscellaneous intro table row data, such as 'Permissions', 431424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 'Samples', and 'Learn More', using intro_tables.json. 432424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) misc_rows = [] 434424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # Look up the API name in intro_tables.json, which is structured 435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # similarly to the data structure being created. If the name is found, loop 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # through the attributes and add them to this structure. 4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) table_info = self._intro_tables.Get().get(self._namespace.name) 438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if table_info is None: 439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return misc_rows 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for category in table_info.keys(): 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) content = copy.deepcopy(table_info[category]) 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for node in content: 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # If there is a 'partial' argument and it hasn't already been 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) # converted to a Handlebar object, transform it to a template. 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if 'partial' in node: 4470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) node['partial'] = self._template_cache.GetFromFile('%s/%s' % 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (PRIVATE_TEMPLATES, node['partial'])).Get() 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) misc_rows.append({ 'title': category, 'content': content }) 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return misc_rows 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def _AddCommonProperties(self, target, src): 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if src.deprecated is not None: 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) target['deprecated'] = self._FormatDescription( 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) src.deprecated) 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (src.parent is not None and 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) not isinstance(src.parent, model.Namespace)): 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) target['parentName'] = src.parent.simple_name 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class _LazySamplesGetter(object): 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) '''This class is needed so that an extensions API page does not have to fetch 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the apps samples page and vice versa. 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, api_name, samples): 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._api_name = api_name 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples = samples 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get(self, key): 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._samples.FilterSamples(key, self._api_name) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class APIDataSource(object): 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) '''This class fetches and loads JSON APIs from the FileSystem passed in with 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) |compiled_fs_factory|, so the APIs can be plugged into templates. 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Factory(object): 480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def __init__(self, 481ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch compiled_fs_factory, 4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_system, 483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) availability_finder, 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api_models, 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) object_store_creator): 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._json_cache = compiled_fs_factory.ForJson(file_system) 4870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._template_cache = compiled_fs_factory.ForTemplates(file_system) 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._availability_finder = availability_finder 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_models = api_models 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._model_cache_refs = object_store_creator.Create( 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) APIDataSource, 'model-cache-refs') 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._model_cache_no_refs = object_store_creator.Create( 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) APIDataSource, 'model-cache-no-refs') 4940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # These must be set later via the SetFooDataSourceFactory methods. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory = None 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples_data_source_factory = None 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # This caches the result of _LoadEventByName. 5000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._event_byname = None 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SetSamplesDataSourceFactory(self, samples_data_source_factory): 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples_data_source_factory = samples_data_source_factory 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SetReferenceResolverFactory(self, ref_resolver_factory): 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory = ref_resolver_factory 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) def Create(self, request): 5090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) '''Creates an APIDataSource. 510424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ''' 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._samples_data_source_factory is None: 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Only error if there is a request, which means this APIDataSource is 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # actually being used to render a page. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if request is not None: 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.error('SamplesDataSource.Factory was never set in ' 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'APIDataSource.Factory.') 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples = None 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples = self._samples_data_source_factory.Create(request) 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return APIDataSource(self._GetSchemaModel, samples) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) def _LoadEventByName(self): 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '''All events have some members in common. We source their description 5240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) from Event in events.json. 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ''' 5260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if self._event_byname is None: 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._event_byname = _GetEventByNameFromEvents( 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._GetSchemaModel('events', True)) 5290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return self._event_byname 5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def _GetModelCache(self, disable_refs): 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if disable_refs: 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._model_cache_no_refs 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._model_cache_refs 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def _GetSchemaModel(self, api_name, disable_refs): 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) jsc_model = self._GetModelCache(disable_refs).Get(api_name).Get() 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if jsc_model is not None: 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return jsc_model 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) jsc_model = _JSCModel( 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api_name, 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_models, 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory.Create() if not disable_refs else None, 54590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) disable_refs, 546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch self._availability_finder, 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._json_cache, 5480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._template_cache, 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._LoadEventByName).ToDict() 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._GetModelCache(disable_refs).Set(api_name, jsc_model) 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return jsc_model 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __init__(self, get_schema_model, samples): 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._get_schema_model = get_schema_model 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples = samples 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _GenerateHandlebarContext(self, handlebar_dict): 5590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # Parsing samples on the preview server takes seconds and doesn't add 5600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # anything. Don't do it. 5610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if not IsPreviewServer(): 5620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) handlebar_dict['samples'] = _LazySamplesGetter( 5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) handlebar_dict['name'], 5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._samples) 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return handlebar_dict 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def get(self, api_name, disable_refs=False): 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._GenerateHandlebarContext( 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._get_schema_model(api_name, disable_refs)) 570