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

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

Issue 1438403002: Remove contents of grit's git-svn-mirror repository. (Closed) Base URL: https://chromium.googlesource.com/external/grit-i18n@master
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
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'):
523 self._AddPolicyAttribute(
524 dl,
525 'android_restriction_name',
526 policy['name'],
527 ['.monospace'])
528 dd = self._AddPolicyAttribute(dl, 'supported_on')
529 self._AddSupportedOnList(dd, policy['supported_on'])
530 dd = self._AddPolicyAttribute(dl, 'supported_features')
531 self._AddFeatures(dd, policy)
532 dd = self._AddPolicyAttribute(dl, 'description')
533 self._AddDescription(dd, policy)
534 if (self.IsPolicySupportedOnPlatform(policy, 'win') or
535 self.IsPolicySupportedOnPlatform(policy, 'linux') or
536 self.IsPolicySupportedOnPlatform(policy, 'android') or
537 self.IsPolicySupportedOnPlatform(policy, 'mac')):
538 # Don't add an example for ChromeOS-only policies.
539 if policy['type'] != 'external':
540 # All types except 'external' can be set through platform policy.
541 dd = self._AddPolicyAttribute(dl, 'example_value')
542 self._AddExample(dd, policy)
543
544 def _AddPolicyNote(self, parent, policy):
545 '''If a policy has an additional web page assigned with it, then add
546 a link for that page.
547
548 Args:
549 policy: The data structure of the policy.
550 '''
551 if 'problem_href' not in policy:
552 return
553 problem_href = policy['problem_href']
554 div = self._AddStyledElement(parent, 'div', ['div.note'])
555 note = self._GetLocalizedMessage('note').replace('$6', problem_href)
556 self._AddParagraphs(div, note)
557
558 def _AddPolicyRow(self, parent, policy):
559 '''Adds a row for the policy in the summary table.
560
561 Args:
562 parent: The DOM node of the summary table.
563 policy: The data structure of the policy.
564 '''
565 tr = self._AddStyledElement(parent, 'tr', ['tr'])
566 indent = 'padding-left: %dpx;' % (7 + self._indent_level * 14)
567 if policy['type'] != 'group':
568 # Normal policies get two columns with name and caption.
569 name_td = self._AddStyledElement(tr, 'td', ['td', 'td.left'],
570 {'style': indent})
571 self.AddElement(name_td, 'a',
572 {'href': '#' + policy['name']}, policy['name'])
573 self._AddStyledElement(tr, 'td', ['td', 'td.right'], {},
574 policy['caption'])
575 else:
576 # Groups get one column with caption.
577 name_td = self._AddStyledElement(tr, 'td', ['td', 'td.left'],
578 {'style': indent, 'colspan': '2'})
579 self.AddElement(name_td, 'a', {'href': '#' + policy['name']},
580 policy['caption'])
581
582 def _AddPolicySection(self, parent, policy):
583 '''Adds a section about the policy in the detailed policy listing.
584
585 Args:
586 parent: The DOM node of the <div> of the detailed policy list.
587 policy: The data structure of the policy.
588 '''
589 # Set style according to group nesting level.
590 indent = 'margin-left: %dpx' % (self._indent_level * 28)
591 if policy['type'] == 'group':
592 heading = 'h2'
593 else:
594 heading = 'h3'
595 parent2 = self.AddElement(parent, 'div', {'style': indent})
596
597 h2 = self.AddElement(parent2, heading)
598 self.AddElement(h2, 'a', {'name': policy['name']})
599 if policy['type'] != 'group':
600 # Normal policies get a full description.
601 policy_name_text = policy['name']
602 if 'deprecated' in policy and policy['deprecated'] == True:
603 policy_name_text += " ("
604 policy_name_text += self._GetLocalizedMessage('deprecated') + ")"
605 self.AddText(h2, policy_name_text)
606 self.AddElement(parent2, 'span', {}, policy['caption'])
607 self._AddPolicyNote(parent2, policy)
608 self._AddPolicyDetails(parent2, policy)
609 else:
610 # Groups get a more compact description.
611 self.AddText(h2, policy['caption'])
612 self._AddStyledElement(parent2, 'div', ['div.group_desc'],
613 {}, policy['desc'])
614 self.AddElement(
615 parent2, 'a', {'href': '#top'},
616 self._GetLocalizedMessage('back_to_top'))
617
618 #
619 # Implementation of abstract methods of TemplateWriter:
620 #
621
622 def IsDeprecatedPolicySupported(self, policy):
623 return True
624
625 def WritePolicy(self, policy):
626 self._AddPolicyRow(self._summary_tbody, policy)
627 self._AddPolicySection(self._details_div, policy)
628
629 def BeginPolicyGroup(self, group):
630 self.WritePolicy(group)
631 self._indent_level += 1
632
633 def EndPolicyGroup(self):
634 self._indent_level -= 1
635
636 def BeginTemplate(self):
637 # Add a <div> for the summary section.
638 if self._GetChromiumVersionString() is not None:
639 self.AddComment(self._main_div, self.config['build'] + \
640 ' version: ' + self._GetChromiumVersionString())
641
642 summary_div = self.AddElement(self._main_div, 'div')
643 self.AddElement(summary_div, 'a', {'name': 'top'})
644 self.AddElement(summary_div, 'br')
645 self._AddParagraphs(
646 summary_div,
647 self._GetLocalizedMessage('intro'))
648 self.AddElement(summary_div, 'br')
649 self.AddElement(summary_div, 'br')
650 self.AddElement(summary_div, 'br')
651 # Add the summary table of policies.
652 summary_table = self._AddStyledElement(summary_div, 'table', ['table'])
653 # Add the first row.
654 thead = self.AddElement(summary_table, 'thead')
655 tr = self._AddStyledElement(thead, 'tr', ['tr'])
656 self._AddStyledElement(
657 tr, 'td', ['td', 'td.left', 'thead td'], {},
658 self._GetLocalizedMessage('name_column_title'))
659 self._AddStyledElement(
660 tr, 'td', ['td', 'td.right', 'thead td'], {},
661 self._GetLocalizedMessage('description_column_title'))
662 self._summary_tbody = self.AddElement(summary_table, 'tbody')
663
664 # Add a <div> for the detailed policy listing.
665 self._details_div = self.AddElement(self._main_div, 'div')
666
667 def Init(self):
668 dom_impl = minidom.getDOMImplementation('')
669 self._doc = dom_impl.createDocument(None, 'html', None)
670 body = self.AddElement(self._doc.documentElement, 'body')
671 self._main_div = self.AddElement(body, 'div')
672 self._indent_level = 0
673
674 # Human-readable names of supported platforms.
675 self._PLATFORM_MAP = {
676 'win': 'Windows',
677 'mac': 'Mac',
678 'linux': 'Linux',
679 'chrome_os': self.config['os_name'],
680 'android': 'Android',
681 'ios': 'iOS',
682 }
683 # Human-readable names of supported products.
684 self._PRODUCT_MAP = {
685 'chrome': self.config['app_name'],
686 'chrome_frame': self.config['frame_name'],
687 'chrome_os': self.config['os_name'],
688 }
689 # Human-readable names of supported features. Each supported feature has
690 # a 'doc_feature_X' entry in |self.messages|.
691 self._FEATURE_MAP = {}
692 for message in self.messages:
693 if message.startswith('doc_feature_'):
694 self._FEATURE_MAP[message[12:]] = self.messages[message]['text']
695 # Human-readable names of types.
696 self._TYPE_MAP = {
697 'string': 'String',
698 'int': 'Integer',
699 'main': 'Boolean',
700 'int-enum': 'Integer',
701 'string-enum': 'String',
702 'list': 'List of strings',
703 'string-enum-list': 'List of strings',
704 'dict': 'Dictionary',
705 'external': 'External data reference',
706 }
707 self._REG_TYPE_MAP = {
708 'string': 'REG_SZ',
709 'int': 'REG_DWORD',
710 'main': 'REG_DWORD',
711 'int-enum': 'REG_DWORD',
712 'string-enum': 'REG_SZ',
713 'dict': 'REG_SZ',
714 }
715 self._RESTRICTION_TYPE_MAP = {
716 'int-enum': 'choice',
717 'string-enum': 'choice',
718 'list': 'string',
719 'string-enum-list': 'multi-select',
720 'dict': 'string',
721 }
722 # The CSS style-sheet used for the document. It will be used in Google
723 # Sites, which strips class attributes from HTML tags. To work around this,
724 # the style-sheet is a dictionary and the style attributes will be added
725 # "by hand" for each element.
726 self._STYLE = {
727 'table': 'border-style: none; border-collapse: collapse;',
728 'tr': 'height: 0px;',
729 'td': 'border: 1px dotted rgb(170, 170, 170); padding: 7px; '
730 'vertical-align: top; width: 236px; height: 15px;',
731 'thead td': 'font-weight: bold;',
732 'td.left': 'width: 200px;',
733 'td.right': 'width: 100%;',
734 'dt': 'font-weight: bold;',
735 'dd dl': 'margin-top: 0px; margin-bottom: 0px;',
736 '.monospace': 'font-family: monospace;',
737 '.pre': 'white-space: pre;',
738 'div.note': 'border: 2px solid black; padding: 5px; margin: 5px;',
739 'div.group_desc': 'margin-top: 20px; margin-bottom: 20px;',
740 'ul': 'padding-left: 0px; margin-left: 0px;'
741 }
742
743
744 def GetTemplateText(self):
745 # Return the text representation of the main <div> tag.
746 return self._main_div.toxml()
747 # To get a complete HTML file, use the following.
748 # return self._doc.toxml()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698