diff options
21 files changed, 587 insertions, 45 deletions
diff --git a/chrome/common/extensions/docs/server2/branch_utility.py b/chrome/common/extensions/docs/server2/branch_utility.py index 795e62f..1872f7d 100644 --- a/chrome/common/extensions/docs/server2/branch_utility.py +++ b/chrome/common/extensions/docs/server2/branch_utility.py @@ -7,12 +7,16 @@ import json OMAHA_PROXY_URL = 'http://omahaproxy.appspot.com/json' -def GetChannelNameFromPath(path): - first_part = path.split('/')[0] - if first_part in ['trunk', 'dev', 'beta', 'stable', 'local']: - return first_part +def SplitChannelNameFromPath(path, default='stable'): + try: + first, second = path.split('/', 1) + except ValueError: + first = path + second ='' + if first in ['trunk', 'dev', 'beta', 'stable']: + return (first, second) else: - return 'stable' + return (default, path) def GetBranchNumberForChannelName(channel_name, urlfetch, diff --git a/chrome/common/extensions/docs/server2/branch_utility_test.py b/chrome/common/extensions/docs/server2/branch_utility_test.py index ee5728c..df872d2 100755 --- a/chrome/common/extensions/docs/server2/branch_utility_test.py +++ b/chrome/common/extensions/docs/server2/branch_utility_test.py @@ -8,17 +8,22 @@ import unittest import test_urlfetch class BranchUtilityTest(unittest.TestCase): - def testGetChannelNameFromPath(self): - self.assertEquals('dev', branch_utility.GetChannelNameFromPath( - 'dev/hello/stuff.html')) - self.assertEquals('beta', branch_utility.GetChannelNameFromPath( - 'beta/hello/stuff.html')) - self.assertEquals('trunk', branch_utility.GetChannelNameFromPath( - 'trunk/hello/stuff.html')) - self.assertEquals('stable', branch_utility.GetChannelNameFromPath( - 'hello/stuff.html')) - self.assertEquals('stable', branch_utility.GetChannelNameFromPath( - 'hello/dev/stuff.html')) + def testSplitChannelNameFromPath(self): + self.assertEquals(('dev', 'hello/stuff.html'), + branch_utility.SplitChannelNameFromPath( + 'dev/hello/stuff.html')) + self.assertEquals(('beta', 'hello/stuff.html'), + branch_utility.SplitChannelNameFromPath( + 'beta/hello/stuff.html')) + self.assertEquals(('trunk', 'hello/stuff.html'), + branch_utility.SplitChannelNameFromPath( + 'trunk/hello/stuff.html')) + self.assertEquals(('stable', 'hello/stuff.html'), + branch_utility.SplitChannelNameFromPath( + 'hello/stuff.html')) + self.assertEquals(('stable', 'hello/dev/stuff.html'), + branch_utility.SplitChannelNameFromPath( + 'hello/dev/stuff.html')) def testGetBranchNumberForChannelName(self): base_path = 'branch_utility/first.json' diff --git a/chrome/common/extensions/docs/server2/echo_handler.py b/chrome/common/extensions/docs/server2/echo_handler.py index 6ee0801..d948a40 100755 --- a/chrome/common/extensions/docs/server2/echo_handler.py +++ b/chrome/common/extensions/docs/server2/echo_handler.py @@ -29,8 +29,13 @@ from template_data_source import TemplateDataSource EXTENSIONS_PATH = 'chrome/common/extensions' DOCS_PATH = 'docs' API_PATH = 'api' -PUBLIC_TEMPLATE_PATH = DOCS_PATH + '/template2/public' -PRIVATE_TEMPLATE_PATH = DOCS_PATH + '/template2/private' +PUBLIC_TEMPLATE_PATH = DOCS_PATH + '/server2/templates/public' +PRIVATE_TEMPLATE_PATH = DOCS_PATH + '/server2/templates/private' + +# The branch that the server will default to when no branch is specified in the +# URL. This is necessary because it is not possible to pass flags to the script +# handler. +DEFAULT_BRANCH = 'local' # Global cache of instances because the Server is recreated for every request. SERVER_INSTANCES = {} @@ -48,6 +53,7 @@ class Server(webapp.RequestHandler): cache_timeout_seconds = 300 cache_builder = FetcherCache.Builder(fetcher, cache_timeout_seconds) template_data_source = TemplateDataSource( + branch, cache_builder, [PUBLIC_TEMPLATE_PATH, PRIVATE_TEMPLATE_PATH]) api_data_source = APIDataSource(cache_builder, [API_PATH]) @@ -58,16 +64,22 @@ class Server(webapp.RequestHandler): return SERVER_INSTANCES[branch] def _HandleRequest(self, path): - channel_name = branch_utility.GetChannelNameFromPath(path) + channel_name, real_path = ( + branch_utility.SplitChannelNameFromPath(path, default=DEFAULT_BRANCH)) branch = branch_utility.GetBranchNumberForChannelName(channel_name, urlfetch) - self._GetInstanceForBranch(branch).Run(path, self) + if real_path == '': + real_path = 'index.html' + self._GetInstanceForBranch(branch).Get(real_path, self) def get(self): path = self.request.path + # Redirect paths like "directory" to "directory/". This is so relative file + # paths will know to treat this as a directory. + if os.path.splitext(path)[1] == '' and path[-1] != '/': + self.redirect(path + '/') path = path.replace('/chrome/extensions/', '') - if len(path) > 0 and path[0] == '/': - path = path.strip('/') + path = path.strip('/') self._HandleRequest(path) def main(): diff --git a/chrome/common/extensions/docs/server2/local_fetcher.py b/chrome/common/extensions/docs/server2/local_fetcher.py index d36dfa7..eecb746 100644 --- a/chrome/common/extensions/docs/server2/local_fetcher.py +++ b/chrome/common/extensions/docs/server2/local_fetcher.py @@ -3,6 +3,7 @@ # found in the LICENSE file. import logging +import mimetypes import os class LocalFetcher(object): @@ -10,6 +11,7 @@ class LocalFetcher(object): """ def __init__(self, base_path): self._base_path = self._ConvertToFilepath(base_path) + mimetypes.init() def _ConvertToFilepath(self, path): return path.replace('/', os.sep) @@ -26,4 +28,7 @@ class LocalFetcher(object): return f.read() def FetchResource(self, path): - return self._Resource(self._ReadFile(self._ConvertToFilepath(path))) + result = self._Resource(self._ReadFile(self._ConvertToFilepath(path))) + base, ext = os.path.splitext(path) + result.headers['content-type'] = mimetypes.types_map[ext] + return result diff --git a/chrome/common/extensions/docs/server2/server_instance.py b/chrome/common/extensions/docs/server2/server_instance.py index e09fd01..139d0e0 100644 --- a/chrome/common/extensions/docs/server2/server_instance.py +++ b/chrome/common/extensions/docs/server2/server_instance.py @@ -3,9 +3,9 @@ # found in the LICENSE file. import logging +import os -DOCS_PATH = 'docs/' -STATIC_PATH = DOCS_PATH + 'static/' +STATIC_DIR_PREFIX = 'docs/server2/' class ServerInstance(object): """This class is used to hold a data source and fetcher for an instance of a @@ -16,22 +16,31 @@ class ServerInstance(object): self._template_data_source = template_data_source self._fetcher = fetcher + def _NotFound(self, request_handler): + # TODO: Actual 404 page. + request_handler.response.set_status(404); + request_handler.response.out.write('File not found.') - def Run(self, path, request_handler): - parts = path.split('/') + def _FetchStaticResource(self, path, request_handler): + """Fetch a resource in the 'static' directory. + """ + try: + result = self._fetcher.FetchResource(STATIC_DIR_PREFIX + path) + for key in result.headers: + request_handler.response.headers[key] = result.headers[key] + request_handler.response.out.write(result.content) + except: + self._NotFound(request_handler) + + def Get(self, path, request_handler): + parts = path.rsplit('/', 1) filename = parts[-1] + if parts[0].startswith('static'): + self._FetchStaticResource(path, request_handler) + return content = self._template_data_source.Render(filename, self._api_data_source[filename]) if not content: - logging.info('Template not found for: ' + filename) - try: - result = self._fetcher.FetchResource(STATIC_PATH + filename) - for key in result.headers: - request_handler.response.headers[key] = result.headers[key] - content = result.content - except: - request_handler.response.set_status(404) - # TODO should be an actual not found page. - content = 'File not found.' - logging.info + self._NotFound(request_handler) + return request_handler.response.out.write(content) diff --git a/chrome/common/extensions/docs/server2/static/css/index.css b/chrome/common/extensions/docs/server2/static/css/index.css new file mode 100644 index 0000000..344f02e --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/css/index.css @@ -0,0 +1,34 @@ +#index table { + margin: 0 0 0 1px; + border-color: #36C; + border-spacing: 0; + clear: right; + border-collapse: collapse; + line-height: 125%; +} + +#index table.columns td { + padding: 0 1em 0 0; +} + +#index table.columns td p { + margin: 1em 0 0 0; + padding: 0; +} + +#index td { + padding: 6px 12px; + border 1px solid #36C; + background-color: white; + text-align: left; + vertical-align: top; +} + +#index td ul, #index td ol { + margin: 0 0 1em 15px; + padding: 0; +} + +#howDoIStart { + width: 330px; +} diff --git a/chrome/common/extensions/docs/server2/static/css/print.css b/chrome/common/extensions/docs/server2/static/css/print.css new file mode 100644 index 0000000..b2820b1 --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/css/print.css @@ -0,0 +1,11 @@ +/* Chrome extensions developer guide - styles for printing */ + +/* Make preformatted text wrap + (ref: http://myy.helia.fi/~karte/pre-wrap-css3-mozilla-opera-ie.html) */ +pre { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ +} diff --git a/chrome/common/extensions/docs/server2/static/css/site.css b/chrome/common/extensions/docs/server2/static/css/site.css new file mode 100644 index 0000000..a649728 --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/css/site.css @@ -0,0 +1,166 @@ +body { + font-family: "open sans", Helvetica, Arial, sans-serif; + font-size: small; + color: #333; + background-color: white; + margin: 0; + padding: 0; +} + +p { + margin: 1em 0 0 0; + line-height: 125%; +} + +a, a:link { + text-decoration: none; + color: #333; +} + +a:visited { + color: #61C; +} + +#header { + margin: 1em 0 1em 14px; + width: 100%; + height: 64px; +} + +#header td { + border: none; + padding: 0; +} + +#logo { + float: left; + padding-top: 10px; +} + +#cse { + float: left; + width: 50%; +} + +li { + margin: .3em 0 0 1.5em; + padding: 0; +} + +ol li { + margin-top: 1em; +} + +img { + border: none; + padding: 0; +} + +.hidden, .hidden *, #skipto, #skipto * { + position: relative; + top: -9999px; + left: -9999px; + height: 0; + width: 0; + overflow: hidden; + z-index: 4444; +} + +.displayModeWarning { + background-color: #FF7735; + color: white; + font-weight: bold; + padding: 6px 8px; + width: 100%; +} + +span.displayModeWarning { + margin-right: 2ex; +} + +.greytext { + position: absolute; + top: 95px; + left: 150px; + color: #AAA; + font-size: 11px; + height: 14px; +} + +#gc-container { + margin: 3px 8px; + padding: 0; + max-width: 1160px; + position: relative; + min-height: 100%; + height: auto !important; + _height: 100%; +} + +#gc-topnav { + font-size: 1em; + margin: 0; + padding: .4em 0; + width: 100%; + white-space: nowrap; + word-wrap: normal; + background-color: #F1F1F1; + border-top: 1px solid #E5E5E5; +} + +#gc-topnav h1 { + font-size: 1.5em; + line-height: 1.3em; + font-weight: bold; + background-color: transparent; + border: 0; + margin: 0; + padding: 0 0 0 14px; + float: left; +} + +#gc-topnav li { + float: none; + display: inline; + margin: 0; + padding: 0; +} + +#gc-topnav ul { + line-height: 1em; + text-align: right; + list-style: none; + margin: 0; + padding: .47em 0; +} + +#gc-topnav a { + padding: 0 .8em; +} + +.pageData { + display: none; +} + +#gc-pagecontent { + padding-left: 24px; +} + +#gc-pagecontent h3 { + font-size: 130%; + font-weight: bold; + margin: 1.5em 0 0 0; + top: 0em; +} + +#gc-footer { + clear: both; + margin: 0; + color: #666; +} + +#gc-footer .text { + text-align: center; + padding: 30px 0; + margin: 0 0 0 0; +} diff --git a/chrome/common/extensions/docs/server2/static/images/chrome_logo.gif b/chrome/common/extensions/docs/server2/static/images/chrome_logo.gif Binary files differnew file mode 100755 index 0000000..c6bcc7b --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/images/chrome_logo.gif diff --git a/chrome/common/extensions/docs/server2/static/images/index/gmail-small.png b/chrome/common/extensions/docs/server2/static/images/index/gmail-small.png Binary files differnew file mode 100644 index 0000000..0e70bc0 --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/images/index/gmail-small.png diff --git a/chrome/common/extensions/docs/server2/static/images/index/html5app.png b/chrome/common/extensions/docs/server2/static/images/index/html5app.png Binary files differnew file mode 100644 index 0000000..62582b6 --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/images/index/html5app.png diff --git a/chrome/common/extensions/docs/server2/static/js/sidebar.js b/chrome/common/extensions/docs/server2/static/js/sidebar.js new file mode 100644 index 0000000..51d9292 --- /dev/null +++ b/chrome/common/extensions/docs/server2/static/js/sidebar.js @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. + */ + +var TEXT_NODE = 3; // Text nodes have nodeType of 3. + +/** + * Toggles the display of nodes given the status of their associated controls. + * + * For each node passed to this function, check to see if a toggle has been + * inserted into the node's parent. If yes, change the state of the toggle and + * hide/reveal the node as needed. + * + * @param {NodeList|Node|Array.<Node>} Nodes to operate on. + */ +function toggleList(list) { + if (typeof list.length != 'number') { + list = Array(list); + } + + for (var i = 0; i < list.length; i++) { + var toggle = list[i].parentNode && + list[i].parentNode.firstChild; + if (toggle && toggle.className.substring(0, 6) == 'toggle') { + var visible = toggle.className == 'toggle'; + list[i].style.display = visible ? 'block' : 'none'; + toggle.className = visible ? 'toggle selected' : 'toggle'; + } + } +}; + +/** + * Reveals the hidden ancestor of the passed node, adjusts toggles as needed. + * + * @param {Node} node The node whose ancestor is a hidden toggleable element. + */ +function revealAncestor(node) { + while (node.parentNode) { + if (node.style.display == 'none') { + toggleList(node); + break; + } + node = node.parentNode; + } +}; + +/** + * Adds toggle controls to the sidebar list. + * + * Controls are inserted as the first children of list items in the sidebar + * which contain only text (not a link). Handlers are set up so that when a + * toggle control is clicked, any <ul> elements who are siblings of the control + * are hidden/revealed as appropriate given the control's state. + * + * If a list item possesses the class "leftNavSelected" its ancestor <ul> is + * revealed by default (it represents the current page). + */ +function initToggles() { + var toc = document.getElementById('gc-toc'); + var items = toc.getElementsByTagName('li'); + var selectedNode = null; + for (var i = 0; i < items.length; i++) { + var item = items[i]; + if (item.className == 'leftNavSelected') { + selectedNode = item; + } else if (item.firstChild && + item.firstChild.nodeType == TEXT_NODE) { + // Only assign toggles to text nodes in the sidebar. + var a = document.createElement('a'); + a.className = 'toggle selected'; + a.appendChild(document.createTextNode(' ')); + a.onclick = function() { + toggleList(this.parentNode.getElementsByTagName('ul')); + }; + item.insertBefore(a, item.firstChild); + toggleList(item.getElementsByTagName('ul')); + } + } + if (selectedNode) { + revealAncestor(selectedNode); + } +}; diff --git a/chrome/common/extensions/docs/server2/template_data_source.py b/chrome/common/extensions/docs/server2/template_data_source.py index 4e1a081..a3bd41d 100644 --- a/chrome/common/extensions/docs/server2/template_data_source.py +++ b/chrome/common/extensions/docs/server2/template_data_source.py @@ -4,13 +4,28 @@ from third_party.handlebar import Handlebar +EXTENSIONS_URL = '/chrome/extensions' + class TemplateDataSource(object): """This class fetches and compiles templates using the fetcher passed in with |cache_builder|. """ - def __init__(self, cache_builder, base_paths): + def __init__(self, branch, cache_builder, base_paths): self._cache = cache_builder.build(self._LoadTemplate) self._base_paths = base_paths + self._branch_info = self._MakeBranchDict(branch) + + def _MakeBranchDict(self, branch): + return { + 'showWarning': branch != 'stable', + 'branches': [ + { 'name': 'Stable', 'path': EXTENSIONS_URL + '/stable' }, + { 'name': 'Dev', 'path': EXTENSIONS_URL + '/dev' }, + { 'name': 'Beta', 'path': EXTENSIONS_URL + '/beta' }, + { 'name': 'Trunk', 'path': EXTENSIONS_URL + '/trunk' } + ], + 'current': branch + } def _LoadTemplate(self, template): return Handlebar(template) @@ -24,7 +39,11 @@ class TemplateDataSource(object): if not template: return '' # TODO error handling - return template.render(context, {'partials': self}).text + return template.render({ + 'api': context, + 'branchInfo': self._branch_info, + 'partials': self + }).text def __getitem__(self, key): return self.get(key) diff --git a/chrome/common/extensions/docs/server2/template_data_source_test.py b/chrome/common/extensions/docs/server2/template_data_source_test.py index c0239a1..d0b45c1 100755 --- a/chrome/common/extensions/docs/server2/template_data_source_test.py +++ b/chrome/common/extensions/docs/server2/template_data_source_test.py @@ -32,7 +32,7 @@ class TemplateDataSourceTest(unittest.TestCase): self._base_path = os.path.join(self._base_path, 'simple') fetcher = LocalFetcher(self._base_path) cache_builder = FetcherCache.Builder(fetcher, 0) - t_data_source = TemplateDataSource(cache_builder, ['./']) + t_data_source = TemplateDataSource('fake_branch', cache_builder, ['./']) template_a1 = Handlebar(self._ReadLocalFile('test1.html')) self.assertEqual(template_a1.render({}, {'templates': {}}).text, @@ -48,7 +48,7 @@ class TemplateDataSourceTest(unittest.TestCase): self._base_path = os.path.join(self._base_path, 'partials') fetcher = LocalFetcher(self._base_path) cache_builder = FetcherCache.Builder(fetcher, 0) - t_data_source = TemplateDataSource(cache_builder, ['./']) + t_data_source = TemplateDataSource('fake_branch', cache_builder, ['./']) self.assertEqual(self._ReadLocalFile('test.html'), t_data_source['test_tmpl'].render( @@ -58,7 +58,7 @@ class TemplateDataSourceTest(unittest.TestCase): self._base_path = os.path.join(self._base_path, 'render') fetcher = LocalFetcher(self._base_path) cache_builder = FetcherCache.Builder(fetcher, 0) - t_data_source = TemplateDataSource(cache_builder, ['./']) + t_data_source = TemplateDataSource('fake_branch', cache_builder, ['./']) self._RenderTest('test1', t_data_source) self._RenderTest('test2', t_data_source) diff --git a/chrome/common/extensions/docs/server2/templates/private/footer.html b/chrome/common/extensions/docs/server2/templates/private/footer.html new file mode 100644 index 0000000..34e45a1 --- /dev/null +++ b/chrome/common/extensions/docs/server2/templates/private/footer.html @@ -0,0 +1,44 @@ +<div id="gc-footer"> + <div class="text"> + <p> + Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>, + the content of this page is licensed under the <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons + Attribution 3.0 License</a>, and code samples are licensed under the + <a rel="license" href="http://code.google.com/google_bsd_license.html">BSD License</a>. + </p> + <p> + ©2012 Google + </p> + <script src="https://www.google-analytics.com/urchin.js" type="text/javascript"></script> + <script src="https://www.google-analytics.com/ga.js" type="text/javascript"></script> + <script type="text/javascript"> + // chrome doc tracking + try { + var engdocs = _gat._getTracker("YT-10763712-2"); + engdocs._trackPageview(); + } catch(err) {} + // code.google.com site-wide tracking + try { + _uacct="UA-18071-1"; + _uanchor=1; + _uff=0; + urchinTracker(); + } + catch(e) {/* urchinTracker not available. */} + </script> + <script src="http://www.google.com/jsapi" type="text/javascript"></script> + <script type="text/javascript"> + google.load('search', '1', + {language : 'en', style : google.loader.themes.V2_DEFAULT}); + google.setOnLoadCallback(function() { + var customSearchOptions = {}; + var customSearchControl = new google.search.CustomSearchControl( + '007539736102453916271:q8_wzmg0804', customSearchOptions); + customSearchControl.setResultSetSize( + google.search.Search.FILTERED_CSE_RESULTSET); + customSearchControl.draw('cse'); + }, true); + </script> + <script type="text/javascript">google.load("elements", "1", {packages: "transliteration"});</script> + </div> +</div> diff --git a/chrome/common/extensions/docs/server2/templates/private/header_body.html b/chrome/common/extensions/docs/server2/templates/private/header_body.html new file mode 100644 index 0000000..9d7e5c1 --- /dev/null +++ b/chrome/common/extensions/docs/server2/templates/private/header_body.html @@ -0,0 +1,47 @@ +{{?branchInfo.showWarning}} +<div id="branchWarning" class="displayModeWarning"> + <span>WARNING: this is the {{branchInfo.current}} documentation. It may not work with the stable release of Chrome.</span> + <select id="branchChooser"> + <option>Choose a different version...</option> + {{#branchInfo.branches}} + <option value="{{path}}">{{name}}</option> + {{/}} + </select> +</div> +{{/}} +<a id="top"></a> +<div id="skipto"> + <a href="#gc-pagecontent">Skip to page content</a> + <a href="#gc-topnav">Skip to main navigation</a> +</div> +<div id="header"> + <div id="logo"> + <a href="http://code.google.com/"><img src="static/images/chrome_logo.gif" alt="Google Code Labs" style="border:0; margin:0;"></a> + </div> + <div id="cse"></div> + <span class="greytext">e.g. "page action" or "tabs"</span> +</div> +<a id="gc-topnav-anchor"></a> +<div id="gc-topnav"> + <h1>Google Chrome Extensions</h1> + <ul id="home" class="gc-topnav-tabs"> + <li id="home_link"> + <a href="index.html" title="Google Chrome Extensions home page">Home</a> + </li> + <li id="docs_link"> + <a href="docs.html" title="Official Google Chrome Extensions documentation">Docs</a> + </li> + <li id="faq_link"> + <a href="faq.html" title="Answers to frequently asked questions about Google Chrome Extensions">FAQ</a> + </li> + <li id="samples_link"> + <a href="samples.html" title="Sample extensions (with source code)">Samples</a> + </li> + <li id="group_link"> + <a href="http://groups.google.com/a/chromium.org/group/chromium-extensions" title="Google Chrome Extensions developer forum">Group</a> + </li> + <li id="so_link"> + <a href="http://stackoverflow.com/questions/tagged/google-chrome-extension" title="[google-chrome-extension] tag on Stack Overflow">Questions?</a> + </li> + </ul> +</div> diff --git a/chrome/common/extensions/docs/server2/templates/private/header_head.html b/chrome/common/extensions/docs/server2/templates/private/header_head.html new file mode 100644 index 0000000..4eb644a --- /dev/null +++ b/chrome/common/extensions/docs/server2/templates/private/header_head.html @@ -0,0 +1,3 @@ +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link href="static/css/site.css" rel="stylesheet" type="text/css"> +<link href="static/css/print.css" rel="stylesheet" type="text/css" media="print"> diff --git a/chrome/common/extensions/docs/template2/public/browserAction.html b/chrome/common/extensions/docs/server2/templates/public/browserAction.html index 9e53ba0..9e53ba0 100644 --- a/chrome/common/extensions/docs/template2/public/browserAction.html +++ b/chrome/common/extensions/docs/server2/templates/public/browserAction.html diff --git a/chrome/common/extensions/docs/server2/templates/public/index.html b/chrome/common/extensions/docs/server2/templates/public/index.html new file mode 100644 index 0000000..551364d --- /dev/null +++ b/chrome/common/extensions/docs/server2/templates/public/index.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<html> + <head> + {{+partials.header_head}} + <link href="static/css/index.css" rel="stylesheet" type="text/css"> + </head> + <body> + {{+partials.header_body}} + <div id="gc-container" class="labs"> + <div id="gc-pagecontent"> + <table id="index"> + <tr> + <td> + <h3>What are extensions?</h3> + <p> + Extensions are small software programs that + can modify and enhance the functionality of the Chrome browser. + You write them using web technologies such as + HTML, JavaScript, and CSS. + You can also use the extension system to build + <a href="apps.html">packaged apps</a>, + a downloadable kind of + <a href="http://code.google.com/chrome/apps/index.html">installable web app</a>. + </p> + <p> + <img src="static/images/index/gmail-small.png" width="91" height="35" align="right" style="margin-top:0px; margin-left:0.5em" alt="A screenshot of an extension's icon in the browser bar"> + From a user's point of view, + extensions and packaged apps are very different + because they present very different user interfaces. + Extensions have little to no user interface. + For example, the image to the right shows the icon + that provides the UI for the + <a href="samples.html#gmail">Gmail extension</a>. + </p> + <p> + <img src="static/images/index/html5app.png" width="200" height="160" align="right" style="margin-top:0px; margin-left:0.5em" alt="A screenshot of a packaged app that implements a jigsaw puzzle"> + Packaged apps, on the other hand, + look and feel like regular web apps, + with a big-screen design + and rich UI. + The image to the right shows a jigsaw puzzle game + implemented by a packaged app. + </p> + <p> + Both extensions and packaged apps bundle all their files + into a single file that the user downloads and installs. + This bundling means that, unlike ordinary web apps, + extensions and packaged apps don't need to depend + on content from the web. + </p> + <p> + You can distribute your extension or packaged app + by using the + <a href="https://chrome.google.com/webstore/developer/dashboard">Chrome Developer Dashboard</a> + to publish to the + <a href="http://chrome.google.com/webstore">Chrome Web Store</a>. + For more information, see the + <a href="http://code.google.com/chrome/webstore">store developer documentation</a>. + </p> + </td> + <td id="howDoIStart"> + <h3>How do I start?</h3> + <p></p> + <ol> + <li> + Follow the <a href="getstarted.html">Getting Started tutorial</a> + <!-- PENDING: once we have one for packaged apps, change to + "for _extensions_ or _packaged_apps_" --> + </li> + <li> + Read the + <a href="overview.html">Overview</a> + </li> + <li> + Keep up-to-date by reading the + <a href="http://blog.chromium.org/">Chromium blog</a> + </li> + <li> + Subscribe to the + <a href="http://groups.google.com/a/chromium.org/group/chromium-extensions">chromium-extensions group</a> + </li> + </ol> + <p></p> + <h3>Featured videos</h3> + <p> + <a href="http://www.youtube.com/view_play_list?p=CA101D6A85FE9D4B">Technical videos</a> <br> + <a href="http://www.youtube.com/view_play_list?p=38DF05697DE372B1">Developer snapshots</a> (below) + </p> + <p> + <iframe title="YouTube video player" width="300" height="199" src="http://www.youtube.com/embed/wRDPTnY3yO8?rel=0" frameborder="0" allowfullscreen=""></iframe> + </p> + </td> + </tr> + </table> + </div> + </div> + </body> + {{+partials.footer}} +</html> diff --git a/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test1_tmpl.html b/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test1_tmpl.html index c390ca4..c37d1bd 100644 --- a/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test1_tmpl.html +++ b/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test1_tmpl.html @@ -1 +1 @@ -{{arg1}} {{arg2}} {{arg3}} {{arg4}}. +{{api.arg1}} {{api.arg2}} {{api.arg3}} {{api.arg4}}. diff --git a/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test2_tmpl.html b/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test2_tmpl.html index 9c43978..cb0a407 100644 --- a/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test2_tmpl.html +++ b/chrome/common/extensions/docs/server2/test_data/template_data_source/render/test2_tmpl.html @@ -1 +1 @@ -{{arg1}} {{arg2.arg}}nd {{arg3}} is an {{#arg4}}{{@}}, {{/arg4}}test. +{{api.arg1}} {{api.arg2.arg}}nd {{api.arg3}} is an {{#api.arg4}}{{@}}, {{/}}test. |