• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE HTML>
2<html i18n-values="dir:textdirection;">
3<head>
4<meta charset="utf-8">
5<title i18n-content="pluginsTitle"></title>
6<style>
7body {
8  margin: 10px;
9  min-width: 47em;
10}
11
12a {
13  color: blue;
14  font-size: 103%;
15}
16
17div#header {
18  margin-bottom: 1.05em;
19  /* 67px is the height of the header's background image. */
20  min-height: 67px;
21  overflow: hidden;
22  padding-bottom: 20px;
23  -webkit-padding-start: 0;
24  padding-top: 20px;
25  position: relative;
26  box-sizing: border-box;
27}
28
29#header h1 {
30  background: url('../../app/theme/extensions_section.png') 0px 20px no-repeat;
31  display: inline;
32  margin: 0;
33  padding-bottom: 43px;
34  padding-left: 75px;
35  padding-top: 40px;
36}
37
38html[dir=rtl] #header h1 {
39  background: url('../../app/theme/extensions_section.png') right no-repeat;
40  padding-right: 95px;
41  padding-left: 0;
42}
43
44h1 {
45  font-size: 156%;
46  font-weight: bold;
47  padding: 0;
48  margin: 0;
49}
50
51div.content {
52  font-size: 88%;
53  margin-top: 5px;
54}
55
56.section-header {
57  background: #ebeff9;
58  border-top: 1px solid #b5c7de;
59  font-size: 99%;
60  padding-bottom: 2px;
61  -webkit-padding-start: 5px;
62  padding-top: 3px;
63  width: 100%;
64}
65
66.section-header > table tr td:first-child {
67  width: 100%;
68}
69
70.section-header > table {
71  width: 100%;
72}
73
74.section-header-title {
75  font-weight: bold;
76}
77
78.vbox-container {
79  display: -webkit-box;
80  -webkit-box-orient: vertical;
81}
82
83.wbox {
84  display: -webkit-box;
85  -webkit-box-align: stretch;
86  -webkit-box-flex: 1;
87}
88
89#top {
90  -webkit-padding-end: 5px;
91}
92
93.showInTmiMode {
94  overflow: hidden;
95}
96
97body.hideTmiModeInitial .showInTmiMode {
98  height: 0 !important;
99  opacity: 0;
100}
101
102body.hideTmiMode .showInTmiMode {
103  height: 0 !important;
104  opacity: 0;
105  -webkit-transition: all .1s ease-out;
106}
107
108body.showTmiModeInitial .showInTmiMode {
109  opacity: 1;
110}
111
112body.showTmiMode .showInTmiMode {
113  opacity: 1;
114  -webkit-transition: all .1s ease-in;
115}
116
117.wbox-tmi-mode {
118  -webkit-box-align: stretch;
119  -webkit-box-flex: 1;
120}
121
122.tmi-mode-image {
123  margin-top: 2px;
124  padding-left: 5px;
125  padding-right: 5px;
126}
127
128.tmi-mode-link {
129  margin-right: 3px;
130  white-space: nowrap;
131}
132
133.tmi-mode-link a {
134  font-size: 97%;
135}
136
137.tmi-mode {
138  background: #f4f6fc;
139  border-bottom: 1px solid #edeff5;
140  font-size: 89%;
141  padding-bottom: 0.8em;
142  -webkit-padding-start: 10px;
143  padding-top: 0.8em;
144  width: 100%;
145}
146
147.plugin-disabled > td {
148  background-color: #f0f0f0;
149  color: #a0a0a0;
150  padding-bottom: 4px;
151  padding-top: 5px;
152}
153
154.plugin-enabled > td {
155  padding-bottom: 4px;
156  padding-top: 5px;
157}
158
159.plugin-file-disabled {
160  background-color: #f0f0f0;
161  color: #a0a0a0;
162  padding-top: 5px;
163  padding-bottom: 5px;
164}
165
166.plugin-file-enabled {
167  padding-top: 5px;
168  padding-bottom: 5px;
169}
170
171.plugin {
172  border-bottom: 1px solid #cdcdcd;
173}
174
175.critical {
176  color: red;
177}
178
179/* Indent the text related to each plug-in. */
180.plugin-text {
181  -webkit-padding-start: 5px;
182}
183
184.plugin-name {
185  font-weight: bold;
186}
187
188.no-plugins {
189  margin: 6em 0 0;
190  text-align: center;
191  font-size: 1.2em;
192}
193
194/* Use tables for layout, so eliminate extra spacing. */
195.plugin-details table {
196  -webkit-border-horizontal-spacing: 0;
197  -webkit-border-vertical-spacing: 0;
198}
199
200.plugin-details {
201  -webkit-padding-start: 1em;
202}
203
204/* Separate the inital line, Description, Location, and MIME Types lines. */
205.plugin-details > div {
206  padding-top: 0.1em
207}
208
209/* Align rows of tables along the top. */
210.plugin-details tr {
211  vertical-align: top;
212}
213
214/* Separate columns by 1em for the most part. */
215.plugin-details td+td {
216  -webkit-padding-start: 1em;
217}
218
219/* Make the MIME Types tables smaller. */
220.plugin-details .mime-types {
221  font-size: 95%;
222}
223
224/* Separate the header from the contents in each MIME Types table. */
225.plugin-details .mime-types .header td {
226  padding-bottom: 0.1em;
227  border-bottom: 1px solid;
228}
229
230/* Separate the columns for tables used for horizontal listings only a bit. */
231.hlisting td+td {
232  -webkit-padding-start: 0.4em;
233}
234
235/* Match the indentation of .plugin-text. */
236.plugin-actions {
237  -webkit-padding-start: 5px;
238  margin-top: 0.2em;
239  margin-bottom: 0.2em;
240}
241
242button {
243  font-size: 104%;
244}
245
246</style>
247<script>
248
249/**
250 * This variable structure is here to document the structure that the template
251 * expects to correctly populate the page.
252 */
253var pluginDataFormat = {
254  'plugins': [
255    {
256      'name': 'Group Name',
257      'description': 'description',
258      'version': 'version',
259      'update_url': 'http://update/',
260      'critical': true,
261      'enabled': true,
262      'plugin_files': [
263        {
264          'path': '/blahblah/blahblah/MyCrappyPlugin.plugin',
265          'name': 'MyCrappyPlugin',
266          'version': '1.2.3',
267          'description': 'My crappy plugin',
268          'mimeTypes': [
269            { 'description': 'Foo Media',
270              'fileExtensions': [ 'foo' ],
271              'mimeType': 'application/x-my-foo' },
272            { 'description': 'Bar Stuff',
273              'fileExtensions': [ 'bar','baz' ],
274              'mimeType': 'application/my-bar' }
275          ],
276          'enabledMode': 'enabledByUser'
277        },
278        {
279          'path': '/tmp/MyFirst.plugin',
280          'name': 'MyFirstPlugin',
281          'version': '3.14r15926',
282          'description': 'My first plugin',
283          'mimeTypes': [
284            { 'description': 'New Guy Media',
285              'fileExtensions': [ 'mfp' ],
286              'mimeType': 'application/x-my-first' }
287          ],
288          'enabledMode': 'enabledByPolicy'
289        },
290        {
291          'path': '/foobar/baz/YourGreatPlugin.plugin',
292          'name': 'YourGreatPlugin',
293          'version': '4.5',
294          'description': 'Your great plugin',
295          'mimeTypes': [
296            { 'description': 'Baz Stuff',
297              'fileExtensions': [ 'baz' ],
298              'mimeType': 'application/x-your-baz' }
299          ],
300          'enabledMode': 'disabledByUser'
301        },
302        {
303          'path': '/foobiz/bar/HisGreatPlugin.plugin',
304          'name': 'HisGreatPlugin',
305          'version': '1.2',
306          'description': 'His great plugin',
307          'mimeTypes': [
308            { 'description': 'More baz Stuff',
309              'fileExtensions': [ 'bor' ],
310              'mimeType': 'application/x-his-bor' }
311          ],
312          'enabledMode': 'disabledByPolicy'
313        }
314      ]
315    }
316  ]
317};
318
319/**
320 * Takes the |pluginsData| input argument which represents data about the
321 * currently installed/running plugins and populates the html jstemplate with
322 * that data. It expects an object structure like the above.
323 * @param {Object} pluginsData Detailed info about installed plugins
324 */
325function renderTemplate(pluginsData) {
326  // This is the javascript code that processes the template:
327  var input = new JsEvalContext(pluginsData);
328  var output = document.getElementById('pluginTemplate');
329  jstProcess(input, output);
330}
331
332/**
333 * Asks the C++ PluginsDOMHandler to get details about the installed plugins and
334 * return detailed data about the configuration. The PluginsDOMHandler should
335 * reply to returnPluginsData() (below).
336 */
337function requestPluginsData() {
338  chrome.send('requestPluginsData', []);
339  chrome.send('getShowDetails', []);
340}
341
342function loadShowDetailsFromPrefs(show_details) {
343  tmiModeExpanded = show_details;
344  document.getElementById('collapse').style.display =
345      show_details ? 'inline' : 'none';
346  document.getElementById('expand').style.display =
347      show_details ? 'none' : 'inline';
348
349  document.body.className =
350      show_details ? 'showTmiMode' : 'hideTmiMode';
351}
352
353/**
354 * Asks the C++ PluginsDOMHandler to show the terms of service (about:terms).
355 */
356function showTermsOfService() {
357  chrome.send('showTermsOfService', []);
358}
359
360/**
361 * Called by the web_ui_ to re-populate the page with data representing the
362 * current state of installed plugins.
363 */
364function returnPluginsData(pluginsData){
365  var bodyContainer = document.getElementById('body-container');
366  var body = document.body;
367
368  // Set all page content to be visible so we can measure heights.
369  bodyContainer.style.visibility = 'hidden';
370  body.className = '';
371  var slidables = document.getElementsByClassName('showInTmiMode');
372  for (var i = 0; i < slidables.length; i++)
373    slidables[i].style.height = 'auto';
374
375  renderTemplate(pluginsData);
376
377  // Make sure the left column (with "Description:", "Location:", etc.) is the
378  // same size for all plugins.
379  var labels = document.getElementsByClassName('plugin-details-label');
380  var maxLabelWidth = 0;
381  for (var i = 0; i < labels.length; i++)
382    labels[i].style.width = 'auto';
383  for (var i = 0; i < labels.length; i++)
384    maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth);
385  for (var i = 0; i < labels.length; i++)
386    labels[i].style.width = maxLabelWidth + 'px';
387
388  // Explicitly set the height for each element that wants to be "slid" in and
389  // out when the tmiModeExpanded is toggled.
390  var slidables = document.getElementsByClassName('showInTmiMode');
391  for (var i = 0; i < slidables.length; i++)
392    slidables[i].style.height = slidables[i].offsetHeight + 'px';
393
394  // Reset visibility of page based on the current tmi mode.
395  document.getElementById('collapse').style.display =
396     tmiModeExpanded ? 'inline' : 'none';
397  document.getElementById('expand').style.display =
398     tmiModeExpanded ? 'none' : 'inline';
399  bodyContainer.style.visibility = 'visible';
400  body.className = tmiModeExpanded ?
401     'showTmiModeInitial' : 'hideTmiModeInitial';
402}
403
404/**
405 * Handles a 'enable' or 'disable' button getting clicked.
406 */
407function handleEnablePlugin(node, enable, isGroup) {
408  // Tell the C++ PluginsDOMHandler to enable/disable the plugin.
409  chrome.send('enablePlugin', [String(node.path), String(enable),
410              String(isGroup)]);
411}
412
413// Keeps track of whether details have been made visible (expanded) or not.
414var tmiModeExpanded = false;
415
416/*
417 * Toggles visibility of details.
418 */
419function toggleTmiMode() {
420  tmiModeExpanded = !tmiModeExpanded;
421
422  document.getElementById('collapse').style.display =
423      tmiModeExpanded ? 'inline' : 'none';
424  document.getElementById('expand').style.display =
425      tmiModeExpanded ? 'none' : 'inline';
426
427  document.body.className =
428      tmiModeExpanded ? 'showTmiMode' : 'hideTmiMode';
429
430  chrome.send('saveShowDetailsToPrefs', [String(tmiModeExpanded)]);
431}
432
433/**
434 * Determines whether a plugin's version should be displayed.
435 */
436function shouldDisplayPluginVersion(plugin) {
437  return !!plugin.version && plugin.version != '0';
438}
439
440/**
441 * Determines whether a plugin's description should be displayed.
442 */
443function shouldDisplayPluginDescription(plugin) {
444  // Only display the description if it's not blank and if it's not just the
445  // name, version, or combination thereof.
446  return plugin.description &&
447         plugin.description != plugin.name &&
448         plugin.description != plugin.version &&
449         plugin.description != 'Version ' + plugin.version &&
450         plugin.description != plugin.name + ' ' + plugin.version;
451}
452
453/**
454 * Determines whether a plugin is enabled or not.
455 */
456function isPluginEnabled(plugin) {
457  return plugin.enabledMode == 'enabledByUser' ||
458         plugin.enabledMode == 'enabledByPolicy';
459}
460
461// Unfortunately, we don't have notifications for plugin (list) status changes
462// (yet), so in the meanwhile just update regularly.
463setInterval(requestPluginsData, 30000);
464
465// Get data and have it displayed upon loading.
466document.addEventListener('DOMContentLoaded', requestPluginsData);
467
468</script>
469</head>
470<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
471<div id="body-container" style="visibility:hidden">
472
473  <div id="header"><h1 i18n-content="pluginsTitle">TITLE</h1></div>
474
475  <div id="pluginTemplate">
476
477    <div id="container" class="vbox-container">
478    <div id="top" class="wbox">
479
480      <div class="section-header">
481        <table cellpadding="0" cellspacing="0"><tr valign="center">
482          <td>
483            <span class="section-header-title" i18n-content="pluginsTitle"
484              >TITLE</span>
485            <span class="section-header-title"
486                  jsdisplay="plugins.length > 0">(<span
487                  jscontent="plugins.length"></span>)</span>
488          </td>
489          <td width="18">
490            <img id="collapse" class="tmi-mode-image"
491                 style="display:none" onclick="toggleTmiMode();"
492                 src="shared/images/minus.png">
493            <img id="expand" class="tmi-mode-image"
494                 onclick="toggleTmiMode();" src="shared/images/plus.png">
495          </td>
496          <td>
497            <div class="tmi-mode-link">
498              <a onclick="toggleTmiMode();" style="cursor: default"
499                 i18n-content="pluginsDetailsModeLink">DETAILS</a>
500            </div>
501          </td>
502        </tr></table>
503      </div>
504
505    </div>
506    </div>
507
508    <div class="content">
509      <div class="plugin-name no-plugins" jsdisplay="plugins.length === 0">
510        <div i18n-content="noPlugins">NO_PLUGINS_ARE_INSTALLED</div>
511      </div>
512
513      <div jsdisplay="plugins.length > 0">
514      <div class="plugin" jsselect="plugins">
515        <table width="100%" cellpadding="2" cellspacing="0">
516        <tr jsvalues=
517            ".className:isPluginEnabled($this) ? 'plugin-enabled' : 'plugin-disabled'">
518        <td valign="top">
519          <div class="plugin-text">
520            <div>
521              <span class="plugin-name" dir="ltr"
522                    jscontent="name">NAME</span>
523              <span jsdisplay="plugin_files.length > 1"
524                  jscontent="'(' + plugin_files.length +' files)'">(x)</span>
525              <span jsdisplay="shouldDisplayPluginVersion($this)">
526                - <span i18n-content="pluginVersion">VERSION</span>
527                <span jsvalues=".className:critical? 'critical': ''"
528                    dir="ltr" jscontent="version">x.x.x.x</span>
529              </span>
530              <a jsdisplay="critical" jsvalues=".href:update_url"
531                    i18n-content="pluginDownload">DOWNLOAD UPDATE</a>
532              <span jsdisplay="enabledMode == 'disabledByUser'"
533                    i18n-content="pluginDisabled">(DISABLED)</span>
534              <span jsdisplay="enabledMode == 'disabledByPolicy'"
535                    i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span>
536              <span jsdisplay="enabledMode == 'enabledByPolicy'"
537                    i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span>
538              <div jsdisplay="shouldDisplayPluginDescription($this)">
539                <span dir="ltr" jsvalues=".innerHTML:description">
540              </div>
541            </div>
542            <div jsselect="plugin_files" class="plugin-details">
543              <div class="showInTmiMode">
544                <div jsvalues=
545                  ".className:isPluginEnabled($this) ? 'plugin-file-enabled' : 'plugin-file-disabled'">
546                  <div><table><tr>
547                    <td class="plugin-details-label"
548                        i18n-content="pluginName">NAME:</td>
549                    <td><span dir="ltr" jscontent="name">NAME</span></td>
550                  </tr></table></div>
551                  <div><table>
552                    <tr jsdisplay="shouldDisplayPluginDescription($this)">
553                      <td class="plugin-details-label"
554                          i18n-content="pluginDescription">DESCRIPTION:</td>
555                      <td>
556                        <span dir="ltr" jsvalues=".innerHTML:description">
557                      </td>
558                    </tr>
559                  </table></div>
560                  <div><table><tr>
561                    <td class="plugin-details-label"
562                        i18n-content="pluginVersion">VERSION:</td>
563                    <td><span dir="ltr" jscontent="version">x.x.x.x</span></td>
564                  </tr></table></div>
565                  <div><table><tr>
566                    <td class="plugin-details-label"
567                        i18n-content="pluginPath">PATH:</td>
568                    <td><span dir="ltr" jscontent="path"></span></td>
569                  </tr></table></div>
570                  <div><table><tr>
571                    <td class="plugin-details-label">&nbsp;</td>
572                    <td>
573                      <span jsdisplay="enabledMode == 'disabledByUser'"
574                          i18n-content="pluginDisabled">(DISABLED)</span>
575                      <span jsdisplay="enabledMode == 'disabledByPolicy'"
576                          i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span>
577                      <span jsdisplay="enabledMode == 'enabledByPolicy'"
578                          i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span>
579                      <span>
580                        <a
581                          jsvalues=".path:path"
582                          jsdisplay="enabledMode == 'enabledByUser'"
583                          onclick="handleEnablePlugin(this, false, false)"
584                          href="javascript:void(0);"
585                          i18n-content="disable"
586                          >DISABLE</a>
587                        <a
588                          jsvalues=".path:path"
589                          jsdisplay="enabledMode == 'disabledByUser'"
590                          onclick="handleEnablePlugin(this, true, false)"
591                          href="javascript:void(0);"
592                          i18n-content="enable"
593                          >ENABLE</a>
594                        <span
595                          jsdisplay="enabledMode == 'enabledByPolicy'"
596                          i18n-content="pluginCannotBeDisabledDueToPolicy"
597                          >CANNOT_DISABLE</span>
598                        <span
599                          jsdisplay="enabledMode == 'disabledByPolicy'"
600                          i18n-content="pluginCannotBeEnabledDueToPolicy"
601                          >CANNOT_ENABLE</span>
602                      </span>
603                    </td>
604                  </tr></table></div>
605                  <table><tr jsdisplay="mimeTypes.length > 0">
606                    <td class="plugin-details-label"
607                        i18n-content="pluginMimeTypes">MIME_TYPES:</td>
608                    <td><table width="100%" class="mime-types">
609                      <tr class="header">
610                        <td i18n-content="pluginMimeTypesMimeType"
611                            >MIME type</td>
612                        <td i18n-content="pluginMimeTypesDescription"
613                            >DESCRIPTION</td>
614                        <td i18n-content="pluginMimeTypesFileExtensions"
615                            >FILE_EXTENSIONS</td>
616                      </tr>
617                      <tr jsselect="mimeTypes">
618                        <td><span dir="ltr"
619                                  jscontent="mimeType"></span></td>
620                        <td><span dir="ltr"
621                                  jsvalues=".innerHTML:description"></span></td>
622                        <td><table jsdisplay="fileExtensions.length > 0"
623                                   class="hlisting">
624                          <tr><td jsselect="fileExtensions">
625                            <span dir="ltr" jscontent="'.' + $this">
626                          </td></tr>
627                        </table></td>
628                      </tr>
629                    </table></td>
630                  </tr></table>
631                </div>
632              </div>
633            </div>
634          </div>
635          <div class="plugin-actions">
636            <span>
637              <a
638                jsvalues=".path:name"
639                jsdisplay="enabledMode == 'enabledByUser'"
640                onclick="handleEnablePlugin(this, false, true)"
641                href="javascript:void(0);"
642                i18n-content="disable"
643                >DISABLE</a>
644              <a
645                jsvalues=".path:name"
646                jsdisplay="enabledMode == 'disabledByUser'"
647                onclick="handleEnablePlugin(this, true, true)"
648                href="javascript:void(0);"
649                i18n-content="enable"
650                >ENABLE</a>
651              <span
652                jsdisplay="enabledMode == 'enabledByPolicy'"
653                i18n-content="pluginCannotBeDisabledDueToPolicy"
654                >CANNOT_DISABLE</span>
655              <span
656                jsdisplay="enabledMode == 'disabledByPolicy'"
657                i18n-content="pluginCannotBeEnabledDueToPolicy"
658                >CANNOT_ENABLE</span>
659            </span>
660          </div>
661        </td>
662        </tr>
663        </table>
664      </div>
665      </div>
666    </div>
667  </div>
668</div>
669</body>
670</html>
671