Home | History | Annotate | Download | only in resources
      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 
    669 
    670 
    671