Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / remoting / webapp / build-html.py
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Builds the complete main.html file from the basic components.
7 """
8
9 from HTMLParser import HTMLParser
10 import argparse
11 import os
12 import re
13 import sys
14
15
16 def error(msg):
17   print 'Error: %s' % msg
18   sys.exit(1)
19
20
21 class HtmlChecker(HTMLParser):
22   def __init__(self):
23     HTMLParser.__init__(self)
24     self.ids = set()
25
26   def handle_starttag(self, tag, attrs):
27     for (name, value) in attrs:
28       if name == 'id':
29         if value in self.ids:
30           error('Duplicate id: %s' % value)
31         self.ids.add(value)
32
33
34 class GenerateWebappHtml:
35   def __init__(self, template_files, js_files, instrumented_js_files,
36                template_rel_dir):
37
38     self.js_files = js_files
39     self.instrumented_js_files = instrumented_js_files
40     self.template_rel_dir = template_rel_dir
41
42     self.templates_expected = set()
43     for template in template_files:
44       self.templates_expected.add(os.path.basename(template))
45
46     self.templates_found = set()
47
48   def includeJavascript(self, output):
49     for js_path in sorted(self.js_files):
50       js_file = os.path.basename(js_path)
51       output.write('    <script src="' + js_file + '"></script>\n')
52
53     for js_path in sorted(self.instrumented_js_files):
54       js_file = os.path.basename(js_path)
55       output.write('    <script src="' + js_file + '" data-cover></script>\n')
56
57   def verifyTemplateList(self):
58     """Verify that all the expected templates were found."""
59     if self.templates_expected > self.templates_found:
60       extra = self.templates_expected - self.templates_found
61       print 'Extra templates specified:', extra
62       return False
63     return True
64
65   def validateTemplate(self, template_path):
66     template = os.path.basename(template_path)
67     if template in self.templates_expected:
68       self.templates_found.add(template)
69       return True
70     return False
71
72   def processTemplate(self, output, template_file, indent):
73     with open(os.path.join(self.template_rel_dir, template_file), 'r') as \
74         input_template:
75       first_line = True
76       skip_header_comment = False
77
78       for line in input_template:
79         # If the first line is the start of a copyright notice, then
80         # skip over the entire comment.
81         # This will remove the copyright info from the included files,
82         # but leave the one on the main template.
83         if first_line and re.match(r'<!--', line):
84           skip_header_comment = True
85         first_line = False
86         if skip_header_comment:
87           if re.search(r'-->', line):
88             skip_header_comment = False
89           continue
90
91         m = re.match(
92             r'^(\s*)<meta-include src="(.+)"\s*/>\s*$',
93             line)
94         if m:
95           prefix = m.group(1)
96           template_name = m.group(2)
97           if not self.validateTemplate(template_name):
98             error('Found template not in list of expected templates: %s' %
99                   template_name)
100           self.processTemplate(output, template_name, indent + len(prefix))
101           continue
102
103         m = re.match(r'^\s*<meta-include type="javascript"\s*/>\s*$', line)
104         if m:
105           self.includeJavascript(output)
106           continue
107
108         if line.strip() == '':
109           output.write('\n')
110         else:
111           output.write((' ' * indent) + line)
112
113
114 def parseArgs():
115   parser = argparse.ArgumentParser()
116   parser.add_argument(
117     '--js', nargs='+', help='The Javascript files to include in HTML <head>')
118   parser.add_argument(
119     '--templates',
120     nargs='*',
121     default=[],
122     help='The html template files used by input-template')
123   parser.add_argument(
124     '--exclude-js',
125     nargs='*',
126     default=[],
127     help='The Javascript files to exclude from <--js> and <--instrumentedjs>')
128   parser.add_argument(
129     '--instrument-js',
130     nargs='*',
131     default=[],
132     help='Javascript to include and instrument for code coverage')
133   parser.add_argument(
134     '--dir-for-templates',
135     default = ".",
136     help='Directory template references in html are relative to')
137   parser.add_argument('output_file')
138   parser.add_argument('input_template')
139   return parser.parse_args(sys.argv[1:])
140
141
142 def main():
143   args = parseArgs()
144
145   out_file = args.output_file
146   js_files = set(args.js) - set(args.exclude_js)
147
148   # Create the output directory if it does not exist.
149   out_directory = os.path.dirname(out_file)
150   if not os.path.exists(out_directory):
151     os.makedirs(out_directory)
152
153   # Generate the main HTML file from the templates.
154   with open(out_file, 'w') as output:
155     gen = GenerateWebappHtml(args.templates, js_files, args.instrument_js,
156                              args.dir_for_templates)
157     gen.processTemplate(output, args.input_template, 0)
158
159     # Verify that all the expected templates were found.
160     if not gen.verifyTemplateList():
161       error('Extra templates specified')
162
163   # Verify that the generated HTML file is valid.
164   with open(out_file, 'r') as input_html:
165     parser = HtmlChecker()
166     parser.feed(input_html.read())
167
168
169 if __name__ == '__main__':
170   sys.exit(main())