Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: grit/format/policy_templates/writers/doc_writer.py

Issue 1442863002: Remove contents of grit's SVN repository. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk/
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 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
7 import json
8 from xml.dom import minidom
9 from grit import lazy_re
10 from grit.format.policy_templates.writers import xml_formatted_writer
11
12
13 def GetWriter(config):
14 '''Factory method for creating DocWriter objects.
15 See the constructor of TemplateWriter for description of
16 arguments.
17 '''
18 return DocWriter(['*'], config)
19
20
21 class DocWriter(xml_formatted_writer.XMLFormattedWriter):
22 '''Class for generating policy templates in HTML format.
23 The intended use of the generated file is to upload it on
24 http://dev.chromium.org, therefore its format has some limitations:
25 - No HTML and body tags.
26 - Restricted set of element attributes: for example no 'class'.
27 Because of the latter the output is styled using the 'style'
28 attributes of HTML elements. This is supported by the dictionary
29 self._STYLES[] and the method self._AddStyledElement(), they try
30 to mimic the functionality of CSS classes. (But without inheritance.)
31
32 This class is invoked by PolicyTemplateGenerator to create the HTML
33 files.
34 '''
35
36 def _GetLocalizedMessage(self, msg_id):
37 '''Returns a localized message for this writer.
38
39 Args:
40 msg_id: The identifier of the message.
41
42 Returns:
43 The localized message.
44 '''
45 return self.messages['doc_' + msg_id]['text']
46
47 def _MapListToString(self, item_map, items):
48 '''Creates a comma-separated list.
49
50 Args:
51 item_map: A dictionary containing all the elements of 'items' as
52 keys.
53 items: A list of arbitrary items.
54
55 Returns:
56 Looks up each item of 'items' in 'item_maps' and concatenates the
57 resulting items into a comma-separated list.
58 '''
59 return ', '.join([item_map[x] for x in items])
60
61 def _AddTextWithLinks(self, parent, text):
62 '''Parse a string for URLs and add it to a DOM node with the URLs replaced
63 with <a> HTML links.
64
65 Args:
66 parent: The DOM node to which the text will be added.
67 text: The string to be added.
68 '''
69 # A simple regexp to search for URLs. It is enough for now.
70 url_matcher = lazy_re.compile('(http://[^\\s]*[^\\s\\.])')
71
72 # Iterate through all the URLs and replace them with links.
73 while True:
74 # Look for the first URL.
75 res = url_matcher.search(text)
76 if not res:
77 break
78 # Calculate positions of the substring of the URL.
79 url = res.group(0)
80 start = res.start(0)
81 end = res.end(0)
82 # Add the text prior to the URL.
83 self.AddText(parent, text[:start])
84 # Add a link for the URL.
85 self.AddElement(parent, 'a', {'href': url}, url)
86 # Drop the part of text that is added.
87 text = text[end:]
88 self.AddText(parent, text)
89
90 def _AddParagraphs(self, parent, text):
91 '''Break description into paragraphs and replace URLs with links.
92
93 Args:
94 parent: The DOM node to which the text will be added.
95 text: The string to be added.
96 '''
97 # Split text into list of paragraphs.
98 entries = text.split('\n\n')
99 for entry in entries:
100 # Create a new paragraph node.
101 paragraph = self.AddElement(parent, 'p')
102 # Insert text to the paragraph with processing the URLs.
103 self._AddTextWithLinks(paragraph, entry)
104
105 def _AddStyledElement(self, parent, name, style_ids, attrs=None, text=None):
106 '''Adds an XML element to a parent, with CSS style-sheets included.
107
108 Args:
109 parent: The parent DOM node.
110 name: Name of the element to add.
111 style_ids: A list of CSS style strings from self._STYLE[].
112 attrs: Dictionary of attributes for the element.
113 text: Text content for the element.
114 '''
115 if attrs == None:
116 attrs = {}
117
118 style = ''.join([self._STYLE[x] for x in style_ids])
119 if style != '':
120 # Apply the style specified by style_ids.
121 attrs['style'] = style + attrs.get('style', '')
122 return self.AddElement(parent, name, attrs, text)
123
124 def _AddDescription(self, parent, policy):
125 '''Adds a string containing the description of the policy. URLs are
126 replaced with links and the possible choices are enumerated in case
127 of 'string-enum' and 'int-enum' type policies.
128
129 Args:
130 parent: The DOM node for which the feature list will be added.
131 policy: The data structure of a policy.
132 '''
133 # Add description by paragraphs (URLs will be substituted by links).
134 self._AddParagraphs(parent, policy['desc'])
135 # Add list of enum items.
136 if policy['type'] in ('string-enum', 'int-enum', 'string-enum-list'):
137 ul = self.AddElement(parent, 'ul')
138 for item in policy['items']:
139 if policy['type'] == 'int-enum':
140 value_string = str(item['value'])
141 else:
142 value_string = '"%s"' % item['value']
143 self.AddElement(
144 ul, 'li', {}, '%s = %s' % (value_string, item['caption']))
145
146 def _AddFeatures(self, parent, policy):
147 '''Adds a string containing the list of supported features of a policy
148 to a DOM node. The text will look like as:
149 Feature_X: Yes, Feature_Y: No
150
151 Args:
152 parent: The DOM node for which the feature list will be added.
153 policy: The data structure of a policy.
154 '''
155 features = []
156 # The sorting is to make the order well-defined for testing.
157 keys = policy['features'].keys()
158 keys.sort()
159 for key in keys:
160 key_name = self._FEATURE_MAP[key]
161 if policy['features'][key]:
162 value_name = self._GetLocalizedMessage('supported')
163 else:
164 value_name = self._GetLocalizedMessage('not_supported')
165 features.append('%s: %s' % (key_name, value_name))
166 self.AddText(parent, ', '.join(features))
167
168 def _AddListExampleMac(self, parent, policy):
169 '''Adds an example value for Mac of a 'list' policy to a DOM node.
170
171 Args:
172 parent: The DOM node for which the example will be added.
173 policy: A policy of type 'list', for which the Mac example value
174 is generated.
175 '''
176 example_value = policy['example_value']
177 self.AddElement(parent, 'dt', {}, 'Mac:')
178 mac = self._AddStyledElement(parent, 'dd', ['.monospace', '.pre'])
179
180 mac_text = ['<array>']
181 for item in example_value:
182 mac_text.append(' <string>%s</string>' % item)
183 mac_text.append('</array>')
184 self.AddText(mac, '\n'.join(mac_text))
185
186 def _AddListExampleWindows(self, parent, policy):
187 '''Adds an example value for Windows of a 'list' policy to a DOM node.
188
189 Args:
190 parent: The DOM node for which the example will be added.
191 policy: A policy of type 'list', for which the Windows example value
192 is generated.
193 '''
194 example_value = policy['example_value']
195 self.AddElement(parent, 'dt', {}, 'Windows:')
196 win = self._AddStyledElement(parent, 'dd', ['.monospace', '.pre'])
197 win_text = []
198 cnt = 1
199 if self.CanBeRecommended(policy) and not self.CanBeMandatory(policy):
200 key_name = self.config['win_reg_recommended_key_name']
201 else:
202 key_name = self.config['win_reg_mandatory_key_name']
203 for item in example_value:
204 win_text.append(
205 '%s\\%s\\%d = "%s"' %
206 (key_name, policy['name'], cnt, item))
207 cnt = cnt + 1
208 self.AddText(win, '\n'.join(win_text))
209
210 def _AddListExampleAndroidLinux(self, parent, policy):
211 '''Adds an example value for Android/Linux of a 'list' policy to a DOM node.
212
213 Args:
214 parent: The DOM node for which the example will be added.
215 policy: A policy of type 'list', for which the Android/Linux example value
216 is generated.
217 '''
218 example_value = policy['example_value']
219 self.AddElement(parent, 'dt', {}, 'Android/Linux:')
220 element = self._AddStyledElement(parent, 'dd', ['.monospace'])
221 text = []
222 for item in example_value:
223 text.append('"%s"' % item)
224 self.AddText(element, '[%s]' % ', '.join(text))
225
226 def _AddListExample(self, parent, policy):
227 '''Adds the example value of a 'list' policy to a DOM node. Example output:
228 <dl>
229 <dt>Windows:</dt>
230 <dd>
231 Software\Policies\Chromium\DisabledPlugins\0 = "Java"
232 Software\Policies\Chromium\DisabledPlugins\1 = "Shockwave Flash"
233 </dd>
234 <dt>Android/Linux:</dt>
235 <dd>["Java", "Shockwave Flash"]</dd>
236 <dt>Mac:</dt>
237 <dd>
238 <array>
239 <string>Java</string>
240 <string>Shockwave Flash</string>
241 </array>
242 </dd>
243 </dl>
244
245 Args:
246 parent: The DOM node for which the example will be added.
247 policy: The data structure of a policy.
248 '''
249 examples = self._AddStyledElement(parent, 'dl', ['dd dl'])
250 if self.IsPolicySupportedOnPlatform(policy, 'win'):
251 self._AddListExampleWindows(examples, policy)
252 if (self.IsPolicySupportedOnPlatform(policy, 'android') or
253 self.IsPolicySupportedOnPlatform(policy, 'linux')):
254 self._AddListExampleAndroidLinux(examples, policy)
255 if self.IsPolicySupportedOnPlatform(policy, 'mac'):
256 self._AddListExampleMac(examples, policy)
257
258 def _PythonObjectToPlist(self, obj, indent=''):
259 '''Converts a python object to an equivalent XML plist.
260
261 Returns a list of lines.'''
262 obj_type = type(obj)
263 if obj_type == bool:
264 return [ '%s<%s/>' % (indent, 'true' if obj else 'false') ]
265 elif obj_type == int:
266 return [ '%s<integer>%s</integer>' % (indent, obj) ]
267 elif obj_type == str:
268 return [ '%s<string>%s</string>' % (indent, obj) ]
269 elif obj_type == list:
270 result = [ '%s<array>' % indent ]
271 for item in obj:
272 result += self._PythonObjectToPlist(item, indent + ' ')
273 result.append('%s</array>' % indent)
274 return result
275 elif obj_type == dict:
276 result = [ '%s<dict>' % indent ]
277 for key in sorted(obj.keys()):
278 result.append('%s<key>%s</key>' % (indent + ' ', key))
279 result += self._PythonObjectToPlist(obj[key], indent + ' ')
280 result.append('%s</dict>' % indent)
281 return result
282 else:
283 raise Exception('Invalid object to convert: %s' % obj)
284
285 def _AddDictionaryExampleMac(self, parent, policy):
286 '''Adds an example value for Mac of a 'dict' policy to a DOM node.
287
288 Args:
289 parent: The DOM node for which the example will be added.
290 policy: A policy of type 'dict', for which the Mac example value
291 is generated.
292 '''
293 example_value = policy['example_value']
294 self.AddElement(parent, 'dt', {}, 'Mac:')
295 mac = self._AddStyledElement(parent, 'dd', ['.monospace', '.pre'])
296 mac_text = ['<key>%s</key>' % (policy['name'])]
297 mac_text += self._PythonObjectToPlist(example_value)
298 self.AddText(mac, '\n'.join(mac_text))
299
300 def _AddDictionaryExampleWindows(self, parent, policy):
301 '''Adds an example value for Windows of a 'dict' policy to a DOM node.
302
303 Args:
304 parent: The DOM node for which the example will be added.
305 policy: A policy of type 'dict', for which the Windows example value
306 is generated.
307 '''
308 self.AddElement(parent, 'dt', {}, 'Windows:')
309 win = self._AddStyledElement(parent, 'dd', ['.monospace', '.pre'])
310 if self.CanBeRecommended(policy) and not self.CanBeMandatory(policy):
311 key_name = self.config['win_reg_recommended_key_name']
312 else:
313 key_name = self.config['win_reg_mandatory_key_name']
314 example = json.dumps(policy['example_value'])
315 self.AddText(win, '%s\\%s = %s' % (key_name, policy['name'], example))
316
317 def _AddDictionaryExampleAndroidLinux(self, parent, policy):
318 '''Adds an example value for Android/Linux of a 'dict' policy to a DOM node.
319
320 Args:
321 parent: The DOM node for which the example will be added.
322 policy: A policy of type 'dict', for which the Android/Linux example value
323 is generated.
324 '''
325 self.AddElement(parent, 'dt', {}, 'Android/Linux:')
326 element = self._AddStyledElement(parent, 'dd', ['.monospace'])
327 example = json.dumps(policy['example_value'])
328 self.AddText(element, '%s: %s' % (policy['name'], example))
329
330 def _AddDictionaryExample(self, parent, policy):
331 '''Adds the example value of a 'dict' policy to a DOM node. Example output:
332 <dl>
333 <dt>Windows:</dt>
334 <dd>
335 Software\Policies\Chromium\ProxySettings = "{ 'ProxyMode': 'direct' }"
336 </dd>
337 <dt>Android/Linux:</dt>
338 <dd>"ProxySettings": {
339 "ProxyMode": "direct"
340 }
341 </dd>
342 <dt>Mac:</dt>
343 <dd>
344 <key>ProxySettings</key>
345 <dict>
346 <key>ProxyMode</key>
347 <string>direct</string>
348 </dict>
349 </dd>
350 </dl>
351
352 Args:
353 parent: The DOM node for which the example will be added.
354 policy: The data structure of a policy.
355 '''
356 examples = self._AddStyledElement(parent, 'dl', ['dd dl'])
357 if self.IsPolicySupportedOnPlatform(policy, 'win'):
358 self._AddDictionaryExampleWindows(examples, policy)
359 if (self.IsPolicySupportedOnPlatform(policy, 'android') or
360 self.IsPolicySupportedOnPlatform(policy, 'linux')):
361 self._AddDictionaryExampleAndroidLinux(examples, policy)
362 if self.IsPolicySupportedOnPlatform(policy, 'mac'):
363 self._AddDictionaryExampleMac(examples, policy)
364
365 def _AddExample(self, parent, policy):
366 '''Adds the HTML DOM representation of the example value of a policy to
367 a DOM node. It is simple text for boolean policies, like
368 '0x00000001 (Windows), true (Linux), true (Android), <true /> (Mac)'
369 in case of boolean policies, but it may also contain other HTML elements.
370 (See method _AddListExample.)
371
372 Args:
373 parent: The DOM node for which the example will be added.
374 policy: The data structure of a policy.
375
376 Raises:
377 Exception: If the type of the policy is unknown or the example value
378 of the policy is out of its expected range.
379 '''
380 example_value = policy['example_value']
381 policy_type = policy['type']
382 if policy_type == 'main':
383 pieces = []
384 if self.IsPolicySupportedOnPlatform(policy, 'win'):
385 value = '0x00000001' if example_value else '0x00000000'
386 pieces.append(value + ' (Windows)')
387 if self.IsPolicySupportedOnPlatform(policy, 'linux'):
388 value = 'true' if example_value else 'false'
389 pieces.append(value + ' (Linux)')
390 if self.IsPolicySupportedOnPlatform(policy, 'android'):
391 value = 'true' if example_value else 'false'
392 pieces.append(value + ' (Android)')
393 if self.IsPolicySupportedOnPlatform(policy, 'mac'):
394 value = '<true />' if example_value else '<false />'
395 pieces.append(value + ' (Mac)')
396 self.AddText(parent, ', '.join(pieces))
397 elif policy_type == 'string':
398 self.AddText(parent, '"%s"' % example_value)
399 elif policy_type in ('int', 'int-enum'):
400 pieces = []
401 if self.IsPolicySupportedOnPlatform(policy, 'win'):
402 pieces.append('0x%08x (Windows)' % example_value)
403 if self.IsPolicySupportedOnPlatform(policy, 'linux'):
404 pieces.append('%d (Linux)' % example_value)
405 if self.IsPolicySupportedOnPlatform(policy, 'android'):
406 pieces.append('%d (Android)' % example_value)
407 if self.IsPolicySupportedOnPlatform(policy, 'mac'):
408 pieces.append('%d (Mac)' % example_value)
409 self.AddText(parent, ', '.join(pieces))
410 elif policy_type == 'string-enum':
411 self.AddText(parent, '"%s"' % (example_value))
412 elif policy_type in ('list', 'string-enum-list'):
413 self._AddListExample(parent, policy)
414 elif policy_type == 'dict':
415 self._AddDictionaryExample(parent, policy)
416 else:
417 raise Exception('Unknown policy type: ' + policy_type)
418
419 def _AddPolicyAttribute(self, dl, term_id,
420 definition=None, definition_style=None):
421 '''Adds a term-definition pair to a HTML DOM <dl> node. This method is
422 used by _AddPolicyDetails. Its result will have the form of:
423 <dt style="...">...</dt>
424 <dd style="...">...</dd>
425
426 Args:
427 dl: The DOM node of the <dl> list.
428 term_id: A key to self._STRINGS[] which specifies the term of the pair.
429 definition: The text of the definition. (Optional.)
430 definition_style: List of references to values self._STYLE[] that specify
431 the CSS stylesheet of the <dd> (definition) element.
432
433 Returns:
434 The DOM node representing the definition <dd> element.
435 '''
436 # Avoid modifying the default value of definition_style.
437 if definition_style == None:
438 definition_style = []
439 term = self._GetLocalizedMessage(term_id)
440 self._AddStyledElement(dl, 'dt', ['dt'], {}, term)
441 return self._AddStyledElement(dl, 'dd', definition_style, {}, definition)
442
443 def _AddSupportedOnList(self, parent, supported_on_list):
444 '''Creates a HTML list containing the platforms, products and versions
445 that are specified in the list of supported_on.
446
447 Args:
448 parent: The DOM node for which the list will be added.
449 supported_on_list: The list of supported products, as a list of
450 dictionaries.
451 '''
452 ul = self._AddStyledElement(parent, 'ul', ['ul'])
453 for supported_on in supported_on_list:
454 text = []
455 product = supported_on['product']
456 platforms = supported_on['platforms']
457 text.append(self._PRODUCT_MAP[product])
458 text.append('(%s)' %
459 self._MapListToString(self._PLATFORM_MAP, platforms))
460 if supported_on['since_version']:
461 since_version = self._GetLocalizedMessage('since_version')
462 text.append(since_version.replace('$6', supported_on['since_version']))
463 if supported_on['until_version']:
464 until_version = self._GetLocalizedMessage('until_version')
465 text.append(until_version.replace('$6', supported_on['until_version']))
466 # Add the list element:
467 self.AddElement(ul, 'li', {}, ' '.join(text))
468
469 def _AddPolicyDetails(self, parent, policy):
470 '''Adds the list of attributes of a policy to the HTML DOM node parent.
471 It will have the form:
472 <dl>
473 <dt>Attribute:</dt><dd>Description</dd>
474 ...
475 </dl>
476
477 Args:
478 parent: A DOM element for which the list will be added.
479 policy: The data structure of the policy.
480 '''
481
482 dl = self.AddElement(parent, 'dl')
483 data_type = [self._TYPE_MAP[policy['type']]]
484 qualified_types = []
485 is_complex_policy = False
486 if (self.IsPolicySupportedOnPlatform(policy, 'android') and
487 self._RESTRICTION_TYPE_MAP.get(policy['type'], None)):
488 qualified_types.append('Android:%s' %
489 self._RESTRICTION_TYPE_MAP[policy['type']])
490 if policy['type'] in ('dict', 'list'):
491 is_complex_policy = True
492 if (self.IsPolicySupportedOnPlatform(policy, 'win') and
493 self._REG_TYPE_MAP.get(policy['type'], None)):
494 qualified_types.append('Windows:%s' % self._REG_TYPE_MAP[policy['type']])
495 if policy['type'] == 'dict':
496 is_complex_policy = True
497 if qualified_types:
498 data_type.append('[%s]' % ', '.join(qualified_types))
499 if is_complex_policy:
500 data_type.append('(%s)' %
501 self._GetLocalizedMessage('complex_policies_on_windows'))
502 self._AddPolicyAttribute(dl, 'data_type', ' '.join(data_type))
503 if policy['type'] != 'external':
504 # All types except 'external' can be set through platform policy.
505 if self.IsPolicySupportedOnPlatform(policy, 'win'):
506 if self.CanBeRecommended(policy) and not self.CanBeMandatory(policy):
507 key_name = self.config['win_reg_recommended_key_name']
508 else:
509 key_name = self.config['win_reg_mandatory_key_name']
510 self._AddPolicyAttribute(
511 dl,
512 'win_reg_loc',
513 key_name + '\\' + policy['name'],
514 ['.monospace'])
515 if (self.IsPolicySupportedOnPlatform(policy, 'linux') or
516 self.IsPolicySupportedOnPlatform(policy, 'mac')):
517 self._AddPolicyAttribute(
518 dl,
519 'mac_linux_pref_name',
520 policy['name'],
521 ['.monospace'])
522 if self.IsPolicySupportedOnPlatform(policy, 'android', 'chrome'):
523 self._AddPolicyAttribute(
524 dl,
525 'android_restriction_name',
526 policy['name'],
527 ['.monospace'])
528 if self.IsPolicySupportedOnPlatform(policy, 'android', 'webview'):
529 restriction_prefix = self.config['android_webview_restriction_prefix']
530 self._AddPolicyAttribute(
531 dl,
532 'android_webview_restriction_name',
533 restriction_prefix + policy['name'],
534 ['.monospace'])
535 dd = self._AddPolicyAttribute(dl, 'supported_on')
536 self._AddSupportedOnList(dd, policy['supported_on'])
537 dd = self._AddPolicyAttribute(dl, 'supported_features')
538 self._AddFeatures(dd, policy)
539 dd = self._AddPolicyAttribute(dl, 'description')
540 self._AddDescription(dd, policy)
541 if (self.IsPolicySupportedOnPlatform(policy, 'win') or
542 self.IsPolicySupportedOnPlatform(policy, 'linux') or
543 self.IsPolicySupportedOnPlatform(policy, 'android') or
544 self.IsPolicySupportedOnPlatform(policy, 'mac')):
545 # Don't add an example for ChromeOS-only policies.
546 if policy['type'] != 'external':
547 # All types except 'external' can be set through platform policy.
548 dd = self._AddPolicyAttribute(dl, 'example_value')
549 self._AddExample(dd, policy)
550
551 def _AddPolicyNote(self, parent, policy):
552 '''If a policy has an additional web page assigned with it, then add
553 a link for that page.
554
555 Args:
556 policy: The data structure of the policy.
557 '''
558 if 'problem_href' not in policy:
559 return
560 problem_href = policy['problem_href']
561 div = self._AddStyledElement(parent, 'div', ['div.note'])
562 note = self._GetLocalizedMessage('note').replace('$6', problem_href)
563 self._AddParagraphs(div, note)
564
565 def _AddPolicyRow(self, parent, policy):
566 '''Adds a row for the policy in the summary table.
567
568 Args:
569 parent: The DOM node of the summary table.
570 policy: The data structure of the policy.
571 '''
572 tr = self._AddStyledElement(parent, 'tr', ['tr'])
573 indent = 'padding-left: %dpx;' % (7 + self._indent_level * 14)
574 if policy['type'] != 'group':
575 # Normal policies get two columns with name and caption.
576 name_td = self._AddStyledElement(tr, 'td', ['td', 'td.left'],
577 {'style': indent})
578 self.AddElement(name_td, 'a',
579 {'href': '#' + policy['name']}, policy['name'])
580 self._AddStyledElement(tr, 'td', ['td', 'td.right'], {},
581 policy['caption'])
582 else:
583 # Groups get one column with caption.
584 name_td = self._AddStyledElement(tr, 'td', ['td', 'td.left'],
585 {'style': indent, 'colspan': '2'})
586 self.AddElement(name_td, 'a', {'href': '#' + policy['name']},
587 policy['caption'])
588
589 def _AddPolicySection(self, parent, policy):
590 '''Adds a section about the policy in the detailed policy listing.
591
592 Args:
593 parent: The DOM node of the <div> of the detailed policy list.
594 policy: The data structure of the policy.
595 '''
596 # Set style according to group nesting level.
597 indent = 'margin-left: %dpx' % (self._indent_level * 28)
598 if policy['type'] == 'group':
599 heading = 'h2'
600 else:
601 heading = 'h3'
602 parent2 = self.AddElement(parent, 'div', {'style': indent})
603
604 h2 = self.AddElement(parent2, heading)
605 self.AddElement(h2, 'a', {'name': policy['name']})
606 if policy['type'] != 'group':
607 # Normal policies get a full description.
608 policy_name_text = policy['name']
609 if 'deprecated' in policy and policy['deprecated'] == True:
610 policy_name_text += " ("
611 policy_name_text += self._GetLocalizedMessage('deprecated') + ")"
612 self.AddText(h2, policy_name_text)
613 self.AddElement(parent2, 'span', {}, policy['caption'])
614 self._AddPolicyNote(parent2, policy)
615 self._AddPolicyDetails(parent2, policy)
616 else:
617 # Groups get a more compact description.
618 self.AddText(h2, policy['caption'])
619 self._AddStyledElement(parent2, 'div', ['div.group_desc'],
620 {}, policy['desc'])
621 self.AddElement(
622 parent2, 'a', {'href': '#top'},
623 self._GetLocalizedMessage('back_to_top'))
624
625 #
626 # Implementation of abstract methods of TemplateWriter:
627 #
628
629 def IsDeprecatedPolicySupported(self, policy):
630 return True
631
632 def WritePolicy(self, policy):
633 self._AddPolicyRow(self._summary_tbody, policy)
634 self._AddPolicySection(self._details_div, policy)
635
636 def BeginPolicyGroup(self, group):
637 self.WritePolicy(group)
638 self._indent_level += 1
639
640 def EndPolicyGroup(self):
641 self._indent_level -= 1
642
643 def BeginTemplate(self):
644 # Add a <div> for the summary section.
645 if self._GetChromiumVersionString() is not None:
646 self.AddComment(self._main_div, self.config['build'] + \
647 ' version: ' + self._GetChromiumVersionString())
648
649 summary_div = self.AddElement(self._main_div, 'div')
650 self.AddElement(summary_div, 'a', {'name': 'top'})
651 self.AddElement(summary_div, 'br')
652 self._AddParagraphs(
653 summary_div,
654 self._GetLocalizedMessage('intro'))
655 self.AddElement(summary_div, 'br')
656 self.AddElement(summary_div, 'br')
657 self.AddElement(summary_div, 'br')
658 # Add the summary table of policies.
659 summary_table = self._AddStyledElement(summary_div, 'table', ['table'])
660 # Add the first row.
661 thead = self.AddElement(summary_table, 'thead')
662 tr = self._AddStyledElement(thead, 'tr', ['tr'])
663 self._AddStyledElement(
664 tr, 'td', ['td', 'td.left', 'thead td'], {},
665 self._GetLocalizedMessage('name_column_title'))
666 self._AddStyledElement(
667 tr, 'td', ['td', 'td.right', 'thead td'], {},
668 self._GetLocalizedMessage('description_column_title'))
669 self._summary_tbody = self.AddElement(summary_table, 'tbody')
670
671 # Add a <div> for the detailed policy listing.
672 self._details_div = self.AddElement(self._main_div, 'div')
673
674 def Init(self):
675 dom_impl = minidom.getDOMImplementation('')
676 self._doc = dom_impl.createDocument(None, 'html', None)
677 body = self.AddElement(self._doc.documentElement, 'body')
678 self._main_div = self.AddElement(body, 'div')
679 self._indent_level = 0
680
681 # Human-readable names of supported platforms.
682 self._PLATFORM_MAP = {
683 'win': 'Windows',
684 'mac': 'Mac',
685 'linux': 'Linux',
686 'chrome_os': self.config['os_name'],
687 'android': 'Android',
688 'ios': 'iOS',
689 }
690 # Human-readable names of supported products.
691 self._PRODUCT_MAP = {
692 'chrome': self.config['app_name'],
693 'chrome_frame': self.config['frame_name'],
694 'chrome_os': self.config['os_name'],
695 'webview': self.config['webview_name'],
696 }
697 # Human-readable names of supported features. Each supported feature has
698 # a 'doc_feature_X' entry in |self.messages|.
699 self._FEATURE_MAP = {}
700 for message in self.messages:
701 if message.startswith('doc_feature_'):
702 self._FEATURE_MAP[message[12:]] = self.messages[message]['text']
703 # Human-readable names of types.
704 self._TYPE_MAP = {
705 'string': 'String',
706 'int': 'Integer',
707 'main': 'Boolean',
708 'int-enum': 'Integer',
709 'string-enum': 'String',
710 'list': 'List of strings',
711 'string-enum-list': 'List of strings',
712 'dict': 'Dictionary',
713 'external': 'External data reference',
714 }
715 self._REG_TYPE_MAP = {
716 'string': 'REG_SZ',
717 'int': 'REG_DWORD',
718 'main': 'REG_DWORD',
719 'int-enum': 'REG_DWORD',
720 'string-enum': 'REG_SZ',
721 'dict': 'REG_SZ',
722 }
723 self._RESTRICTION_TYPE_MAP = {
724 'int-enum': 'choice',
725 'string-enum': 'choice',
726 'list': 'string',
727 'string-enum-list': 'multi-select',
728 'dict': 'string',
729 }
730 # The CSS style-sheet used for the document. It will be used in Google
731 # Sites, which strips class attributes from HTML tags. To work around this,
732 # the style-sheet is a dictionary and the style attributes will be added
733 # "by hand" for each element.
734 self._STYLE = {
735 'table': 'border-style: none; border-collapse: collapse;',
736 'tr': 'height: 0px;',
737 'td': 'border: 1px dotted rgb(170, 170, 170); padding: 7px; '
738 'vertical-align: top; width: 236px; height: 15px;',
739 'thead td': 'font-weight: bold;',
740 'td.left': 'width: 200px;',
741 'td.right': 'width: 100%;',
742 'dt': 'font-weight: bold;',
743 'dd dl': 'margin-top: 0px; margin-bottom: 0px;',
744 '.monospace': 'font-family: monospace;',
745 '.pre': 'white-space: pre;',
746 'div.note': 'border: 2px solid black; padding: 5px; margin: 5px;',
747 'div.group_desc': 'margin-top: 20px; margin-bottom: 20px;',
748 'ul': 'padding-left: 0px; margin-left: 0px;'
749 }
750
751
752 def GetTemplateText(self):
753 # Return the text representation of the main <div> tag.
754 return self._main_div.toxml()
755 # To get a complete HTML file, use the following.
756 # return self._doc.toxml()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698