| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Takes the |pluginsData| input argument which represents data about the | |
| 7 * currently installed/running plugins and populates the html jstemplate with | |
| 8 * that data. | |
| 9 * @param {Object} pluginsData Detailed info about installed plugins. Same | |
| 10 * expected format as returnPluginsData(). | |
| 11 */ | |
| 12 function renderTemplate(pluginsData) { | |
| 13 // This is the javascript code that processes the template: | |
| 14 var input = new JsEvalContext(pluginsData); | |
| 15 var output = $('pluginTemplate'); | |
| 16 jstProcess(input, output); | |
| 17 } | |
| 18 | |
| 19 // Keeps track of whether details have been made visible (expanded) or not. | |
| 20 var tmiModeExpanded = false; | |
| 21 | |
| 22 /** | |
| 23 * @param {boolean} showDetails | |
| 24 */ | |
| 25 function loadShowDetailsFromPrefs(showDetails) { | |
| 26 tmiModeExpanded = showDetails; | |
| 27 // TODO(dpapad): Use setAttribute()/removeAttribute() with 'hidden' instead of | |
| 28 // style.display. | |
| 29 $('collapse').style.display = showDetails ? 'inline' : 'none'; | |
| 30 $('expand').style.display = showDetails ? 'none' : 'inline'; | |
| 31 document.body.className = showDetails ? 'show-in-tmi-mode' : 'hide-tmi-mode'; | |
| 32 } | |
| 33 | |
| 34 /** | |
| 35 * Called by the web_ui_ to re-populate the page with data representing the | |
| 36 * current state of installed plugins. | |
| 37 * @param {Object} pluginsData Detailed info about installed plugins. The | |
| 38 * template expects each plugin's format to match the following structure to | |
| 39 * correctly populate the page: | |
| 40 * { | |
| 41 * plugins: [ | |
| 42 * { | |
| 43 * name: 'Group Name', | |
| 44 * description: 'description', | |
| 45 * version: 'version', | |
| 46 * update_url: 'http://update/', | |
| 47 * critical: true, | |
| 48 * enabled_mode: 'enabledByUser', | |
| 49 * id: 'plugin-name', | |
| 50 * always_allowed: false, | |
| 51 * plugin_files: [ | |
| 52 * { | |
| 53 * path: '/foo/bar/baz/MyPlugin.plugin', | |
| 54 * name: 'MyPlugin', | |
| 55 * version: '1.2,3' | |
| 56 * description: 'My plugin', | |
| 57 * type: 'BROWSER PLUGIN', | |
| 58 * mime_types: [ | |
| 59 * { | |
| 60 * description: 'Foo Media', | |
| 61 * file_extensions: ['pdf'], | |
| 62 * mime_type: 'application/x-my-foo' | |
| 63 * }, | |
| 64 * { | |
| 65 * description: 'Bar Stuff', | |
| 66 * file_extensions: ['bar', 'baz'], | |
| 67 * mime_type: 'application/my-bar' | |
| 68 * } | |
| 69 * ], | |
| 70 * enabled_mode: 'enabledByUser', | |
| 71 * }, | |
| 72 * { | |
| 73 * path: '/tmp/MyFirst.plugin', | |
| 74 * name: 'MyFirstPlugin', | |
| 75 * version: '3.14r15926', | |
| 76 * description: 'My first plugin', | |
| 77 * type: 'BROWSER PLUGIN', | |
| 78 * mime_types: [ | |
| 79 * { | |
| 80 * description: 'New Media Type', | |
| 81 * file_extensions: ['mfp'], | |
| 82 * mime_type: 'application/x-my-first' | |
| 83 * }, | |
| 84 * ], | |
| 85 * enabled_mode: 'disabledByUser', | |
| 86 * }, | |
| 87 * ], | |
| 88 * }, | |
| 89 * ], | |
| 90 * } | |
| 91 */ | |
| 92 function returnPluginsData(pluginsData) { | |
| 93 var bodyContainer = $('body-container'); | |
| 94 var body = document.body; | |
| 95 | |
| 96 // Set all page content to be visible so we can measure heights. | |
| 97 bodyContainer.style.visibility = 'hidden'; | |
| 98 body.className = ''; | |
| 99 var slidables = document.getElementsByClassName('show-in-tmi-mode'); | |
| 100 for (var i = 0; i < slidables.length; i++) | |
| 101 slidables[i].style.height = 'auto'; | |
| 102 | |
| 103 renderTemplate(pluginsData); | |
| 104 | |
| 105 // Add handlers to dynamically created HTML elements. | |
| 106 var checkboxes = document.getElementsByClassName('always-allow'); | |
| 107 for (var i = 0; i < checkboxes.length; i++) { | |
| 108 checkboxes[i].onclick = function() { | |
| 109 handleSetPluginAlwaysAllowed(this); | |
| 110 }; | |
| 111 } | |
| 112 | |
| 113 if (cr.isChromeOS) { | |
| 114 // Disable some controls for Guest in ChromeOS. | |
| 115 uiAccountTweaks.UIAccountTweaks.applyGuestSessionVisibility(document); | |
| 116 // Disable some controls for Public session in ChromeOS. | |
| 117 uiAccountTweaks.UIAccountTweaks.applyPublicSessionVisibility(document); | |
| 118 } | |
| 119 | |
| 120 // Make sure the left column (with "Description:", "Location:", etc.) is the | |
| 121 // same size for all plugins. | |
| 122 var labels = document.getElementsByClassName('plugin-details-label'); | |
| 123 var maxLabelWidth = 0; | |
| 124 for (var i = 0; i < labels.length; i++) | |
| 125 labels[i].style.width = 'auto'; | |
| 126 for (var i = 0; i < labels.length; i++) | |
| 127 maxLabelWidth = Math.max(maxLabelWidth, labels[i].offsetWidth); | |
| 128 for (var i = 0; i < labels.length; i++) | |
| 129 labels[i].style.width = maxLabelWidth + 'px'; | |
| 130 | |
| 131 // Explicitly set the height for each element that wants to be "slid" in and | |
| 132 // out when the tmiModeExpanded is toggled. | |
| 133 var slidables = document.getElementsByClassName('show-in-tmi-mode'); | |
| 134 for (var i = 0; i < slidables.length; i++) | |
| 135 slidables[i].style.height = slidables[i].offsetHeight + 'px'; | |
| 136 | |
| 137 // Reset visibility of page based on the current tmi mode. | |
| 138 $('collapse').style.display = | |
| 139 tmiModeExpanded ? 'inline' : 'none'; | |
| 140 $('expand').style.display = | |
| 141 tmiModeExpanded ? 'none' : 'inline'; | |
| 142 bodyContainer.style.visibility = 'visible'; | |
| 143 body.className = tmiModeExpanded ? | |
| 144 'show-tmi-mode-initial' : 'hide-tmi-mode-initial'; | |
| 145 } | |
| 146 | |
| 147 /* | |
| 148 * Toggles visibility of details. | |
| 149 */ | |
| 150 function toggleTmiMode() { | |
| 151 tmiModeExpanded = !tmiModeExpanded; | |
| 152 | |
| 153 $('collapse').style.display = | |
| 154 tmiModeExpanded ? 'inline' : 'none'; | |
| 155 $('expand').style.display = | |
| 156 tmiModeExpanded ? 'none' : 'inline'; | |
| 157 | |
| 158 document.body.className = | |
| 159 tmiModeExpanded ? 'show-tmi-mode' : 'hide-tmi-mode'; | |
| 160 | |
| 161 browserProxy.saveShowDetailsToPrefs(tmiModeExpanded); | |
| 162 } | |
| 163 | |
| 164 function handleSetPluginAlwaysAllowed(el) { | |
| 165 browserProxy.setPluginAlwaysAllowed(el.identifier, el.checked); | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * @param {Object} plugin An object containing the information about a plugin. | |
| 170 * See returnPluginsData() for the format of this object. | |
| 171 * @return {boolean} Whether the plugin's version should be displayed. | |
| 172 */ | |
| 173 function shouldDisplayPluginVersion(plugin) { | |
| 174 return !!plugin.version && plugin.version != '0'; | |
| 175 } | |
| 176 | |
| 177 /** | |
| 178 * @param {Object} plugin An object containing the information about a plugin. | |
| 179 * See returnPluginsData() for the format of this object. | |
| 180 * @return {boolean} Whether the plugin's description should be displayed. | |
| 181 */ | |
| 182 function shouldDisplayPluginDescription(plugin) { | |
| 183 // Only display the description if it's not blank and if it's not just the | |
| 184 // name, version, or combination thereof. | |
| 185 return plugin.description && | |
| 186 plugin.description != plugin.name && | |
| 187 plugin.description != plugin.version && | |
| 188 plugin.description != 'Version ' + plugin.version && | |
| 189 plugin.description != plugin.name + ' ' + plugin.version; | |
| 190 } | |
| 191 | |
| 192 /** | |
| 193 * @param {Object} plugin An object containing the information about a plugin. | |
| 194 * See returnPluginsData() for the format of this object. | |
| 195 * @return {boolean} Whether the plugin is enabled. | |
| 196 */ | |
| 197 function isPluginEnabled(plugin) { | |
| 198 return plugin.enabled_mode == 'enabledByUser' || | |
| 199 plugin.enabled_mode == 'enabledByPolicy'; | |
| 200 } | |
| 201 | |
| 202 /** | |
| 203 * @param {Object} plugin An object containing the information about a plugin. | |
| 204 * See returnPluginsData() for the format of this object. | |
| 205 * @return {boolean} Whether the plugin is fully trusted. | |
| 206 */ | |
| 207 function isPluginTrusted(plugin) { | |
| 208 return plugin.trusted == true; | |
| 209 } | |
| 210 | |
| 211 /** | |
| 212 * @param {Object} plugin An object containing the information about a plugin. | |
| 213 * See returnPluginsData() for the format of this object. | |
| 214 * @return {boolean} Whether the plugin is marked click to play by policy. | |
| 215 * | |
| 216 * This would normally be set by setting the policy DefaultPluginsSetting to 3. | |
| 217 */ | |
| 218 function isPluginPolicyClickToPlay(plugin) { | |
| 219 return plugin.policy_click_to_play == true; | |
| 220 } | |
| 221 | |
| 222 // NOTE: Need to keep a global reference to the |pageImpl| such that it is not | |
| 223 // garbage collected, which causes the pipe to close and future calls from C++ | |
| 224 // to JS to get dropped. This also allows tests to make direct calls on it. | |
| 225 var pageImpl = null; | |
| 226 var browserProxy = null; | |
| 227 | |
| 228 function initializeProxies() { | |
| 229 return importModules([ | |
| 230 'mojo/public/js/bindings', | |
| 231 'chrome/browser/ui/webui/plugins/plugins.mojom', | |
| 232 'content/public/renderer/frame_interfaces', | |
| 233 ]).then(function(modules) { | |
| 234 var bindings = modules[0]; | |
| 235 var pluginsMojom = modules[1]; | |
| 236 var frameInterfaces = modules[2]; | |
| 237 | |
| 238 browserProxy = new pluginsMojom.PluginsPageHandlerPtr( | |
| 239 frameInterfaces.getInterface(pluginsMojom.PluginsPageHandler.name)); | |
| 240 | |
| 241 /** @constructor */ | |
| 242 var PluginsPageImpl = function() { | |
| 243 this.binding = new bindings.Binding(pluginsMojom.PluginsPage, this); | |
| 244 }; | |
| 245 | |
| 246 PluginsPageImpl.prototype = { | |
| 247 /** @override */ | |
| 248 onPluginsUpdated: function(plugins) { | |
| 249 returnPluginsData({plugins: plugins}); | |
| 250 }, | |
| 251 }; | |
| 252 pageImpl = new PluginsPageImpl(); | |
| 253 browserProxy.setClientPage(pageImpl.binding.createInterfacePtrAndBind()); | |
| 254 }); | |
| 255 } | |
| 256 | |
| 257 /** | |
| 258 * Overriden by tests to give them a chance to setup a fake Mojo browser proxy | |
| 259 * before any other code executes. | |
| 260 * @return {!Promise} A promise firing once necessary setup has been completed. | |
| 261 */ | |
| 262 var setupFn = setupFn || function() { return Promise.resolve(); }; | |
| 263 | |
| 264 function main() { | |
| 265 setupFn().then(function() { | |
| 266 // Add handlers to static HTML elements. | |
| 267 $('collapse').onclick = toggleTmiMode; | |
| 268 $('expand').onclick = toggleTmiMode; | |
| 269 $('details-link').onclick = toggleTmiMode; | |
| 270 return initializeProxies(); | |
| 271 }).then(function() { | |
| 272 return browserProxy.getShowDetails(); | |
| 273 }).then(function(response) { | |
| 274 // Set the |tmiModeExpanded| first otherwise the UI flickers when | |
| 275 // returnPlignsData executes. | |
| 276 loadShowDetailsFromPrefs(response.show_details); | |
| 277 return browserProxy.getPluginsData(); | |
| 278 }).then(function(pluginsData) { | |
| 279 returnPluginsData(pluginsData); | |
| 280 | |
| 281 // Unfortunately, we don't have notifications for plugin (list) status | |
| 282 // changes (yet), so in the meanwhile just update regularly. | |
| 283 setInterval(function() { | |
| 284 browserProxy.getPluginsData().then(returnPluginsData); | |
| 285 }, 30000); | |
| 286 }); | |
| 287 } | |
| 288 | |
| 289 document.addEventListener('DOMContentLoaded', main); | |
| OLD | NEW |