1 <!DOCTYPE HTML>
2 <html i18n-values="dir:textdirection;">
3 <head>
4 <meta charset="utf-8">
5 <title i18n-content="pluginsTitle"></title>
6 <style>
7 body {
8 margin: 10px;
9 min-width: 47em;
10 }
11
12 a {
13 color: blue;
14 font-size: 103%;
15 }
16
17 div#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
38 html[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
44 h1 {
45 font-size: 156%;
46 font-weight: bold;
47 padding: 0;
48 margin: 0;
49 }
50
51 div.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
97 body.hideTmiModeInitial .showInTmiMode {
98 height: 0 !important;
99 opacity: 0;
100 }
101
102 body.hideTmiMode .showInTmiMode {
103 height: 0 !important;
104 opacity: 0;
105 -webkit-transition: all .1s ease-out;
106 }
107
108 body.showTmiModeInitial .showInTmiMode {
109 opacity: 1;
110 }
111
112 body.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
242 button {
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 */
253 var 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 */
325 function 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 */
337 function requestPluginsData() {
338 chrome.send('requestPluginsData', []);
339 chrome.send('getShowDetails', []);
340 }
341
342 function 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 */
356 function 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 */
364 function 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 */
407 function 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.
414 var tmiModeExpanded = false;
415
416 /*
417 * Toggles visibility of details.
418 */
419 function 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 */
436 function shouldDisplayPluginVersion(plugin) {
437 return !!plugin.version && plugin.version != '0';
438 }
439
440 /**
441 * Determines whether a plugin's description should be displayed.
442 */
443 function 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 */
456 function 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.
463 setInterval(requestPluginsData, 30000);
464
465 // Get data and have it displayed upon loading.
466 document.addEventListener('DOMContentLoaded', requestPluginsData);
467
468
469
470 .style.fontFamily:fontfamily;.style.fontSize:fontsize">
471
472
473
474
475
476
477
507
508
509 plugins.length === 0">
510 NO_PLUGINS_ARE_INSTALLED
511
512
513 plugins.length > 0">
514
515
516 517 ".className:isPluginEnabled($this) ? 'plugin-enabled' : 'plugin-disabled'">
518
519
520
521 522 jscontent="name">NAME
523 plugin_files.length > 1"
524 jscontent="'( ' + plugin_files.length +' files) '">(x)
525
526 - VERSION
527 critical': ''"
528 dir="ltr" jscontent="version">x.x.x.x
529
530 531 i18n-content="pluginDownload">DOWNLOAD UPDATE
532 disabledByUser'"
533 i18n-content="pluginDisabled">(DISABLED)
534 disabledByPolicy'"
535 i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)
536 enabledByPolicy'"
537 i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)
538
541
542
543
544 545 ".className:isPluginEnabled($this) ? ' plugin- file- enabled' : 'plugin- file- disabled'">
546
547 548 i18n-content="pluginName">NAME: |
549 NAME |
550
551
560
565
566 567 i18n-content="pluginPath">PATH: |
568 |
569
570
571 |
572
573 disabledByUser'"
574 i18n-content="pluginDisabled">(DISABLED)
575 disabledByPolicy'"
576 i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)
577 enabledByPolicy'"
578 i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)
579
580 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
587 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
594 595 jsdisplay="enabledMode == 'enabledByPolicy'"
596 i18n-content="pluginCannotBeDisabledDueToPolicy"
597 >CANNOT_DISABLE
598 599 jsdisplay="enabledMode == 'disabledByPolicy'"
600 i18n-content="pluginCannotBeEnabledDueToPolicy"
601 >CANNOT_ENABLE
602
603 |
604
605 mimeTypes.length > 0">
606 607 i18n-content="pluginMimeTypes">MIME_TYPES: |
608 |
630
631
632
633
634
635
636
637 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
644 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
651 652 jsdisplay="enabledMode == 'enabledByPolicy'"
653 i18n-content="pluginCannotBeDisabledDueToPolicy"
654 >CANNOT_DISABLE
655 656 jsdisplay="enabledMode == 'disabledByPolicy'"
657 i18n-content="pluginCannotBeEnabledDueToPolicy"
658 >CANNOT_ENABLE
659
660
661 |
662
663
664
665
666
667
668
669
670