1<!DOCTYPE HTML> 2<html i18n-values="dir:textdirection;"> 3<head> 4<meta charset="utf-8"> 5<style> 6body { 7 margin: 10px; 8 min-width: 47em; 9} 10 11a { 12 color: blue; 13 font-size: 103%; 14} 15 16div#header { 17 margin-bottom: 1.05em; 18 /* 67px is the height of the header's background image. */ 19 min-height: 67px; 20 overflow: hidden; 21 padding-bottom: 20px; 22 padding-left: 0; 23 padding-top: 20px; 24 position: relative; 25 box-sizing: border-box; 26} 27 28html[dir=rtl] #header { 29 padding-right: 0; 30} 31 32#header h1 { 33 background: url('/app/theme/flags_section.png') 0px 20px no-repeat; 34 display: inline; 35 margin: 0; 36 padding-bottom: 43px; 37 padding-left: 75px; 38 padding-top: 40px; 39} 40 41html[dir=rtl] #header h1 { 42 background: url('/app/theme/flags_section.png') right no-repeat; 43 padding-right: 95px; 44 padding-left: 0; 45} 46 47h1 { 48 font-size: 156%; 49 font-weight: bold; 50 padding: 0; 51 margin: 0; 52} 53 54#blurb-container { 55 padding-bottom: 1.5em; 56 font-size: 120%; 57} 58 59#blurb-warning { 60 color: red; 61 font-weight: bold; 62} 63 64div.content { 65 font-size: 88%; 66 margin-top: 5px; 67} 68 69.section-header { 70 background: #ebeff9; 71 border-top: 1px solid #b5c7de; 72 font-size: 99%; 73 padding-bottom: 2px; 74 padding-left: 5px; 75 padding-top: 3px; 76 width: 100%; 77} 78 79html[dir=rtl] .section-header { 80 padding-right: 5px; 81 padding-left: 0; 82} 83 84.section-header > table tr td:first-child { 85 width: 100%; 86} 87 88.section-header > table { 89 width: 100%; 90} 91 92.section-header-title { 93 font-weight: bold; 94} 95 96.vbox-container { 97 display: -webkit-box; 98 -webkit-box-orient: vertical; 99} 100 101.wbox { 102 display: -webkit-box; 103 -webkit-box-align: stretch; 104 -webkit-box-flex: 1; 105} 106 107#top { 108 padding-right: 5px; 109} 110 111html[dir=rtl] #top { 112 padding-left: 5px; 113 padding-right: 0; 114} 115 116/* Disabled experiments display grey text on a grey background. The title, 117 however, should remain completely legible. */ 118.experiment-disabled > td { 119 background: #F0F0F0; 120 color: #A0A0A0; 121} 122 123.experiment-disabled .experiment-name { 124 color: #000; 125} 126 127.experiment { 128 border-bottom: 1px solid #cdcdcd; 129} 130 131.experiment td { 132 padding-bottom: 4px; 133 padding-top: 5px; 134} 135 136/* Indent the text related to each experiment. */ 137.experiment-text { 138 padding-left: 5px; 139} 140 141html[dir=rtl] .experiment-text { 142 padding-right: 5px; 143 padding-left: 0; 144} 145 146.experiment-name { 147 font-weight: bold; 148} 149 150.no-experiments { 151 margin: 6em 0 0; 152 text-align: center; 153 font-size: 1.2em; 154} 155 156/* Match the indentation of .experiment-text. */ 157.experiment-actions { 158 padding-left: 5px; 159 margin-top: 0.2em; 160 margin-bottom: 0.2em; 161} 162 163html[dir=rtl] .experiment-actions { 164 padding-right: 5px; 165 padding-left: 0; 166} 167 168div.needs-restart { 169 padding-top: 10px; 170 padding-left: 5px; 171} 172 173button { 174 font-size: 104%; 175} 176 177</style> 178<script> 179 180/** 181 * This variable structure is here to document the structure that the template 182 * expects to correctly populate the page. 183 */ 184var flagsExperimentsDataFormat = { 185 'flagsExperiments': [ 186 { 187 'internal_name': 'Experiment ID string', 188 'name': 'Experiment Name', 189 'description': 'description', 190 /* enabled is only set if the experiment is single valued */ 191 'enabled': true, 192 /* choices is only set if the experiment has multiple values */ 193 'choices': [ 194 { 195 'internal_name': 'Experiment ID string', 196 'description': 'description', 197 'selected': true 198 } 199 ] 200 } 201 ], 202 'needsRestart': false 203}; 204 205/** 206 * Takes the |flagsExperimentsData| input argument which represents data about 207 * the currently available experiments and populates the html jstemplate 208 * with that data. It expects an object structure like the above. 209 * @param {Object} flagsExperimentsData Information about available experiments 210 */ 211function renderTemplate(flagsExperimentsData) { 212 // This is the javascript code that processes the template: 213 var input = new JsEvalContext(flagsExperimentsData); 214 var output = document.getElementById('flagsExperimentTemplate'); 215 jstProcess(input, output); 216} 217 218/** 219 * Asks the C++ FlagsDOMHandler to get details about the available experiments 220 * and return detailed data about the configuration. The FlagsDOMHandler 221 * should reply to returnFlagsExperiments() (below). 222 */ 223function requestFlagsExperimentsData() { 224 chrome.send('requestFlagsExperiments', []); 225} 226 227/** 228 * Asks the C++ FlagsDOMHandler to restart the browser (restoring tabs). 229 */ 230function restartBrowser() { 231 chrome.send('restartBrowser', []); 232} 233 234/** 235 * Called by the WebUI to re-populate the page with data representing the 236 * current state of installed experiments. 237 */ 238function returnFlagsExperiments(flagsExperimentsData){ 239 var bodyContainer = document.getElementById('body-container'); 240 renderTemplate(flagsExperimentsData); 241 bodyContainer.style.visibility = 'visible'; 242} 243 244/** 245 * Handles a 'enable' or 'disable' button getting clicked. 246 */ 247function handleEnableExperiment(node, enable) { 248 // Tell the C++ FlagsDOMHandler to enable/disable the experiment. 249 chrome.send('enableFlagsExperiment', [String(node.internal_name), 250 String(enable)]); 251 requestFlagsExperimentsData(); 252} 253 254/** 255 * Invoked when the selection of a multi-value choice is changed to the 256 * specified index. 257 */ 258function handleSelectChoiceExperiment(node, index) { 259 // Tell the C++ FlagsDOMHandler to enable the selected choice. 260 chrome.send('enableFlagsExperiment', 261 [String(node.internal_name) + "@" + index, "true"]); 262 requestFlagsExperimentsData(); 263} 264 265// Get data and have it displayed upon loading. 266document.addEventListener('DOMContentLoaded', requestFlagsExperimentsData); 267 268</script> 269</head> 270<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> 271<div id="body-container" style="visibility:hidden"> 272 273 <div id="header"><h1 i18n-content="flagsLongTitle">TITLE</h1></div> 274 275 <div id="blurb-container"> 276 <span id="blurb-warning" i18n-content="flagsWarningHeader">WARNING</span> 277 <span i18n-content="flagsBlurb">WARNING TEXT</span> 278 </div> 279 280 <div id="flagsExperimentTemplate"> 281 282 <div id="container" class="vbox-container"> 283 <div id="top" class="wbox"> 284 285 <div class="section-header"> 286 <table cellpadding="0" cellspacing="0"><tr valign="center"> 287 <td> 288 <span class="section-header-title" i18n-content="flagsTableTitle" 289 >TITLE</span> 290 </td> 291 </tr></table> 292 </div> 293 294 </div> 295 </div> 296 297 <div class="content"> 298 <div class="experiment-name no-experiments" 299 jsdisplay="flagsExperiments.length === 0"> 300 <div i18n-content="flagsNoExperimentsAvailable" 301 >NO_EXPERIMENTS_ARE_AVAILABLE</div> 302 </div> 303 304 <div jsdisplay="flagsExperiments.length > 0"> 305 <div class="experiment" jsselect="flagsExperiments"> 306 <table width="100%" cellpadding="2" cellspacing="0"> 307 <!-- TODO(mkwst): This doesn't work exactly as expected for multivalue 308 experiments. See http://crbug.com/73730 --> 309 <tr jsvalues="class:enabled ? 'experiment-enabled' : 'experiment-disabled'"> 310 <td valign="top"> 311 <div class="experiment-text"> 312 <div> 313 <span class="experiment-name" dir="ltr" 314 jscontent="name">NAME</span> 315 <div> 316 <span dir="ltr" jsvalues=".innerHTML:description"> 317 </div> 318 <div jsdisplay="choices && choices.length > 0"> 319 <select jsvalues=".internal_name:internal_name;.disabled:!enabled" 320 onchange="handleSelectChoiceExperiment(this, this.selectedIndex)"> 321 <option jsvalues=".selected:selected" 322 jsselect="choices" 323 jscontent="description">NAME 324 </option> 325 </select> 326 </div> 327 </div> 328 </div> 329 <div class="experiment-actions"> 330 <!-- If enabled isn't set (i.e. in multi_type options), 331 then both jsdisplay tests fail, and we get no 332 rendering from this section. --> 333 <span> 334 <a 335 jsvalues=".internal_name:internal_name" 336 jsdisplay="enabled" 337 onclick="handleEnableExperiment(this, false)" 338 href="javascript:void(0);" 339 i18n-content="disable" 340 >DISABLE</a> 341 <a 342 jsvalues=".internal_name:internal_name" 343 jsdisplay="!enabled" 344 onclick="handleEnableExperiment(this, true)" 345 href="javascript:void(0);" 346 i18n-content="enable" 347 >ENABLE</a> 348 </span> 349 </div> 350 </td> 351 </tr> 352 </table> 353 </div> 354 </div> 355 356 <div class="needs-restart" jsdisplay="needsRestart"> 357 <div i18n-content="flagsRestartNotice">NEEDS_RESTART</div> 358 <button type="button" 359 onclick="restartBrowser();" 360 i18n-content="flagsRestartButton">RESTART</button> 361 </div> 362 </div> 363 </div> 364</div> 365</body> 366</html> 367