summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/common/extensions/docs/server2/branch_utility.py14
-rwxr-xr-xchrome/common/extensions/docs/server2/branch_utility_test.py27
-rwxr-xr-xchrome/common/extensions/docs/server2/echo_handler.py24
-rw-r--r--chrome/common/extensions/docs/server2/local_fetcher.py7
-rw-r--r--chrome/common/extensions/docs/server2/server_instance.py39
-rw-r--r--chrome/common/extensions/docs/server2/static/css/index.css34
-rw-r--r--chrome/common/extensions/docs/server2/static/css/print.css11
-rw-r--r--chrome/common/extensions/docs/server2/static/css/site.css166
-rwxr-xr-xchrome/common/extensions/docs/server2/static/images/chrome_logo.gifbin0 -> 2262 bytes
-rw-r--r--chrome/common/extensions/docs/server2/static/images/index/gmail-small.pngbin0 -> 2383 bytes
-rw-r--r--chrome/common/extensions/docs/server2/static/images/index/html5app.pngbin0 -> 40439 bytes
-rw-r--r--chrome/common/extensions/docs/server2/static/js/sidebar.js84
-rw-r--r--chrome/common/extensions/docs/server2/template_data_source.py23
-rwxr-xr-xchrome/common/extensions/docs/server2/template_data_source_test.py6
-rw-r--r--chrome/common/extensions/docs/server2/templates/private/footer.html44
-rw-r--r--chrome/common/extensions/docs/server2/templates/private/header_body.html47
-rw-r--r--chrome/common/extensions/docs/server2/templates/private/header_head.html3
-rw-r--r--chrome/common/extensions/docs/server2/templates/public/browserAction.html (renamed from chrome/common/extensions/docs/template2/public/browserAction.html)0
-rw-r--r--chrome/common/extensions/docs/server2/templates/public/index.html99
-rw-r--r--chrome/common/extensions/docs/server2/test_data/template_data_source/render/test1_tmpl.html2
-rw-r--r--chrome/common/extensions/docs/server2/test_data/template_data_source/render/test2_tmpl.html2
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
new file mode 100755
index 0000000..c6bcc7b
--- /dev/null
+++ b/chrome/common/extensions/docs/server2/static/images/chrome_logo.gif
Binary files differ
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
new file mode 100644
index 0000000..0e70bc0
--- /dev/null
+++ b/chrome/common/extensions/docs/server2/static/images/index/gmail-small.png
Binary files differ
diff --git a/chrome/common/extensions/docs/server2/static/images/index/html5app.png b/chrome/common/extensions/docs/server2/static/images/index/html5app.png
new file mode 100644
index 0000000..62582b6
--- /dev/null
+++ b/chrome/common/extensions/docs/server2/static/images/index/html5app.png
Binary files differ
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.