| <!DOCTYPE HTML> |
| <html i18n-values="dir:textdirection;"> |
| <head> |
| <meta charset="utf-8"> |
| <title i18n-content="pluginsTitle"></title> |
| <style> |
| body { |
| margin: 10px; |
| min-width: 47em; |
| } |
| |
| a { |
| color: blue; |
| font-size: 103%; |
| } |
| |
| div#header { |
| margin-bottom: 1.05em; |
| /* 67px is the height of the header's background image. */ |
| min-height: 67px; |
| overflow: hidden; |
| padding-bottom: 20px; |
| -webkit-padding-start: 0; |
| padding-top: 20px; |
| position: relative; |
| box-sizing: border-box; |
| } |
| |
| #header h1 { |
| background: url('../../app/theme/extensions_section.png') 0px 20px no-repeat; |
| display: inline; |
| margin: 0; |
| padding-bottom: 43px; |
| padding-left: 75px; |
| padding-top: 40px; |
| } |
| |
| html[dir=rtl] #header h1 { |
| background: url('../../app/theme/extensions_section.png') right no-repeat; |
| padding-right: 95px; |
| padding-left: 0; |
| } |
| |
| h1 { |
| font-size: 156%; |
| font-weight: bold; |
| padding: 0; |
| margin: 0; |
| } |
| |
| div.content { |
| font-size: 88%; |
| margin-top: 5px; |
| } |
| |
| .section-header { |
| background: #ebeff9; |
| border-top: 1px solid #b5c7de; |
| font-size: 99%; |
| padding-bottom: 2px; |
| -webkit-padding-start: 5px; |
| padding-top: 3px; |
| width: 100%; |
| } |
| |
| .section-header > table tr td:first-child { |
| width: 100%; |
| } |
| |
| .section-header > table { |
| width: 100%; |
| } |
| |
| .section-header-title { |
| font-weight: bold; |
| } |
| |
| .vbox-container { |
| display: -webkit-box; |
| -webkit-box-orient: vertical; |
| } |
| |
| .wbox { |
| display: -webkit-box; |
| -webkit-box-align: stretch; |
| -webkit-box-flex: 1; |
| } |
| |
| #top { |
| -webkit-padding-end: 5px; |
| } |
| |
| .showInTmiMode { |
| overflow: hidden; |
| } |
| |
| body.hideTmiModeInitial .showInTmiMode { |
| height: 0 !important; |
| opacity: 0; |
| } |
| |
| body.hideTmiMode .showInTmiMode { |
| height: 0 !important; |
| opacity: 0; |
| -webkit-transition: all .1s ease-out; |
| } |
| |
| body.showTmiModeInitial .showInTmiMode { |
| opacity: 1; |
| } |
| |
| body.showTmiMode .showInTmiMode { |
| opacity: 1; |
| -webkit-transition: all .1s ease-in; |
| } |
| |
| .wbox-tmi-mode { |
| -webkit-box-align: stretch; |
| -webkit-box-flex: 1; |
| } |
| |
| .tmi-mode-image { |
| margin-top: 2px; |
| padding-left: 5px; |
| padding-right: 5px; |
| } |
| |
| .tmi-mode-link { |
| margin-right: 3px; |
| white-space: nowrap; |
| } |
| |
| .tmi-mode-link a { |
| font-size: 97%; |
| } |
| |
| .tmi-mode { |
| background: #f4f6fc; |
| border-bottom: 1px solid #edeff5; |
| font-size: 89%; |
| padding-bottom: 0.8em; |
| -webkit-padding-start: 10px; |
| padding-top: 0.8em; |
| width: 100%; |
| } |
| |
| .plugin-disabled > td { |
| background-color: #f0f0f0; |
| color: #a0a0a0; |
| padding-bottom: 4px; |
| padding-top: 5px; |
| } |
| |
| .plugin-enabled > td { |
| padding-bottom: 4px; |
| padding-top: 5px; |
| } |
| |
| .plugin-file-disabled { |
| background-color: #f0f0f0; |
| color: #a0a0a0; |
| padding-top: 5px; |
| padding-bottom: 5px; |
| } |
| |
| .plugin-file-enabled { |
| padding-top: 5px; |
| padding-bottom: 5px; |
| } |
| |
| .plugin { |
| border-bottom: 1px solid #cdcdcd; |
| } |
| |
| .critical { |
| color: red; |
| } |
| |
| /* Indent the text related to each plug-in. */ |
| .plugin-text { |
| -webkit-padding-start: 5px; |
| } |
| |
| .plugin-name { |
| font-weight: bold; |
| } |
| |
| .no-plugins { |
| margin: 6em 0 0; |
| text-align: center; |
| font-size: 1.2em; |
| } |
| |
| /* Use tables for layout, so eliminate extra spacing. */ |
| .plugin-details table { |
| -webkit-border-horizontal-spacing: 0; |
| -webkit-border-vertical-spacing: 0; |
| } |
| |
| .plugin-details { |
| -webkit-padding-start: 1em; |
| } |
| |
| /* Separate the inital line, Description, Location, and MIME Types lines. */ |
| .plugin-details > div { |
| padding-top: 0.1em |
| } |
| |
| /* Align rows of tables along the top. */ |
| .plugin-details tr { |
| vertical-align: top; |
| } |
| |
| /* Separate columns by 1em for the most part. */ |
| .plugin-details td+td { |
| -webkit-padding-start: 1em; |
| } |
| |
| /* Make the MIME Types tables smaller. */ |
| .plugin-details .mime-types { |
| font-size: 95%; |
| } |
| |
| /* Separate the header from the contents in each MIME Types table. */ |
| .plugin-details .mime-types .header td { |
| padding-bottom: 0.1em; |
| border-bottom: 1px solid; |
| } |
| |
| /* Separate the columns for tables used for horizontal listings only a bit. */ |
| .hlisting td+td { |
| -webkit-padding-start: 0.4em; |
| } |
| |
| /* Match the indentation of .plugin-text. */ |
| .plugin-actions { |
| -webkit-padding-start: 5px; |
| margin-top: 0.2em; |
| margin-bottom: 0.2em; |
| } |
| |
| button { |
| font-size: 104%; |
| } |
| |
| </style> |
| <script> |
| |
| /** |
| * This variable structure is here to document the structure that the template |
| * expects to correctly populate the page. |
| */ |
| var pluginDataFormat = { |
| 'plugins': [ |
| { |
| 'name': 'Group Name', |
| 'description': 'description', |
| 'version': 'version', |
| 'update_url': 'http://update/', |
| 'critical': true, |
| 'enabled': true, |
| 'plugin_files': [ |
| { |
| 'path': '/blahblah/blahblah/MyCrappyPlugin.plugin', |
| 'name': 'MyCrappyPlugin', |
| 'version': '1.2.3', |
| 'description': 'My crappy plugin', |
| 'mimeTypes': [ |
| { 'description': 'Foo Media', |
| 'fileExtensions': [ 'foo' ], |
| 'mimeType': 'application/x-my-foo' }, |
| { 'description': 'Bar Stuff', |
| 'fileExtensions': [ 'bar','baz' ], |
| 'mimeType': 'application/my-bar' } |
| ], |
| 'enabledMode': 'enabledByUser' |
| }, |
| { |
| 'path': '/tmp/MyFirst.plugin', |
| 'name': 'MyFirstPlugin', |
| 'version': '3.14r15926', |
| 'description': 'My first plugin', |
| 'mimeTypes': [ |
| { 'description': 'New Guy Media', |
| 'fileExtensions': [ 'mfp' ], |
| 'mimeType': 'application/x-my-first' } |
| ], |
| 'enabledMode': 'enabledByPolicy' |
| }, |
| { |
| 'path': '/foobar/baz/YourGreatPlugin.plugin', |
| 'name': 'YourGreatPlugin', |
| 'version': '4.5', |
| 'description': 'Your great plugin', |
| 'mimeTypes': [ |
| { 'description': 'Baz Stuff', |
| 'fileExtensions': [ 'baz' ], |
| 'mimeType': 'application/x-your-baz' } |
| ], |
| 'enabledMode': 'disabledByUser' |
| }, |
| { |
| 'path': '/foobiz/bar/HisGreatPlugin.plugin', |
| 'name': 'HisGreatPlugin', |
| 'version': '1.2', |
| 'description': 'His great plugin', |
| 'mimeTypes': [ |
| { 'description': 'More baz Stuff', |
| 'fileExtensions': [ 'bor' ], |
| 'mimeType': 'application/x-his-bor' } |
| ], |
| 'enabledMode': 'disabledByPolicy' |
| } |
| ] |
| } |
| ] |
| }; |
| |
| /** |
| * Takes the |pluginsData| input argument which represents data about the |
| * currently installed/running plugins and populates the html jstemplate with |
| * that data. It expects an object structure like the above. |
| * @param {Object} pluginsData Detailed info about installed plugins |
| */ |
| function renderTemplate(pluginsData) { |
| // This is the javascript code that processes the template: |
| var input = new JsEvalContext(pluginsData); |
| var output = document.getElementById('pluginTemplate'); |
| jstProcess(input, output); |
| } |
| |
| /** |
| * Asks the C++ PluginsDOMHandler to get details about the installed plugins and |
| * return detailed data about the configuration. The PluginsDOMHandler should |
| * reply to returnPluginsData() (below). |
| */ |
| function requestPluginsData() { |
| chrome.send('requestPluginsData', []); |
| chrome.send('getShowDetails', []); |
| } |
| |
| function loadShowDetailsFromPrefs(show_details) { |
| tmiModeExpanded = show_details; |
| document.getElementById('collapse').style.display = |
| show_details ? 'inline' : 'none'; |
| document.getElementById('expand').style.display = |
| show_details ? 'none' : 'inline'; |
| |
| document.body.className = |
| show_details ? 'showTmiMode' : 'hideTmiMode'; |
| } |
| |
| /** |
| * Asks the C++ PluginsDOMHandler to show the terms of service (about:terms). |
| */ |
| function showTermsOfService() { |
| chrome.send('showTermsOfService', []); |
| } |
| |
| /** |
| * Called by the web_ui_ to re-populate the page with data representing the |
| * current state of installed plugins. |
| */ |
| function returnPluginsData(pluginsData){ |
| var bodyContainer = document.getElementById('body-container'); |
| var body = document.body; |
| |
| // Set all page content to be visible so we can measure heights. |
| bodyContainer.style.visibility = 'hidden'; |
| body.className = ''; |
| var slidables = document.getElementsByClassName('showInTmiMode'); |
| for (var i = 0; i < slidables.length; i++) |
| slidables[i].style.height = 'auto'; |
| |
| renderTemplate(pluginsData); |
| |
| // Make sure the left column (with "Description:", "Location:", etc.) is the |
| // same size for all plugins. |
| var labels = document.getElementsByClassName('plugin-details-label'); |
| var maxLabelWidth = 0; |
| for (var i = 0; i < labels.length; i++) |
| labels[i].style.width = 'auto'; |
| for (var i = 0; i < labels.length; i++) |
| maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth); |
| for (var i = 0; i < labels.length; i++) |
| labels[i].style.width = maxLabelWidth + 'px'; |
| |
| // Explicitly set the height for each element that wants to be "slid" in and |
| // out when the tmiModeExpanded is toggled. |
| var slidables = document.getElementsByClassName('showInTmiMode'); |
| for (var i = 0; i < slidables.length; i++) |
| slidables[i].style.height = slidables[i].offsetHeight + 'px'; |
| |
| // Reset visibility of page based on the current tmi mode. |
| document.getElementById('collapse').style.display = |
| tmiModeExpanded ? 'inline' : 'none'; |
| document.getElementById('expand').style.display = |
| tmiModeExpanded ? 'none' : 'inline'; |
| bodyContainer.style.visibility = 'visible'; |
| body.className = tmiModeExpanded ? |
| 'showTmiModeInitial' : 'hideTmiModeInitial'; |
| } |
| |
| /** |
| * Handles a 'enable' or 'disable' button getting clicked. |
| */ |
| function handleEnablePlugin(node, enable, isGroup) { |
| // Tell the C++ PluginsDOMHandler to enable/disable the plugin. |
| chrome.send('enablePlugin', [String(node.path), String(enable), |
| String(isGroup)]); |
| } |
| |
| // Keeps track of whether details have been made visible (expanded) or not. |
| var tmiModeExpanded = false; |
| |
| /* |
| * Toggles visibility of details. |
| */ |
| function toggleTmiMode() { |
| tmiModeExpanded = !tmiModeExpanded; |
| |
| document.getElementById('collapse').style.display = |
| tmiModeExpanded ? 'inline' : 'none'; |
| document.getElementById('expand').style.display = |
| tmiModeExpanded ? 'none' : 'inline'; |
| |
| document.body.className = |
| tmiModeExpanded ? 'showTmiMode' : 'hideTmiMode'; |
| |
| chrome.send('saveShowDetailsToPrefs', [String(tmiModeExpanded)]); |
| } |
| |
| /** |
| * Determines whether a plugin's version should be displayed. |
| */ |
| function shouldDisplayPluginVersion(plugin) { |
| return !!plugin.version && plugin.version != '0'; |
| } |
| |
| /** |
| * Determines whether a plugin's description should be displayed. |
| */ |
| function shouldDisplayPluginDescription(plugin) { |
| // Only display the description if it's not blank and if it's not just the |
| // name, version, or combination thereof. |
| return plugin.description && |
| plugin.description != plugin.name && |
| plugin.description != plugin.version && |
| plugin.description != 'Version ' + plugin.version && |
| plugin.description != plugin.name + ' ' + plugin.version; |
| } |
| |
| /** |
| * Determines whether a plugin is enabled or not. |
| */ |
| function isPluginEnabled(plugin) { |
| return plugin.enabledMode == 'enabledByUser' || |
| plugin.enabledMode == 'enabledByPolicy'; |
| } |
| |
| // Unfortunately, we don't have notifications for plugin (list) status changes |
| // (yet), so in the meanwhile just update regularly. |
| setInterval(requestPluginsData, 30000); |
| |
| // Get data and have it displayed upon loading. |
| document.addEventListener('DOMContentLoaded', requestPluginsData); |
| |
| </script> |
| </head> |
| <body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> |
| <div id="body-container" style="visibility:hidden"> |
| |
| <div id="header"><h1 i18n-content="pluginsTitle">TITLE</h1></div> |
| |
| <div id="pluginTemplate"> |
| |
| <div id="container" class="vbox-container"> |
| <div id="top" class="wbox"> |
| |
| <div class="section-header"> |
| <table cellpadding="0" cellspacing="0"><tr valign="center"> |
| <td> |
| <span class="section-header-title" i18n-content="pluginsTitle" |
| >TITLE</span> |
| <span class="section-header-title" |
| jsdisplay="plugins.length > 0">(<span |
| jscontent="plugins.length"></span>)</span> |
| </td> |
| <td width="18"> |
| <img id="collapse" class="tmi-mode-image" |
| style="display:none" onclick="toggleTmiMode();" |
| src="shared/images/minus.png"> |
| <img id="expand" class="tmi-mode-image" |
| onclick="toggleTmiMode();" src="shared/images/plus.png"> |
| </td> |
| <td> |
| <div class="tmi-mode-link"> |
| <a onclick="toggleTmiMode();" style="cursor: default" |
| i18n-content="pluginsDetailsModeLink">DETAILS</a> |
| </div> |
| </td> |
| </tr></table> |
| </div> |
| |
| </div> |
| </div> |
| |
| <div class="content"> |
| <div class="plugin-name no-plugins" jsdisplay="plugins.length === 0"> |
| <div i18n-content="noPlugins">NO_PLUGINS_ARE_INSTALLED</div> |
| </div> |
| |
| <div jsdisplay="plugins.length > 0"> |
| <div class="plugin" jsselect="plugins"> |
| <table width="100%" cellpadding="2" cellspacing="0"> |
| <tr jsvalues= |
| ".className:isPluginEnabled($this) ? 'plugin-enabled' : 'plugin-disabled'"> |
| <td valign="top"> |
| <div class="plugin-text"> |
| <div> |
| <span class="plugin-name" dir="ltr" |
| jscontent="name">NAME</span> |
| <span jsdisplay="plugin_files.length > 1" |
| jscontent="'(' + plugin_files.length +' files)'">(x)</span> |
| <span jsdisplay="shouldDisplayPluginVersion($this)"> |
| - <span i18n-content="pluginVersion">VERSION</span> |
| <span jsvalues=".className:critical? 'critical': ''" |
| dir="ltr" jscontent="version">x.x.x.x</span> |
| </span> |
| <a jsdisplay="critical" jsvalues=".href:update_url" |
| i18n-content="pluginDownload">DOWNLOAD UPDATE</a> |
| <span jsdisplay="enabledMode == 'disabledByUser'" |
| i18n-content="pluginDisabled">(DISABLED)</span> |
| <span jsdisplay="enabledMode == 'disabledByPolicy'" |
| i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span> |
| <span jsdisplay="enabledMode == 'enabledByPolicy'" |
| i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span> |
| <div jsdisplay="shouldDisplayPluginDescription($this)"> |
| <span dir="ltr" jsvalues=".innerHTML:description"> |
| </div> |
| </div> |
| <div jsselect="plugin_files" class="plugin-details"> |
| <div class="showInTmiMode"> |
| <div jsvalues= |
| ".className:isPluginEnabled($this) ? 'plugin-file-enabled' : 'plugin-file-disabled'"> |
| <div><table><tr> |
| <td class="plugin-details-label" |
| i18n-content="pluginName">NAME:</td> |
| <td><span dir="ltr" jscontent="name">NAME</span></td> |
| </tr></table></div> |
| <div><table> |
| <tr jsdisplay="shouldDisplayPluginDescription($this)"> |
| <td class="plugin-details-label" |
| i18n-content="pluginDescription">DESCRIPTION:</td> |
| <td> |
| <span dir="ltr" jsvalues=".innerHTML:description"> |
| </td> |
| </tr> |
| </table></div> |
| <div><table><tr> |
| <td class="plugin-details-label" |
| i18n-content="pluginVersion">VERSION:</td> |
| <td><span dir="ltr" jscontent="version">x.x.x.x</span></td> |
| </tr></table></div> |
| <div><table><tr> |
| <td class="plugin-details-label" |
| i18n-content="pluginPath">PATH:</td> |
| <td><span dir="ltr" jscontent="path"></span></td> |
| </tr></table></div> |
| <div><table><tr> |
| <td class="plugin-details-label"> </td> |
| <td> |
| <span jsdisplay="enabledMode == 'disabledByUser'" |
| i18n-content="pluginDisabled">(DISABLED)</span> |
| <span jsdisplay="enabledMode == 'disabledByPolicy'" |
| i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span> |
| <span jsdisplay="enabledMode == 'enabledByPolicy'" |
| i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span> |
| <span> |
| <a |
| jsvalues=".path:path" |
| jsdisplay="enabledMode == 'enabledByUser'" |
| onclick="handleEnablePlugin(this, false, false)" |
| href="javascript:void(0);" |
| i18n-content="disable" |
| >DISABLE</a> |
| <a |
| jsvalues=".path:path" |
| jsdisplay="enabledMode == 'disabledByUser'" |
| onclick="handleEnablePlugin(this, true, false)" |
| href="javascript:void(0);" |
| i18n-content="enable" |
| >ENABLE</a> |
| <span |
| jsdisplay="enabledMode == 'enabledByPolicy'" |
| i18n-content="pluginCannotBeDisabledDueToPolicy" |
| >CANNOT_DISABLE</span> |
| <span |
| jsdisplay="enabledMode == 'disabledByPolicy'" |
| i18n-content="pluginCannotBeEnabledDueToPolicy" |
| >CANNOT_ENABLE</span> |
| </span> |
| </td> |
| </tr></table></div> |
| <table><tr jsdisplay="mimeTypes.length > 0"> |
| <td class="plugin-details-label" |
| i18n-content="pluginMimeTypes">MIME_TYPES:</td> |
| <td><table width="100%" class="mime-types"> |
| <tr class="header"> |
| <td i18n-content="pluginMimeTypesMimeType" |
| >MIME type</td> |
| <td i18n-content="pluginMimeTypesDescription" |
| >DESCRIPTION</td> |
| <td i18n-content="pluginMimeTypesFileExtensions" |
| >FILE_EXTENSIONS</td> |
| </tr> |
| <tr jsselect="mimeTypes"> |
| <td><span dir="ltr" |
| jscontent="mimeType"></span></td> |
| <td><span dir="ltr" |
| jsvalues=".innerHTML:description"></span></td> |
| <td><table jsdisplay="fileExtensions.length > 0" |
| class="hlisting"> |
| <tr><td jsselect="fileExtensions"> |
| <span dir="ltr" jscontent="'.' + $this"> |
| </td></tr> |
| </table></td> |
| </tr> |
| </table></td> |
| </tr></table> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="plugin-actions"> |
| <span> |
| <a |
| jsvalues=".path:name" |
| jsdisplay="enabledMode == 'enabledByUser'" |
| onclick="handleEnablePlugin(this, false, true)" |
| href="javascript:void(0);" |
| i18n-content="disable" |
| >DISABLE</a> |
| <a |
| jsvalues=".path:name" |
| jsdisplay="enabledMode == 'disabledByUser'" |
| onclick="handleEnablePlugin(this, true, true)" |
| href="javascript:void(0);" |
| i18n-content="enable" |
| >ENABLE</a> |
| <span |
| jsdisplay="enabledMode == 'enabledByPolicy'" |
| i18n-content="pluginCannotBeDisabledDueToPolicy" |
| >CANNOT_DISABLE</span> |
| <span |
| jsdisplay="enabledMode == 'disabledByPolicy'" |
| i18n-content="pluginCannotBeEnabledDueToPolicy" |
| >CANNOT_ENABLE</span> |
| </span> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </body> |
| </html> |