<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[191853] trunk/PerformanceTests</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191853">191853</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-11-01 01:26:46 -0700 (Sun, 01 Nov 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make the size of the benchmark canvas adaptive to the screen size and screen resolution
https://bugs.webkit.org/show_bug.cgi?id=150530

Patch by Said Abou-Hallawa &lt;sabouhallawa@apple,com&gt; on 2015-11-01
Reviewed by Darin Adler.

We want to set the size of the benchmark stage dynamically such that it
depends on the screen resolution and the device scale factor. This patch
does more than that because the home page css was not done properly. To
use the flex box layout, the animometer.css has to be rewritten almost from
scratch. The suites tree has to be rewritten also because it was not collapsing
and with the flex box layout it was going outside of the window area. The
options handling and the local storage handling had to be rewritten to
allow more flexibility with this patch and the future patches. The code
in animometer.js was reorganized into objects to allow distributing the code
nicely among separate entities.

* Animometer/resources/extensions.js:
(Point.elementClientSize): Returns the client size of an HTMLElement as a Point object.
(Insets.prototype.get width): Follow the function opening brace style guidelines.
(Insets.prototype.get height):
(Insets.prototype.get size): Returns the size of an Insets as a Point object.

(window.DocumentExtension): Provides document helper functions. It should be assailable from the runner and the tests.
(window.DocumentExtension.createElement): Creates an HTMLElement given its name, attributes and parentElement.
(window.DocumentExtension.createSvgElement): Creates an SVGElement given its name, attributes and parentElement (moved from utilities.js).
(window.DocumentExtension.insertCssRuleAfter): Inserts a CSS rule after an exiting rule given its text.

(ResultsTable.prototype._showHeader): Use DocumentExtension functions.
(ResultsTable.prototype._showGraph): Use DocumentExtension functions and create a real button for &quot;Graph...&quot; option.
(ResultsTable.prototype._showJSON): Use DocumentExtension functions and create a real button for &quot;JSON...&quot; option.
(Options): Deleted.

* Animometer/runner/animometer.html: Restructure the page to use the flex box layout.

* Animometer/runner/resources/animometer.css:
(html,body):
(button):

(button.large-button):The large button appears in the animometer.html.
(button.large-button:active):
(button.large-button:disabled):

(button.small-button): The small button appears in the results table.
(button.small-button:active):

(.tree): The tree class is used to list the suites and their tests.
(.tree .expand-button): This button expands a tree element.
(.tree .expand-button ~ ul): Hide the children (&lt;ul&gt;...&lt;/ul&gt;) of a parent node by default.
(.tree .expand-button:checked ~ ul): Show the children of a parent node only when checked.
(.tree ul): Hide the list bullets.
(.tree li): Indent every node in the tree relative to its parent.
(.tree ul li): Indent all the non top level nodes only (the tests nodes in our case).
(.tree &gt; li:last-child): Do not indent the bottom of the last child node.
(.tree-label): Style for all the labels in the tree.
(label.tree-label): Style for the labels in the top level only (the suites nodes in our case).
(label.tree-label:before): Style the unchecked case of the expand-button.
(:checked ~ label.tree-label:before): Style the checked case of the expand-button.

(table.results-table): The results table appears while running the test and at the end.
(.results-table td):
(.results-table th):

(div.results-json): The JSON div appears per test or for the whole run.

(main): This is the flex box container.

(section): A section is displayed exclusively inside the &lt;main&gt;. It is hidden by default.
(section.selected): When it is selected, its layout is flex layout.
(section &gt; footer): The header or the footer of a section should not take more than 15% of the container.

(section#home): The home section has &lt;suites&gt; and &lt;options&gt; parts to be laid out in the middle.
(section#home &gt; options):
(section#home &gt; suites): The &lt;suites&gt; should not take more than 40% of the width.
(section#home &gt; options &gt; label): The benchmark title.
(section#home &gt; header &gt; h2): The benchmark title.
(section#home &gt; options &gt; label &gt; input[type=&quot;number&quot;]): Sets the width of the option edit control.

(section#running): The running section contain the runner &lt;iframe&gt; which takes the whole area of the &lt;main&gt;.
(section#running &gt; #running-test): This is the &lt;iframe&gt; container.
(section#running &gt; #running-test &gt; iframe): The &lt;iframe&gt; is created by the runner for each test.
(section#running &gt; #progress): This is the progress bar.
(section#running &gt; #progress &gt; #progress-completed): This is another element which grows while the runner is progressing.
(section#running &gt; #record): This the container of the record results table which is shown while running a test.

(section#results):
(section#json):
(section#test-json):
(section#test-graph): All these sections have the same layout. A &lt;data&gt; element is laid out between &lt;header&gt; and &lt;footer&gt;.

(section#results &gt; data):
(section#json &gt; data):
(section#test-json &gt; data):
(section#test-graph &gt; data): The &lt;data&gt; element should take 70% of the &lt;section&gt;.

(section#test-graph &gt; data &gt; svg):
(.axis line):
(.left-samples): These styles are for the d3 graph.

(section#test-json &gt; data): This is the style of the JSON &lt;data&gt; element.

(iframe): Deleted.
(label, p): Deleted.
(section &gt; p): Deleted.
(section#home &gt; p): Deleted.
(section#home &gt; p:first-child): Deleted.
(#testContainer): Deleted.
(section#running #progress-completed): Deleted.
(section#results &gt; table): Deleted.
(section#results &gt; table td, th): Deleted.
(section#results &gt; table tr.alt, td): Deleted.
(section#results &gt; table th): Deleted.
(section#json &gt; textarea): Deleted.
(.options): Deleted.
(.options p): Deleted.
(#suites ul): Deleted.
(#suites ul ul): Deleted.
(#suites ul ul input, #suites ul ul label): Deleted.
(#suites.showTests ul ul): Deleted.
(.column): Deleted.
(input[type=&quot;number&quot;]): Deleted.
(.buttons): Deleted.
(.small-button): Deleted.
(#graphContainer): Deleted.
(.right-samples): Deleted.
(.sample-time): Deleted.
(.left-mean): Deleted.
(.right-mean): Deleted.

* Animometer/runner/resources/animometer.js:
(window.benchmarkRunnerClient.initialize): Initialize the client object with the options and the suites.
(window.benchmarkRunnerClient.willStartFirstIteration): Use new css selectors for results and the record table.
(window.benchmarkRunnerClient.didFinishLastIteration): Move the code which sets the JSON text to sectionsManager.showJSON().

(window.sectionsManager): Responsible of managing the &lt;section&gt;s elements inside animometer.html.
(window.sectionsManager._sectionHeaderH1Element): Return the &lt;h1&gt; inside the &lt;header&gt; of a given section.
(window.sectionsManager._sectionDataDivElement): Return the &lt;div&gt; inside the &lt;data&gt; of a given section.
(window.sectionsManager.showScore): Show the score of the last benchmark run.
(window.sectionsManager.showTestName): Show the test name for detailed results &lt;section&gt;.
(window.sectionsManager.showJSON): Shows the JSON text of the last benchmark or for a specific test.
(window.sectionsManager.showSection): Shows a specific &lt;section&gt; in the &lt;main&gt; container.
(window.sectionsManager.setupSectionStyle): Sets css attributes for all the &lt;section&gt;s.
(window.sectionsManager.setupRunningSectionStyle): Sets the css attributes for the running &lt;section&gt; only.

(window.optionsManager): Responsible of managing the user options and streaming them to/form the localStorage.
(window.optionsManager._optionsElements): Returns the children &lt;input&gt; elements of the &lt;options&gt;.
(window.optionsManager.updateUIFromLocalStorage): Restore the values of the &lt;options&gt; UI elements from the local storage.
(window.optionsManager.updateLocalStorageFromUI): Saves the values of the &lt;options&gt; UI elements to the local storage.

(window.suitesManager): Responsible of managing the user suites and streaming them to/form the localStorage.
(window.suitesManager._treeElement): Returns the suites tree container element.
(window.suitesManager._suitesElements): Returns a list of the suites elements.
(window.suitesManager._checkboxElement): Returns the checkbox element of a given suite.
(window.suitesManager._localStorageNameForTest): Generates a string for the tuple &lt;suite, test&gt; to be saved in the localStorage.
(window.suitesManager._updateSuiteCheckboxState): Updates the state of a suite checkbox from the state of its tests' checkboxes.
(window.suitesManager._updateStartButtonState): Updates the state of the start button from the state of the suites' checkboxes.
(window.suitesManager._onChangeSuiteCheckbox): Called when a suite checkbox is clicked.
(window.suitesManager._onChangeTestCheckbox): Called when a test checkbox is clicked.
(window.suitesManager._createSuiteElement): Creates suite node in the suites tree.
(window.suitesManager._createTestElement): Creates test node in the suites tree.
(window.suitesManager.createElements): Creates the suites tree dynamically from the array Suites.
(window.suitesManager.updateUIFromLocalStorage): Restore the values of the &lt;suites&gt; UI elements from the local storage.
(window.suitesManager.updateLocalStorageFromUI): aves the values of the &lt;suites&gt; UI elements to the local storage.

(window.benchmarkController): This is the UI controller of the animometer.html page.
(window.benchmarkController.initialize): Called when the animometer.html page is loaded.
(window.benchmarkController._runBenchmark): Starts a benchmark run.
(window.benchmarkController.startTest): Called when the &quot;Start Test&quot; button is clicked.
(window.benchmarkController.showResults): Called at the end of the test to show the final results.
(window.benchmarkController.showJson): Called from the results page to show the JSON of the last benchmark run.
(window.benchmarkController.showTestGraph): Called from the results the table to show a graph for the samples of a specific test.
(window.benchmarkController.showTestJSON): Called from the results the table to show a JSON for the samples of a specific test.

(showSection): Deleted.
(startTest): Deleted.
(showResults): Deleted.
(showJson): Deleted.
(showTestGraph): Deleted.
(showTestJSON): Deleted.
(initialize.toggleTestsCheckbox.onchange): Deleted.
(initialize): Deleted.
(updateSuiteSelection): Deleted.
(updateTestSelection): Deleted.
(updateSuiteCheckbox): Deleted.
(localStorageNameForTest): Deleted.
(populateSettings.): Deleted.
(populateSettings): Deleted.

* Animometer/runner/resources/benchmark-runner.js:
(BenchmarkRunner): Pass the frameContainer element to the BenchmarkRunner.
(BenchmarkRunner.prototype._appendFrame): Remove unused parameter unwanted styling code.
(BenchmarkRunner.prototype.runMultipleIterations):  Use the this._client.iterationCount instead of passing it as a parameter also.

* Animometer/runner/resources/graph.js:
(graph): Calculate the size of the chart from the container element.

* Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js:
(BouncingSvgImage):
* Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js:
(BouncingSvgParticlesStage.prototype._createDefs):
(BouncingSvgParticlesStage.prototype._createClipStar):
* Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js:
(BouncingSvgShape.prototype._createShape):
(BouncingSvgShapesStage.prototype.createGradient):
Call DocumentExtension.createSvgElement() instead of calling Utilities.createSvgElement().

* Animometer/tests/resources/main.js:
(Animator.prototype.animate):
(Benchmark):
(Benchmark.prototype.update):
* Animometer/tests/resources/stage.js:
(StageBenchmark.prototype.showResults):
Rename the options to match the &lt;input&gt; ids in animometer.html.

* Animometer/tests/resources/utilities.js:
(window.Utilities.createSvgElement): Deleted.

* Animometer/tests/text/layering-text.html:
* Animometer/tests/text/resources/layering-text.js:
(LayeringTextStage):
(LayeringTextStage.prototype._setFontSize): Sets the size of the text dynamically such that they all fit in one stage.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsAnimometerresourcesextensionsjs">trunk/PerformanceTests/Animometer/resources/extensions.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunneranimometerhtml">trunk/PerformanceTests/Animometer/runner/animometer.html</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunnerresourcesanimometercss">trunk/PerformanceTests/Animometer/runner/resources/animometer.css</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunnerresourcesanimometerjs">trunk/PerformanceTests/Animometer/runner/resources/animometer.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunnerresourcesbenchmarkrunnerjs">trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometerrunnerresourcesgraphjs">trunk/PerformanceTests/Animometer/runner/resources/graph.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsbouncingparticlesresourcesbouncingsvgimagesjs">trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsbouncingparticlesresourcesbouncingsvgparticlesjs">trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsbouncingparticlesresourcesbouncingsvgshapesjs">trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsresourcesmainjs">trunk/PerformanceTests/Animometer/tests/resources/main.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsresourcesstagejs">trunk/PerformanceTests/Animometer/tests/resources/stage.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometertestsresourcesutilitiesjs">trunk/PerformanceTests/Animometer/tests/resources/utilities.js</a></li>
<li><a href="#trunkPerformanceTestsAnimometerteststextlayeringtexthtml">trunk/PerformanceTests/Animometer/tests/text/layering-text.html</a></li>
<li><a href="#trunkPerformanceTestsAnimometerteststextresourceslayeringtextjs">trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js</a></li>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsAnimometerresourcesextensionsjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/resources/extensions.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/resources/extensions.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/resources/extensions.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -14,6 +14,11 @@
</span><span class="cx">     return new Point(radiuses.x * Math.cos(angle), radiuses.y * Math.sin(angle));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Point.elementClientSize = function(element)
+{
+    return new Point(element.clientWidth, element.clientHeight);
+}
+
</ins><span class="cx"> Point.prototype =
</span><span class="cx"> {
</span><span class="cx">     // Used when the point object is used as a size object.
</span><span class="lines">@@ -65,12 +70,19 @@
</span><span class="cx"> 
</span><span class="cx"> Insets.prototype =
</span><span class="cx"> {
</span><del>-    get width() {
</del><ins>+    get width()
+    {
</ins><span class="cx">         return this.left + this.right;
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    get height() {
</del><ins>+    get height()
+    {
</ins><span class="cx">         return this.top + this.bottom;
</span><ins>+    },
+    
+    get size()
+    {
+        return new Point(this.width, this.height);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -110,10 +122,51 @@
</span><span class="cx">         this._chainedPromise.resolve(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function Options(testInterval, frameRate)
</del><ins>+window.DocumentExtension =
</ins><span class="cx"> {
</span><del>-    this.testInterval = testInterval;
-    this.frameRate = frameRate;
</del><ins>+    createElement : function(name, attrs, parentElement)
+    {
+        var element = document.createElement(name);
+
+        for (var key in attrs)
+            element.setAttribute(key, attrs[key]);
+
+        parentElement.appendChild(element);
+        return element;
+    },
+
+    createSvgElement: function(name, attrs, xlinkAttrs, parentElement)
+    {
+        const svgNamespace = &quot;http://www.w3.org/2000/svg&quot;;
+        const xlinkNamespace = &quot;http://www.w3.org/1999/xlink&quot;;
+
+        var element = document.createElementNS(svgNamespace, name);
+        
+        for (var key in attrs)
+            element.setAttribute(key, attrs[key]);
+            
+        for (var key in xlinkAttrs)
+            element.setAttributeNS(xlinkNamespace, key, xlinkAttrs[key]);
+            
+        parentElement.appendChild(element);
+        return element;
+    },
+    
+    insertCssRuleAfter: function(newRule, referenceRule)
+    {
+        var styleSheets = document.styleSheets;
+
+        for (var i = 0; i &lt; styleSheets.length; ++i) {       
+            for (var j = 0; j &lt; styleSheets[i].cssRules.length; ++j) {
+                if (styleSheets[i].cssRules[j].selectorText == referenceRule) {
+                    styleSheets[i].insertRule(newRule, j + 1);
+                    return true;
+                }
+            }
+        }
+        
+        return false;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function ProgressBar(element, ranges)
</span><span class="lines">@@ -227,11 +280,11 @@
</span><span class="cx"> 
</span><span class="cx">     _showHeader: function(message)
</span><span class="cx">     {
</span><del>-        var row = document.createElement(&quot;tr&quot;);
</del><ins>+        var thead = DocumentExtension.createElement(&quot;thead&quot;, {}, this.element);
+        var row = DocumentExtension.createElement(&quot;tr&quot;, {}, thead);
</ins><span class="cx"> 
</span><span class="cx">         var queue = [];
</span><span class="cx">         this._showHeaderRow(row, queue, this._headers, message);
</span><del>-        this.element.appendChild(row);
</del><span class="cx"> 
</span><span class="cx">         while (queue.length) {
</span><span class="cx">             var row = null;
</span><span class="lines">@@ -246,14 +299,13 @@
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 if (!row)
</span><del>-                    var row = document.createElement(&quot;tr&quot;);
</del><ins>+                    row = DocumentExtension.createElement(&quot;tr&quot;, {}, thead);
</ins><span class="cx"> 
</span><span class="cx">                 this._showHeaderRow(row, queue, entry.headers, &quot;&quot;);
</span><span class="cx">                 entry.element.colSpan = entry.headers.length;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             if (row) {
</span><del>-                this.element.appendChild(row);
</del><span class="cx">                 entries.forEach(function(entry) {
</span><span class="cx">                     ++entry.rowSpan;
</span><span class="cx">                 });
</span><span class="lines">@@ -290,14 +342,14 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         var td = document.createElement(&quot;td&quot;);
</span><del>-        var button = document.createElement(&quot;div&quot;);
</del><ins>+        var button = document.createElement(&quot;button&quot;);
</ins><span class="cx">         button.className = &quot;small-button&quot;;
</span><span class="cx"> 
</span><span class="cx">         button.addEventListener(&quot;click&quot;, function() {
</span><span class="cx">             var samples = data[Strings[&quot;JSON_GRAPH&quot;][0]];
</span><span class="cx">             var samplingTimeOffset = data[Strings[&quot;JSON_GRAPH&quot;][1]];
</span><span class="cx">             var axes = Strings[&quot;TEXT_EXPERIMENTS&quot;];
</span><del>-            window.showTestGraph(testName, axes, samples, samplingTimeOffset);
</del><ins>+            benchmarkController.showTestGraph(testName, axes, samples, samplingTimeOffset);
</ins><span class="cx">         });
</span><span class="cx">             
</span><span class="cx">         button.textContent = Strings[&quot;TEXT_RESULTS&quot;][1] + &quot;...&quot;;
</span><span class="lines">@@ -314,11 +366,11 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         var td = document.createElement(&quot;td&quot;);
</span><del>-        var button = document.createElement(&quot;div&quot;);
</del><ins>+        var button = document.createElement(&quot;button&quot;);
</ins><span class="cx">         button.className = &quot;small-button&quot;;
</span><span class="cx"> 
</span><span class="cx">         button.addEventListener(&quot;click&quot;, function() {
</span><del>-            window.showTestJSON(testName, testResults);
</del><ins>+            benchmarkController.showTestJSON(testName, testResults);
</ins><span class="cx">         });
</span><span class="cx">             
</span><span class="cx">         button.textContent = Strings[&quot;TEXT_RESULTS&quot;][2] + &quot;...&quot;;
</span><span class="lines">@@ -390,3 +442,4 @@
</span><span class="cx">         }, this);
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+
</ins></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunneranimometerhtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/animometer.html (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/animometer.html        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/animometer.html        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -14,71 +14,85 @@
</span><span class="cx"> &lt;body&gt;
</span><span class="cx">     &lt;main&gt;
</span><span class="cx">         &lt;section id=&quot;home&quot; class=&quot;selected&quot;&gt;
</span><del>-            &lt;p&gt;
-                Animometer is a browser benchmark that measures the complexity of an animation for
-                which a browser can achieve 50 FPS (frame per second). It uses adaptive animations
-                to tune their complexities to stay close to 50 FPS.
-            &lt;/p&gt;
-            &lt;div class=&quot;options&quot;&gt;
-                &lt;div id=&quot;suites&quot; class=&quot;column&quot;&gt;
-                &lt;p&gt;
-                    &lt;label&gt;&lt;input type=&quot;checkbox&quot; id=&quot;toggleTests&quot;&gt; Show individual tests&lt;/label&gt;
-                &lt;/p&gt;
-                Suites:&lt;br&gt;
-                &lt;/div&gt;
-                &lt;div&gt;
-                    &lt;label&gt;Test interval: &lt;input id=&quot;test-interval&quot; type=&quot;number&quot; value=&quot;30&quot;&gt; seconds&lt;/label&gt;&lt;br&gt;
-                    &lt;label&gt;Frame rate: &lt;input id=&quot;frame-rate&quot; type=&quot;number&quot; value=&quot;50&quot;&gt; fps&lt;/label&gt;&lt;br&gt;
-                    &lt;label&gt;&lt;input id=&quot;estimated-frame-rate&quot; type=&quot;checkbox&quot; checked&gt; Estimated Frame Rate&lt;/label&gt;&lt;br&gt;
-                    &lt;label&gt;&lt;input id=&quot;fix-test-complexity&quot; type=&quot;checkbox&quot;&gt; Fix test complexity after warmup&lt;/label&gt;&lt;br&gt;
-                    &lt;label&gt;&lt;input id=&quot;show-running-results&quot; type=&quot;checkbox&quot;&gt; Show running results&lt;/label&gt;
-                &lt;/div&gt;
-            &lt;/div&gt;
-            &lt;div class=&quot;buttons&quot;&gt;
-                &lt;button onclick=&quot;startTest()&quot;&gt;Start Test&lt;/button&gt;
-            &lt;/div&gt;
</del><ins>+            &lt;header&gt;
+                &lt;h2&gt;
+                    Animometer is a browser benchmark that measures the complexity of an animation for
+                    which a browser can achieve 50 FPS (frame per second). It uses adaptive animations
+                    to tune their complexities to stay close to 50 FPS.
+                &lt;/h2&gt;
+            &lt;/header&gt;
+            &lt;suites&gt;
+                &lt;h2&gt;Suites:&lt;/h2&gt;
+                &lt;ul class=&quot;tree&quot;&gt;&lt;/ul&gt;
+            &lt;/suites&gt;
+            &lt;options&gt;
+                &lt;h2&gt;Options:&lt;/h2&gt;
+                &lt;label&gt;Test interval: &lt;input id=&quot;test-interval&quot; type=&quot;number&quot; value=&quot;30&quot;&gt; seconds&lt;/label&gt;&lt;br&gt;
+                &lt;label&gt;Frame rate: &lt;input id=&quot;frame-rate&quot; type=&quot;number&quot; value=&quot;50&quot;&gt; fps&lt;/label&gt;&lt;br&gt;
+                &lt;label&gt;&lt;input id=&quot;estimated-frame-rate&quot; type=&quot;checkbox&quot; checked&gt; Estimated Frame Rate&lt;/label&gt;&lt;br&gt;
+                &lt;label&gt;&lt;input id=&quot;fix-test-complexity&quot; type=&quot;checkbox&quot;&gt; Fix test complexity after warmup&lt;/label&gt;&lt;br&gt;
+                &lt;label&gt;&lt;input id=&quot;show-running-results&quot; type=&quot;checkbox&quot;&gt; Show running results&lt;/label&gt;&lt;br&gt;
+                &lt;label&gt;&lt;input id=&quot;normalize-for-device-scale-factor&quot; type=&quot;checkbox&quot;&gt; Normalize for device scale factor&lt;/label&gt;
+            &lt;/options&gt;
+            &lt;footer&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.startTest()&quot;&gt;Start Test&lt;/button&gt;
+            &lt;/footer&gt;
</ins><span class="cx">         &lt;/section&gt;
</span><span class="cx">         &lt;section id=&quot;running&quot;&gt;
</span><del>-            &lt;div id=&quot;testContainer&quot;&gt;&lt;/div&gt;
</del><ins>+            &lt;div id=&quot;running-test&quot;&gt;&lt;/div&gt;
</ins><span class="cx">             &lt;div id=&quot;progress&quot;&gt;
</span><span class="cx">                 &lt;div id=&quot;progress-completed&quot;&gt;&lt;/div&gt;
</span><span class="cx">             &lt;/div&gt;
</span><span class="cx">             &lt;div id=&quot;record&quot;&gt;
</span><del>-                &lt;table class=&quot;record-table&quot;&gt;&lt;/table&gt;
</del><ins>+                &lt;table class=&quot;results-table&quot;&gt;&lt;/table&gt;
</ins><span class="cx">             &lt;/div&gt;
</span><span class="cx">         &lt;/section&gt;
</span><span class="cx">         &lt;section id=&quot;results&quot;&gt;
</span><del>-            &lt;h1&gt;Results:&lt;/h1&gt;
-            &lt;table class=&quot;results-table&quot;&gt;&lt;/table&gt;
-            &lt;div class=&quot;buttons&quot;&gt;
-                &lt;button onclick=&quot;showJson()&quot;&gt;JSON&lt;/button&gt;
-                &lt;button onclick=&quot;startTest()&quot;&gt;Test Again&lt;/button&gt;
-            &lt;/div&gt;
</del><ins>+            &lt;header&gt;
+                &lt;h1&gt;Results:&lt;/h1&gt;
+            &lt;/header&gt;
+            &lt;data&gt;
+                &lt;table class=&quot;results-table&quot;&gt;&lt;/table&gt;
+            &lt;/data&gt;
+            &lt;footer&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.showJson()&quot;&gt;JSON&lt;/button&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.startTest()&quot;&gt;Test Again&lt;/button&gt;
+            &lt;/footer&gt;
</ins><span class="cx">         &lt;/section&gt;  
</span><span class="cx">         &lt;section id=&quot;json&quot;&gt;
</span><del>-            &lt;h1&gt;JSON:&lt;/h1&gt;
-            &lt;textarea class=&quot;results-json&quot;&gt;&lt;/textarea&gt;
-            &lt;div class=&quot;buttons&quot;&gt;
-                &lt;button onclick=&quot;showResults()&quot;&gt;Results&lt;/button&gt;
-                &lt;button onclick=&quot;startTest()&quot;&gt;Test Again&lt;/button&gt;
-            &lt;/div&gt;
</del><ins>+            &lt;header&gt;
+                &lt;h1&gt;JSON:&lt;/h1&gt;
+            &lt;/header&gt;
+            &lt;data&gt;
+                &lt;div class=&quot;results-json&quot; contentEditable=&quot;true&quot;&gt;&lt;/div&gt;
+            &lt;/data&gt;
+            &lt;footer&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.showResults()&quot;&gt;Results&lt;/button&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.startTest()&quot;&gt;Test Again&lt;/button&gt;
+            &lt;/footer&gt;
</ins><span class="cx">         &lt;/section&gt;  
</span><ins>+        &lt;section id=&quot;test-json&quot;&gt;
+            &lt;header&gt;
+                &lt;h1&gt;JSON:&lt;/h1&gt;
+            &lt;/header&gt;
+            &lt;data&gt;
+                &lt;div class=&quot;results-json&quot; contentEditable=&quot;true&quot;&gt;&lt;/div&gt;
+            &lt;/data&gt;
+            &lt;footer&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.showResults()&quot;&gt;Results&lt;/button&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.startTest()&quot;&gt;Test Again&lt;/button&gt;        
+            &lt;/footer&gt;
+        &lt;/section&gt;
</ins><span class="cx">         &lt;section id=&quot;test-graph&quot;&gt;
</span><del>-            &lt;h1&gt;Graph:&lt;/h1&gt;
-            &lt;div id=&quot;graphContainer&quot;&gt;&lt;/div&gt;
-            &lt;div class=&quot;buttons&quot;&gt;
-                &lt;button onclick=&quot;showResults()&quot;&gt;Results&lt;/button&gt;
-                &lt;button onclick=&quot;startTest()&quot;&gt;Test Again&lt;/button&gt;        
-            &lt;/div&gt;
</del><ins>+            &lt;header&gt;
+                &lt;h1&gt;Graph:&lt;/h1&gt;
+            &lt;/header&gt;
+            &lt;data&gt;&lt;/data&gt;
+            &lt;footer&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.showResults()&quot;&gt;Results&lt;/button&gt;
+                &lt;button class=&quot;large-button&quot; onclick=&quot;benchmarkController.startTest()&quot;&gt;Test Again&lt;/button&gt;        
+            &lt;/footer&gt;
</ins><span class="cx">         &lt;/section&gt;  
</span><del>-        &lt;section id=&quot;test-json&quot;&gt;
-            &lt;h1&gt;JSON:&lt;/h1&gt;
-            &lt;textarea class=&quot;results-json&quot;&gt;&lt;/textarea&gt;
-            &lt;div class=&quot;buttons&quot;&gt;
-                &lt;button onclick=&quot;showResults()&quot;&gt;Results&lt;/button&gt;
-                &lt;button onclick=&quot;startTest()&quot;&gt;Test Again&lt;/button&gt;        
-            &lt;/div&gt;
-        &lt;/section&gt;  
</del><span class="cx">     &lt;/main&gt;
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunnerresourcesanimometercss"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/resources/animometer.css (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/resources/animometer.css        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/animometer.css        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+/* -------------------------------------------------------------------------- */
+/*                                HTML and Body                               */
+/* -------------------------------------------------------------------------- */
+
+html,body {
+    height: 100%;
+    margin: 0px;
+    padding: 0px;
+}
+
</ins><span class="cx"> body {
</span><span class="cx">     background-color: rgb(96, 96, 96);
</span><span class="cx">     color: rgb(235, 235, 235);
</span><span class="lines">@@ -4,252 +14,419 @@
</span><span class="cx">     font-family: &quot;Helvetica Neue&quot;, Helvetica, Verdana, sans-serif;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-main {
-    display: block;
-    position: absolute;
-    width: 800px;
-    height: 600px;
-    top: 50%;
-    left: 50%;
-    margin-top: -321px;
-    margin-left: -421px;
-    padding: 15px;
-    border: 6px solid rgb(235, 235, 235);
-    border-radius: 20px;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                              Buttons                                       */
+/* -------------------------------------------------------------------------- */
+
+button {
+    -webkit-appearance: none;
+    -webkit-user-select: none;
+    background-color: transparent;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-iframe {
-    width: 800px;
-    height: 600px;
-    border: 0px none;
-    position: absolute;
</del><ins>+button.large-button {
+    border: 3px solid rgb(235, 235, 235);
+    border-radius: 10px;
+    min-width: 200px;
+    padding: .5em 2em;
+    margin: 0 1em;
+    font-size: 25px;
+    color: rgb(235, 235, 235);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-label, p {
-    font-size: 16px;
-    line-height: 21px;
</del><ins>+button.large-button:active {
+    background-color: rgb(235, 235, 235);
+    color: rgb(46, 51, 55);
+    border-color: rgb(235, 235, 235) !important;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section {
-    display: none;
</del><ins>+button.large-button:disabled {
+    background-color: rgb(96, 96, 96);
+    color: rgb(128, 128, 128);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section &gt; p {
-    margin: 10px 20px;
</del><ins>+button.small-button {
+    border: 1px solid DarkCyan;
+    border-radius: 2px;
+    padding: 1px 4px;
+    margin: 0 4px;
+    font-size: 9px;
+    color: black;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#home &gt; p {
-    margin: 0 auto;
-    width: 70%;
-    text-align: center;
</del><ins>+button.small-button:active {
+    background-color: DarkCyan;
+    color: rgb(46, 51, 55);
+    border-color: DarkCyan !important;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#home &gt; p:first-child {
-    margin-top: 160px;
-    text-align: center;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                               Tree                                         */
+/* -------------------------------------------------------------------------- */
+
+.tree {
+    margin: 1em;
+    overflow-y: scroll;
+    height: 80%;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section.selected {
</del><ins>+.tree .expand-button {
+    position: absolute;
+    clip: rect(0, 0, 0, 0);
+}
+
+.tree .expand-button ~ ul {
+    display: none;
+}
+
+.tree .expand-button:checked ~ ul {
</ins><span class="cx">     display: block;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#testContainer {
-    position: absolute;
-    top: 15px;
-    left: 15px;
-    width: 800px;
-    height: 600px;
</del><ins>+.tree ul {
+    list-style-type:none;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#running &gt; #progress {
-    position: absolute;
-    bottom: -6px;
-    left: 60px;
-    right: 60px;
-    height: 6px;
-    background-color: rgb(128, 128, 128);
-    border-left: 6px solid rgb(46, 51, 55);
-    border-right: 6px solid rgb(46, 51, 55);
</del><ins>+.tree li {
+    position: relative;
+    padding: 0 0 1em 1em;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#running #progress-completed {
-    position: absolute;
-    top: 0;
-    left: 0;
-    height: 6px;
-    width: 0;
-    background-color: rgb(235, 235, 235);
</del><ins>+.tree ul li {
+    list-style:none;
+    padding: 1em 0 0 0em;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#running &gt; #record {
-    position: absolute;
-    bottom: -130px;
-    left: 0px;
-    right: 0px;
-    height: 75px;
-    color: rgb(128, 128, 128);
-    padding: 15px;
-    border: 6px solid rgb(235, 235, 235);
-    border-radius: 20px;
</del><ins>+.tree &gt; li:last-child {
+    padding-bottom: 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#running &gt; #record &gt; table,
-section#results &gt; table {
</del><ins>+.tree-label {
+  position: relative;
+  display: inline-block;
+}
+
+label.tree-label {
+    cursor: pointer;
+}
+
+label.tree-label:before {
+    background: black;
+    color: white;
+    position: relative;
+    z-index: 1;
+    float: left;
+    margin: 0 1em 0 -2.1em;
+    width: 1em;
+    height: 1em;
+    border-radius: 1em;
+    content: '+';
+    text-align: center;
+    line-height: .9em;
+}
+
+:checked ~ label.tree-label:before {
+    content: '\2013';
+}
+
+/* -------------------------------------------------------------------------- */
+/*                              Results Table                                 */
+/* -------------------------------------------------------------------------- */
+
+table.results-table {
</ins><span class="cx">     width: 100%;
</span><ins>+    border: 2px solid DarkCyan;
+    border-collapse: collapse;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#running &gt; #record &gt; table td, th,
-section#results &gt; table td, th {
</del><ins>+.results-table th,
+.results-table td {
</ins><span class="cx">     font-size: 11px;
</span><del>-    border: 1px solid #98bf21;
</del><span class="cx">     padding: 3px 4px 2px 4px;
</span><span class="cx"> }
</span><del>-                                           
-section#running &gt; #record &gt; table tr.alt, td
-section#results &gt; table tr.alt, td {
-    color: #000000;
-    background-color: #EAF2D3;
</del><ins>+
+.results-table th {
+    background: DarkCyan;
+    border-left: 1px solid LightCyan;
+    border-right: 1px solid LightCyan;
+    border-top: 1px solid LightCyan;
</ins><span class="cx"> }
</span><del>-                                             
-section#running &gt; #record &gt; table th,
-section#results &gt; table th {
-    background-color: #A7C942; 
-    text-align: center;
</del><ins>+
+.results-table td {
+    background: white;
+    border-bottom: none;
+    border-left: none;
+    border-right: 1px solid DarkCyan;
+    border-top: 1px solid DarkCyan;
+    color: black;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-section#test-json &gt; textarea,
-section#json &gt; textarea {
-    width: 800px;
-    height: 460px;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                              Results JSON                                  */
+/* -------------------------------------------------------------------------- */
+
+div.results-json {
+    width: 100%;
</ins><span class="cx">     background-color: rgb(128, 128, 128);
</span><del>-    border: 1px solid rgb(235, 235, 235);
-    color: white;
</del><ins>+    color: rgb(235, 235, 235);
</ins><span class="cx">     white-space: pre;
</span><del>-    overflow: scroll;
</del><ins>+    font-size: 12px;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-.options {
-    margin:0 auto;    
-    margin-top: 30px;
-    width: 600px;
-    align: center;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                                 Main Layout                                */
+/* -------------------------------------------------------------------------- */
+
+main {
+    width: 100%;
+    height: 100%;
+    display: -ms-flexbox;
+    display: -webkit-flex;
+    display: flex;
+    -ms-flex-align: center;
+    -webkit-align-items: center;
+    -webkit-box-align: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    -ms-flex-pack: center;
+    justify-content: center;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-.options p {
-    margin-top: 0;
</del><ins>+section {
+    width: 800px;
+    height: 600px;
+    display: none;
+    padding: 10px;
+    border: 6px solid rgb(235, 235, 235);
+    border-radius: 20px;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#suites ul {
-    list-style-type: none;
-    margin: 0;
-    padding: 0;
</del><ins>+section.selected {
+    display: -ms-flexbox;
+    display: -webkit-flex;
+    display: flex;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#suites ul ul {
-    padding-left: 1.5em;
-    display: none;
</del><ins>+section &gt; header,
+section &gt; footer {
+    margin: 10px;
+    padding: 10px;
+    -webkit-flex: 0 1 100%;
+    -ms-flex: 0 1 100%;
+    flex: 0 1 100%;
+    max-height: 15%;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#suites ul ul input, #suites ul ul label {
-    font-size: .8em;
</del><ins>+section &gt; footer {
+    text-align: center;
+    clear: both;
+    display: -ms-flexbox;
+    display: -webkit-flex;
+    display: flex;
+    -ms-flex-align: center;
+    -webkit-align-items: center;
+    -webkit-box-align: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    -ms-flex-pack: center;
+    justify-content: center;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#suites.showTests ul ul {
-    display: block;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                                 Home Section                               */
+/* -------------------------------------------------------------------------- */
+
+section#home {
+    -webkit-flex-direction: row;
+    -ms-flex-direction: row;
+    flex-direction: row;
+    -webkit-flex-wrap: wrap;
+    -ms-flex-wrap: wrap;
+    flex-wrap: wrap;
+    -webkit-align-content: center;
+    -ms-flex-line-pack: center;
+    align-content: center;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-.column {
-    width: 55%;
-    float:left;
</del><ins>+section#home &gt; suites,
+section#home &gt; options {
+    padding: 10px;
+    margin: 10px;
+    height: 50%;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-input[type=&quot;number&quot;] {
-   width:50px;
</del><ins>+section#home &gt; suites {
+    padding-left: 80px;
+    -webkit-flex: 0 1 40%;
+    -ms-flex: 0 1 40%;
+    flex: 0 1 40%;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-.buttons {
-    margin-top: 10px;
</del><ins>+section#home &gt; options {
+    -webkit-flex: 1 1 auto;
+    -ms-flex: 1 1 auto;
+    flex: 1 1 auto;
+}
+
+section#home &gt; options &gt; label {
+    margin: 2em;
+    line-height: 2;
+}
+
+section#home &gt; header &gt; h2 {
+    margin: 0 auto;
+    width: 70%;
</ins><span class="cx">     text-align: center;
</span><del>-    clear: both;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-button {
-    -webkit-appearance: none;
-    border: 3px solid rgb(235, 235, 235);
-    border-radius: 10px;
-    min-width: 200px;
-    padding: 5px 20px;
-    margin: 0 40px;
-    font-size: 25px;
-    color: rgb(235, 235, 235);
-    background-color: transparent;
</del><ins>+section#home &gt; options &gt; label &gt; input[type=&quot;number&quot;] {
+   width: 50px;
+}
</ins><span class="cx"> 
</span><del>-    -webkit-user-select: none;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                           Running Section                                  */
+/* -------------------------------------------------------------------------- */
+
+section#running {
+    position: relative;
+    -ms-flex-align: center;
+    -webkit-align-items: center;
+    -webkit-box-align: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    -ms-flex-pack: center;
+    justify-content: center;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-button:active {
</del><ins>+section#running &gt; #running-test {
+    width: 100%;
+    height: 100%;
+}
+
+section#running &gt; #running-test &gt; iframe {
+    width: 100%;
+    height: 100%;
+    border: 0px none;
+}
+
+section#running &gt; #progress {
+    position: absolute;
+    bottom: -6px;
+    left: 60px;
+    right: 60px;
+    height: 6px;
+    background-color: rgb(128, 128, 128);
+    border-left: 6px solid rgb(46, 51, 55);
+    border-right: 6px solid rgb(46, 51, 55);
+}
+
+section#running &gt; #progress &gt; #progress-completed {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 6px;
+    width: 0;
</ins><span class="cx">     background-color: rgb(235, 235, 235);
</span><del>-    color: rgb(46, 51, 55);
-    border-color: rgb(235, 235, 235) !important;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-button:focus {
-    outline: none;
-    border-color: rgb(232, 79, 79);
</del><ins>+section#running &gt; #record {
+    position: absolute;
+    bottom: -95px;
+    left: 0px;
+    right: 0px;
+    padding: 16px;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-.small-button {
-    -webkit-appearance: none;
-    border: 1px solid rgb(96, 96, 96);
-    border-radius: 2px;
-    padding: 1px 4px;
-    margin: 0 4px;
-    background-color: transparent;
-    cursor: pointer;
-    text-align: center;
-    -webkit-user-select: none;
</del><ins>+/* -------------------------------------------------------------------------- */
+/*                           Results Section                                  */
+/* -------------------------------------------------------------------------- */
+
+section#results,
+section#json,
+section#test-json,
+section#test-graph {
+    -webkit-flex-direction: row;
+    -ms-flex-direction: row;
+    flex-direction: row;
+    -webkit-flex-wrap: wrap;
+    -ms-flex-wrap: wrap;
+    flex-wrap: wrap;
+    -webkit-justify-content: space-between;
+    -ms-flex-pack: justify;
+    justify-content: space-between;
+    -webkit-align-content: space-between;
+    -ms-flex-line-pack: justify;
+    align-content: space-between;
+    -webkit-align-items: flex-start;
+    -ms-flex-align: start;
+    align-items: flex-start;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#graphContainer {
-  font: 10px sans-serif;
-  color: rgb(235, 235, 235);  
</del><ins>+section#results &gt; data,
+section#json &gt; data,
+section#test-json &gt; data,
+section#test-graph &gt; data {
+    overflow-y: scroll;
+    height: 70%;
+    -webkit-flex: 0 1 100%;
+    -ms-flex: 0 1 100%;
+    flex: 0 1 100%;
+    -webkit-align-self: stretch;
+    -ms-flex-item-align: stretch;
+    align-self: stretch;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+/* -------------------------------------------------------------------------- */
+/*                           Graph Section                                    */
+/* -------------------------------------------------------------------------- */
+
+section#test-graph &gt; data {
+    font: 10px sans-serif;
+    color: rgb(235, 235, 235);
+}
+
+section#test-graph &gt; data &gt; svg {
+    fill: none;
+    shape-rendering: crispEdges;  
+}
+
</ins><span class="cx"> .axis path,
</span><span class="cx"> .axis line {
</span><del>-  fill: none;
-  stroke: #999;
-  shape-rendering: crispEdges;
</del><ins>+    fill: none;
+    stroke: #999999;
+    shape-rendering: crispEdges;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .left-samples {
</span><del>-  fill: none;
-  stroke: #7ADD49;
-  stroke-width: 1.5px;
</del><ins>+    stroke: #7ADD49;
+    stroke-width: 1.5px;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .right-samples {
</span><del>-    fill: none;
</del><span class="cx">     stroke: #FA4925;
</span><span class="cx">     stroke-width: 1.5px;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .sample-time {
</span><del>-    fill: none;
</del><span class="cx">     stroke: #5493D6;
</span><del>-    stroke-width: 1px;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .left-mean {
</span><del>-    fill: none;
</del><span class="cx">     stroke: #7ADD49;
</span><del>-    stroke-width: 1px;
</del><span class="cx">     opacity: .8;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> .right-mean {
</span><del>-    fill: none;
</del><span class="cx">     stroke: #FA4925;
</span><del>-    stroke-width: 1px;
</del><span class="cx">     opacity: .8;
</span><span class="cx"> }
</span><ins>+
+/* -------------------------------------------------------------------------- */
+/*                           JSON Section                                  */
+/* -------------------------------------------------------------------------- */
+
+section#json &gt; data,
+section#test-json &gt; data {
+    border: 1px solid rgb(235, 235, 235);
+    box-sizing: border-box;
+}
</ins></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunnerresourcesanimometerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/resources/animometer.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/resources/animometer.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/animometer.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -3,11 +3,17 @@
</span><span class="cx">     testsCount: null,
</span><span class="cx">     progressBar: null,
</span><span class="cx">     recordTable: null,
</span><del>-    options: { testInterval: 30000, frameRate: 50, estimatedFrameRate: true, fixTestComplexity : false },
</del><ins>+    options: null,
</ins><span class="cx">     score: 0,
</span><span class="cx">     _resultsDashboard: null,
</span><span class="cx">     _resultsTable: null,
</span><span class="cx">     
</span><ins>+    initialize: function(suites, options)
+    {
+        this.testsCount = this.iterationCount * suites.reduce(function (count, suite) { return count + suite.tests.length; }, 0);
+        this.options = options;
+    },
+
</ins><span class="cx">     willAddTestFrame: function (frame)
</span><span class="cx">     {
</span><span class="cx">         var main = document.querySelector(&quot;main&quot;);
</span><span class="lines">@@ -24,10 +30,10 @@
</span><span class="cx">     willStartFirstIteration: function ()
</span><span class="cx">     {
</span><span class="cx">         this._resultsDashboard = new ResultsDashboard();
</span><del>-        this._resultsTable = new ResultsTable(document.querySelector(&quot;.results-table&quot;), Headers);
</del><ins>+        this._resultsTable = new ResultsTable(document.querySelector(&quot;section#results &gt; data &gt; table&quot;), Headers);
</ins><span class="cx">         
</span><span class="cx">         this.progressBar = new ProgressBar(document.getElementById(&quot;progress-completed&quot;), this.testsCount);
</span><del>-        this.recordTable = new ResultsTable(document.querySelector(&quot;.record-table&quot;), Headers);
</del><ins>+        this.recordTable = new ResultsTable(document.querySelector(&quot;section#running &gt; #record &gt; table&quot;), Headers);
</ins><span class="cx">     },
</span><span class="cx">     
</span><span class="cx">     didRunSuites: function (suitesSamplers)
</span><span class="lines">@@ -38,226 +44,365 @@
</span><span class="cx">     didFinishLastIteration: function ()
</span><span class="cx">     {
</span><span class="cx">         var json = this._resultsDashboard.toJSON(true, true);
</span><ins>+        this.score = json[Strings[&quot;JSON_SCORE&quot;]];
</ins><span class="cx">         this._resultsTable.showIterations(json[Strings[&quot;JSON_RESULTS&quot;][0]]);
</span><del>-        
-        var element = document.querySelector(&quot;#json &gt; textarea&quot;);
-        element.innerHTML = JSON.stringify(json[Strings[&quot;JSON_RESULTS&quot;][0]][0], function(key, value) { 
-            if (typeof value == &quot;number&quot;)
-                return value.toFixed(2);
-            return value;
-        }, 4);
-        
-        this.score = json[Strings[&quot;JSON_SCORE&quot;]];
-        showResults();
</del><ins>+        sectionsManager.showJSON(&quot;json&quot;, json[Strings[&quot;JSON_RESULTS&quot;][0]][0]);
+        benchmarkController.showResults();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function showSection(sectionIdentifier, pushState)
</del><ins>+window.sectionsManager =
</ins><span class="cx"> {
</span><del>-    var currentSectionElement = document.querySelector(&quot;section.selected&quot;);
-    console.assert(currentSectionElement);
</del><ins>+    _sectionHeaderH1Element: function(sectionIdentifier)
+    {
+        return document.querySelector(&quot;#&quot; + sectionIdentifier + &quot; &gt; header &gt; h1&quot;);
+    },
+    
+    _sectionDataDivElement: function(sectionIdentifier)
+    {
+        return document.querySelector(&quot;#&quot; + sectionIdentifier + &quot; &gt;  data &gt; div&quot;);
+    },
+    
+    showScore: function(sectionIdentifier, title)
+    {
+        var element = this._sectionHeaderH1Element(sectionIdentifier);
+        element.textContent = title + &quot;:&quot;;
</ins><span class="cx"> 
</span><del>-    var newSectionElement = document.getElementById(sectionIdentifier);
-    console.assert(newSectionElement);
</del><ins>+        var score = benchmarkRunnerClient.score.toFixed(2);
+        element.textContent += &quot; [Score = &quot; + score + &quot;]&quot;;
+    },
+    
+    showTestName: function(sectionIdentifier, title, testName)
+    {
+        var element = this._sectionHeaderH1Element(sectionIdentifier);
+        element.textContent = title + &quot;:&quot;;
</ins><span class="cx"> 
</span><del>-    currentSectionElement.classList.remove(&quot;selected&quot;);
-    newSectionElement.classList.add(&quot;selected&quot;);
</del><ins>+        if (!testName.length)
+            return;
+            
+        element.textContent += &quot; [test = &quot; + testName + &quot;]&quot;;
+    },
+    
+    showJSON: function(sectionIdentifier, json)
+    {
+        var element = this._sectionDataDivElement(sectionIdentifier);
+        element.textContent = JSON.stringify(json, function(key, value) { 
+            if (typeof value == &quot;number&quot;)
+                return value.toFixed(2);
+            return value;
+        }, 4);
+    },
+    
+    showSection: function(sectionIdentifier, pushState)
+    {
+        var currentSectionElement = document.querySelector(&quot;section.selected&quot;);
+        console.assert(currentSectionElement);
</ins><span class="cx"> 
</span><del>-    if (pushState)
-        history.pushState({section: sectionIdentifier}, document.title);
-}
</del><ins>+        var newSectionElement = document.getElementById(sectionIdentifier);
+        console.assert(newSectionElement);
</ins><span class="cx"> 
</span><del>-function startBenchmark()
-{
-    var enabledSuites = [];
</del><ins>+        currentSectionElement.classList.remove(&quot;selected&quot;);
+        newSectionElement.classList.add(&quot;selected&quot;);
</ins><span class="cx"> 
</span><del>-    localStorage.clear();
-    var suiteItems = document.querySelectorAll(&quot;#suites &gt; ul &gt; li&quot;);
-    for (var i = 0; i &lt; suiteItems.length; ++i) {
-        var suiteItem = suiteItems[i];
-        var suiteCheckbox = suiteItem.querySelector(&quot;input&quot;);
</del><ins>+        if (pushState)
+            history.pushState({section: sectionIdentifier}, document.title);
+    },
</ins><span class="cx"> 
</span><del>-        if (!suiteCheckbox.checked)
-            continue;
</del><ins>+    setupSectionStyle: function()
+    {
+        if (screen.width &gt;= 1800 &amp;&amp; screen.height &gt;= 1000)
+            DocumentExtension.insertCssRuleAfter(&quot; section { width: 1600px; height: 800px; }&quot;, &quot;section&quot;);
+        else
+            DocumentExtension.insertCssRuleAfter(&quot; section { width: 800px; height: 600px; }&quot;, &quot;section&quot;);
+    },
+    
+    setupRunningSectionStyle: function(options)
+    {
+        if (!options[&quot;show-running-results&quot;])
+            document.getElementById(&quot;record&quot;).style.display = &quot;none&quot;;
</ins><span class="cx"> 
</span><del>-        var enabledTests = [];
-        var testCheckboxes = suiteItem.querySelector(&quot;ul&quot;).querySelectorAll(&quot;input&quot;);
-        for (var j = 0; j &lt; testCheckboxes.length; ++j) {
-            var testCheckbox = testCheckboxes[j];
-            if (!testCheckbox.checked)
-                continue;
-
-            enabledTests.push(testCheckbox.test);
-            localStorage.setItem(localStorageNameForTest(suiteCheckbox.suite, testCheckbox.test), +testCheckbox.checked);
</del><ins>+        if (options[&quot;normalize-for-device-scale-factor&quot;] &amp;&amp; window.devicePixelRatio != 1) {
+            var percentage = window.devicePixelRatio * 100;
+            var rule = &quot;section#running &gt; #running-test &gt; iframe&quot;;
+            var newRule = rule;
+            newRule += &quot; { &quot;;
+            newRule += &quot;width: &quot; + percentage + &quot;%; &quot;;
+            newRule += &quot;height: &quot; + percentage + &quot;%; &quot;;
+            newRule += &quot;transform: scale(&quot; + 100 / percentage + &quot;) translate(&quot; + (100 - percentage) / 2 + &quot;%,&quot; + (100 - percentage) / 2 + &quot;%);&quot;;
+            newRule += &quot; }&quot;;
+            DocumentExtension.insertCssRuleAfter(newRule, rule);
</ins><span class="cx">         }
</span><del>-
-        enabledSuites.push(new Suite(suiteCheckbox.suite.name, enabledTests));
</del><span class="cx">     }
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    localStorage.setItem(&quot;test-interval&quot;, document.getElementById(&quot;test-interval&quot;).value);
-
-    var testsCount = enabledSuites.reduce(function (testsCount, suite) { return testsCount + suite.tests.length; }, 0);
-    benchmarkRunnerClient.testsCount = benchmarkRunnerClient.iterationCount * testsCount;
-    benchmarkRunnerClient.options[&quot;testInterval&quot;] = parseInt(document.getElementById(&quot;test-interval&quot;).value) * 1000;
-    benchmarkRunnerClient.options[&quot;frameRate&quot;] = parseInt(document.getElementById(&quot;frame-rate&quot;).value);
-    benchmarkRunnerClient.options[&quot;estimatedFrameRate&quot;] = document.getElementById(&quot;estimated-frame-rate&quot;).checked;    
-    benchmarkRunnerClient.options[&quot;fixTestComplexity&quot;] = document.getElementById(&quot;fix-test-complexity&quot;).checked;
-    benchmarkRunnerClient.options[&quot;showRunningResults&quot;] = document.getElementById(&quot;show-running-results&quot;).checked;
</del><ins>+window.optionsManager =
+{
+    _optionsElements : function()
+    {
+        return document.querySelectorAll(&quot;section#home &gt; options input&quot;);;
+    },
</ins><span class="cx">     
</span><del>-    if (!benchmarkRunnerClient.options[&quot;showRunningResults&quot;])
-        document.getElementById(&quot;record&quot;).style.display = &quot;none&quot;;
</del><ins>+    updateUIFromLocalStorage: function()
+    {
+        var optionsElements = this._optionsElements();
</ins><span class="cx"> 
</span><del>-    var runner = new BenchmarkRunner(enabledSuites, benchmarkRunnerClient);
-    runner.runMultipleIterations(benchmarkRunnerClient.iterationCount);
-}
</del><ins>+        for (var i = 0; i &lt; optionsElements.length; ++i) {
+            var optionElement = optionsElements[i];
+            
+            var value = localStorage.getItem(optionElement.id);
+            if (value === null)
+                continue;
</ins><span class="cx"> 
</span><del>-function startTest()
-{
-    showSection(&quot;running&quot;);
-    startBenchmark();
-}
</del><ins>+            if (optionElement.getAttribute(&quot;type&quot;) == &quot;number&quot;)
+                optionElement.value = +value;
+            else if (optionElement.getAttribute(&quot;type&quot;) == &quot;checkbox&quot;)
+                optionElement.checked = value == &quot;true&quot;;
+        }
+    },
</ins><span class="cx"> 
</span><del>-function showResults()
-{
-    var element = document.querySelector(&quot;#results &gt; h1&quot;);
-    element.textContent = Strings[&quot;TEXT_RESULTS&quot;][0] + &quot;:&quot;;
</del><ins>+    updateLocalStorageFromUI: function()
+    {
+        var optionsElements = this._optionsElements();
+        var options = {};        
+
+        for (var i = 0; i &lt; optionsElements.length; ++i) {
+            var optionElement = optionsElements[i];
+        
+            if (optionElement.getAttribute(&quot;type&quot;) == &quot;number&quot;)
+                options[optionElement.id] = optionElement.value;
+            else if (optionElement.getAttribute(&quot;type&quot;) == &quot;checkbox&quot;)
+                options[optionElement.id] = optionElement.checked;
</ins><span class="cx">     
</span><del>-    var score = benchmarkRunnerClient.score.toFixed(2);
-    element.textContent += &quot; [Score = &quot; + score + &quot;]&quot;;
</del><ins>+            localStorage.setItem(optionElement.id, options[optionElement.id]);
+        }
</ins><span class="cx">         
</span><del>-    showSection(&quot;results&quot;, true);
</del><ins>+        return options;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-function showJson()
</del><ins>+window.suitesManager =
</ins><span class="cx"> {
</span><del>-    var element = document.querySelector(&quot;#json &gt; h1&quot;);
-    element.textContent = Strings[&quot;TEXT_RESULTS&quot;][2] + &quot;:&quot;;
</del><ins>+    _treeElement : function()
+    {
+        return document.querySelector(&quot;suites &gt; .tree&quot;);
+    },
</ins><span class="cx">     
</span><del>-    var score = benchmarkRunnerClient.score.toFixed(2);
-    element.textContent += &quot; [Score = &quot; + score + &quot;]&quot;;
</del><ins>+    _suitesElements : function()
+    {
+        return document.querySelectorAll(&quot;#home &gt; suites &gt; ul &gt; li&quot;);
+    },
+    
+    _checkboxElement: function(element)
+    {
+        return element.querySelector(&quot;input[type='checkbox']:not(.expand-button)&quot;);
+    },
</ins><span class="cx"> 
</span><del>-    showSection(&quot;json&quot;, true);
-}
</del><ins>+    _localStorageNameForTest: function(suite, test)
+    {
+        return suite.name + &quot;/&quot; + test.name;
+    },
</ins><span class="cx"> 
</span><del>-function showTestGraph(testName, axes, samples, samplingTimeOffset)
-{
-    var element = document.querySelector(&quot;#test-graph &gt; h1&quot;);
-    element.textContent = Strings[&quot;TEXT_RESULTS&quot;][1] + &quot;:&quot;;
</del><ins>+    _updateSuiteCheckboxState: function(suiteCheckbox)
+    {
+        var numberEnabledTests = 0;
+        suiteCheckbox.testsElements.forEach(function(testElement) {
+            var testCheckbox = this._checkboxElement(testElement);
+            if (testCheckbox.checked)
+                ++numberEnabledTests;
+        }, this);
+        suiteCheckbox.checked = numberEnabledTests &gt; 0;
+        suiteCheckbox.indeterminate = numberEnabledTests &gt; 0 &amp;&amp; numberEnabledTests &lt; suiteCheckbox.testsElements.length;
+    },
</ins><span class="cx"> 
</span><del>-    if (testName.length)
-        element.textContent += &quot; [test = &quot; + testName + &quot;]&quot;;
</del><ins>+    _updateStartButtonState: function()
+    {
+        var suitesElements = this._suitesElements();
+        var startButton = document.querySelector(&quot;#home &gt; footer &gt; button&quot;);
+        
+        for (var i = 0; i &lt; suitesElements.length; ++i) {
+            var suiteElement = suitesElements[i];
+            var suiteCheckbox = this._checkboxElement(suiteElement);
</ins><span class="cx">             
</span><del>-    graph(&quot;#graphContainer&quot;, new Point(700, 400), new Insets(20, 50, 20, 50), axes, samples, samplingTimeOffset);
-    showSection(&quot;test-graph&quot;, true);    
-}
</del><ins>+            if (suiteCheckbox.checked) {
+                startButton.disabled = false;
+                return;
+            }
+        }
+    
+        startButton.disabled = true;
+    },
</ins><span class="cx"> 
</span><del>-function showTestJSON(testName, testResults)
-{
-    var element = document.querySelector(&quot;#test-json &gt; h1&quot;);
-    element.textContent = Strings[&quot;TEXT_RESULTS&quot;][2] + &quot;:&quot;;
</del><ins>+    _onChangeSuiteCheckbox: function(event)
+    {
+        var selected = event.target.checked;
+        event.target.testsElements.forEach(function(testElement) {
+            var testCheckbox = this._checkboxElement(testElement);
+            testCheckbox.checked = selected;        
+        }, this);
+        this._updateStartButtonState();
+    },
</ins><span class="cx"> 
</span><del>-    if (testName.length)
-        element.textContent += &quot; [test = &quot; + testName + &quot;]&quot;;
-            
-    var element = document.querySelector(&quot;#test-json &gt; textarea&quot;);
-    element.innerHTML = JSON.stringify(testResults, function(key, value) { 
-        if (typeof value == &quot;number&quot;)
-            return value.toFixed(2);
-        return value;
-    }, 4);
</del><ins>+    _onChangeTestCheckbox: function(event)
+    {
+        var suiteCheckbox = event.target.suiteCheckbox;
+        this._updateSuiteCheckboxState(suiteCheckbox);
+        this._updateStartButtonState();
+    },
</ins><span class="cx"> 
</span><del>-    showSection(&quot;test-json&quot;, true);    
-}
</del><ins>+    _createSuiteElement: function(treeElement, suite, id)
+    {
+        var suiteElement = DocumentExtension.createElement(&quot;li&quot;, {}, treeElement);
+        var expand = DocumentExtension.createElement(&quot;input&quot;, { type: &quot;checkbox&quot;,  class: &quot;expand-button&quot;, id: id }, suiteElement);
+        var label = DocumentExtension.createElement(&quot;label&quot;, { class: &quot;tree-label&quot;, for: id }, suiteElement);
</ins><span class="cx"> 
</span><del>-function initialize() {
-    populateSettings();
</del><ins>+        var suiteCheckbox = DocumentExtension.createElement(&quot;input&quot;, { type: &quot;checkbox&quot; }, label);
+        suiteCheckbox.suite = suite;
+        suiteCheckbox.onchange = this._onChangeSuiteCheckbox.bind(this);
+        suiteCheckbox.testsElements = [];
</ins><span class="cx"> 
</span><del>-    var toggleTestsCheckbox = document.getElementById(&quot;toggleTests&quot;);
-    toggleTestsCheckbox.onchange = function(event) {
-        if (event.target.checked)
-            document.getElementById(&quot;suites&quot;).classList.add(&quot;showTests&quot;);
-        else
-            document.getElementById(&quot;suites&quot;).classList.remove(&quot;showTests&quot;);
-    };
-}
</del><ins>+        label.appendChild(document.createTextNode(&quot; &quot; + suite.name));
+        return suiteElement;
+    },
</ins><span class="cx"> 
</span><del>-function updateSuiteSelection(event) {
-    var selected = event.target.checked;
-    var testCheckboxes = event.target.parentNode.parentNode.querySelector(&quot;ul&quot;).querySelectorAll(&quot;input&quot;);
-    for (var i = 0; i &lt; testCheckboxes.length; ++i) {
-        testCheckboxes[i].checked = selected;
-    }
-}
</del><ins>+    _createTestElement: function(listElement, test, suiteCheckbox)
+    {
+        var testElement = DocumentExtension.createElement(&quot;li&quot;, {}, listElement);
+        var span = DocumentExtension.createElement(&quot;span&quot;, { class: &quot;tree-label&quot; }, testElement);
</ins><span class="cx"> 
</span><del>-function updateTestSelection(event) {
-    var testsList = event.target.parentNode.parentNode.parentNode;
-    var suiteCheckbox = testsList.parentNode.querySelector(&quot;label &gt; input&quot;);
</del><ins>+        var testCheckbox = DocumentExtension.createElement(&quot;input&quot;, { type: &quot;checkbox&quot; }, span);
+        testCheckbox.test = test;
+        testCheckbox.onchange = this._onChangeTestCheckbox.bind(this);
+        testCheckbox.suiteCheckbox = suiteCheckbox;
</ins><span class="cx"> 
</span><del>-    updateSuiteCheckbox(testsList, suiteCheckbox);
-}
</del><ins>+        suiteCheckbox.testsElements.push(testElement);
+        span.appendChild(document.createTextNode(&quot; &quot; + test.name));
+        return testElement;
+    },
</ins><span class="cx"> 
</span><del>-function updateSuiteCheckbox(testsList, suiteCheckbox) {
-    var numberEnabledTests = 0;
-    var testCheckboxes = testsList.querySelectorAll(&quot;input&quot;);
-    var totalCheckboxes = testCheckboxes.length;
-    for (var i = 0; i &lt; totalCheckboxes; ++i) {
-        if (testCheckboxes[i].checked)
-            ++numberEnabledTests;
-    }
-    suiteCheckbox.checked = numberEnabledTests &gt; 0;
-    suiteCheckbox.indeterminate = numberEnabledTests &gt; 0 &amp;&amp; numberEnabledTests &lt; totalCheckboxes;
-}
</del><ins>+    createElements: function()
+    {
+        var treeElement = this._treeElement();
</ins><span class="cx"> 
</span><del>-function localStorageNameForTest(suite, test) {
-    return suite.name + &quot;/&quot; + test.name;
-}
</del><ins>+        Suites.forEach(function(suite, index) {
+            var suiteElement = this._createSuiteElement(treeElement, suite, &quot;suite-&quot; + index);
+            var listElement = DocumentExtension.createElement(&quot;ul&quot;, {}, suiteElement);
+            var suiteCheckbox = this._checkboxElement(suiteElement);
</ins><span class="cx"> 
</span><del>-function populateSettings() {
-    var suitesDiv = document.getElementById(&quot;suites&quot;);
</del><ins>+            suite.tests.forEach(function(test) {
+                var testElement = this._createTestElement(listElement, test, suiteCheckbox);
+            }, this);
+        }, this);
+    },
+    
+    updateUIFromLocalStorage: function()
+    {
+        var suitesElements = this._suitesElements();
+        
+        for (var i = 0; i &lt; suitesElements.length; ++i) {
+            var suiteElement = suitesElements[i];
+            var suiteCheckbox = this._checkboxElement(suiteElement);
+            var suite = suiteCheckbox.suite;
+            
+            suiteCheckbox.testsElements.forEach(function(testElement) {
+                var testCheckbox = this._checkboxElement(testElement);
+                var test = testCheckbox.test;
+                
+                var str = localStorage.getItem(this._localStorageNameForTest(suite, test));
+                if (str === null)
+                    return;
</ins><span class="cx"> 
</span><del>-    var suitesList = document.createElement(&quot;ul&quot;);
-    suitesDiv.appendChild(suitesList);
</del><ins>+                var value = JSON.parse(str);
+                testCheckbox.checked = value.checked;
+            }, this);
</ins><span class="cx"> 
</span><del>-    Suites.forEach(function(suite) {
-        var suiteItem = document.createElement(&quot;li&quot;);
-        suitesList.appendChild(suiteItem);
</del><ins>+            this._updateSuiteCheckboxState(suiteCheckbox);
+        }
+        
+        this._updateStartButtonState();
+    },
</ins><span class="cx"> 
</span><del>-        var suiteLabel = document.createElement(&quot;label&quot;);
-        suiteItem.appendChild(suiteLabel);
</del><ins>+    updateLocalStorageFromUI: function()
+    {
+        var suitesElements = this._suitesElements();
+        var suites = [];
+        
+        for (var i = 0; i &lt; suitesElements.length; ++i) {
+            var suiteElement = suitesElements[i];
+            var suiteCheckbox = this._checkboxElement(suiteElement);
+            var suite = suiteCheckbox.suite;
</ins><span class="cx"> 
</span><del>-        var suiteCheckbox = document.createElement(&quot;input&quot;);
-        suiteCheckbox.setAttribute(&quot;type&quot;, &quot;checkbox&quot;);
-        suiteCheckbox.suite = suite;
-        suiteCheckbox.onchange = updateSuiteSelection;
-        suiteLabel.appendChild(suiteCheckbox);
-        suiteLabel.appendChild(document.createTextNode(&quot; &quot; + suite.name));
</del><ins>+            var tests = [];
+            suiteCheckbox.testsElements.forEach(function(testElement) {
+                var testCheckbox = this._checkboxElement(testElement);
+                var test = testCheckbox.test;
+                
+                if (testCheckbox.checked)
+                    tests.push(test);
</ins><span class="cx"> 
</span><del>-        var testsList = document.createElement(&quot;ul&quot;);
-        suiteItem.appendChild(testsList);
</del><ins>+                var value = { checked: testCheckbox.checked }; 
+                localStorage.setItem(this._localStorageNameForTest(suite, test), JSON.stringify(value));
+            }, this);
</ins><span class="cx"> 
</span><del>-        suite.tests.forEach(function(test) {
-            var testItem = document.createElement(&quot;li&quot;);
-            testsList.appendChild(testItem);
</del><ins>+            if (tests.length)
+                suites.push(new Suite(suiteCheckbox.suite.name, tests));
+        }
</ins><span class="cx"> 
</span><del>-            var testLabel = document.createElement(&quot;label&quot;);
-            testItem.appendChild(testLabel);
</del><ins>+        return suites;
+    }
+}
</ins><span class="cx"> 
</span><del>-            var testCheckbox = document.createElement(&quot;input&quot;);
-            testCheckbox.setAttribute(&quot;type&quot;, &quot;checkbox&quot;);
-            testCheckbox.test = test;
-            testCheckbox.onchange = updateTestSelection;
-            if (+localStorage.getItem(localStorageNameForTest(suite, test)))
-                testCheckbox.checked = true;
-            testLabel.appendChild(testCheckbox);
-            testLabel.appendChild(document.createTextNode(&quot; &quot; + test.name));
-        });
</del><ins>+window.benchmarkController =
+{
+    initialize: function()
+    {
+        sectionsManager.setupSectionStyle();
+        optionsManager.updateUIFromLocalStorage();
+        suitesManager.createElements();
+        suitesManager.updateUIFromLocalStorage();
+    },
</ins><span class="cx"> 
</span><del>-        updateSuiteCheckbox(testsList, suiteCheckbox);
-    });
</del><ins>+    _runBenchmark: function(suites, options)
+    {
+        benchmarkRunnerClient.initialize(suites, options);
+        var frameContainer = document.querySelector(&quot;#running &gt; #running-test&quot;);
+        var runner = new BenchmarkRunner(suites, frameContainer || document.body, benchmarkRunnerClient);
+        runner.runMultipleIterations();
+    },
</ins><span class="cx"> 
</span><del>-    var interval = localStorage.getItem(&quot;test-interval&quot;);
-    if (interval) {
-        document.getElementById(&quot;test-interval&quot;).value = interval;
</del><ins>+    startTest: function()
+    {
+        var options = optionsManager.updateLocalStorageFromUI();
+        var suites = suitesManager.updateLocalStorageFromUI();
+        sectionsManager.setupRunningSectionStyle(options);
+        this._runBenchmark(suites, options);
+        sectionsManager.showSection(&quot;running&quot;);
+    },
+    
+    showResults: function()
+    {
+        sectionsManager.showScore(&quot;results&quot;, Strings[&quot;TEXT_RESULTS&quot;][0]);
+        sectionsManager.showSection(&quot;results&quot;, true);
+    },
+    
+    showJson: function()
+    {
+        sectionsManager.showScore(&quot;json&quot;, Strings[&quot;TEXT_RESULTS&quot;][0]);
+        sectionsManager.showSection(&quot;json&quot;, true);
+    },
+    
+    showTestGraph: function(testName, axes, samples, samplingTimeOffset)
+    {
+        sectionsManager.showTestName(&quot;test-graph&quot;, Strings[&quot;TEXT_RESULTS&quot;][1], testName);
+        sectionsManager.showSection(&quot;test-graph&quot;, true);
+        graph(&quot;section#test-graph &gt; data&quot;, new Insets(20, 50, 20, 50), axes, samples, samplingTimeOffset);
+    },
+
+    showTestJSON: function(testName, json)
+    {
+        sectionsManager.showTestName(&quot;test-json&quot;, Strings[&quot;TEXT_RESULTS&quot;][1], testName);
+        sectionsManager.showJSON(&quot;test-json&quot;, json);
+        sectionsManager.showSection(&quot;test-json&quot;, true);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><del>-document.addEventListener(&quot;DOMContentLoaded&quot;, initialize);
</del><ins>+
+document.addEventListener(&quot;DOMContentLoaded&quot;, benchmarkController.initialize());
</ins></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunnerresourcesbenchmarkrunnerjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/benchmark-runner.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -50,10 +50,11 @@
</span><span class="cx">     return promise;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function BenchmarkRunner(suites, client)
</del><ins>+function BenchmarkRunner(suites, frameContainer, client)
</ins><span class="cx"> {
</span><span class="cx">     this._suites = suites;
</span><span class="cx">     this._client = client;
</span><ins>+    this._frameContainer = frameContainer;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BenchmarkRunner.prototype.waitForElement = function(selector)
</span><span class="lines">@@ -72,25 +73,15 @@
</span><span class="cx">     return promise;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-BenchmarkRunner.prototype._appendFrame = function(src)
</del><ins>+BenchmarkRunner.prototype._appendFrame = function()
</ins><span class="cx"> {
</span><span class="cx">     var frame = document.createElement(&quot;iframe&quot;);
</span><span class="cx">     frame.setAttribute(&quot;scrolling&quot;, &quot;no&quot;);
</span><span class="cx"> 
</span><del>-    var marginLeft = parseInt(getComputedStyle(document.body).marginLeft);
-    var marginTop = parseInt(getComputedStyle(document.body).marginTop);
-    if (window.innerWidth &gt; 800 + marginLeft &amp;&amp; window.innerHeight &gt; 600 + marginTop) {
-        frame.style.left = marginLeft + &quot;px&quot;;
-        frame.style.top = marginTop + &quot;px&quot;;
-    } else {
-        frame.style.left = &quot;0px&quot;;
-        frame.style.top = &quot;0px&quot;;
-    }
-
</del><span class="cx">     if (this._client &amp;&amp; this._client.willAddTestFrame)
</span><span class="cx">         this._client.willAddTestFrame(frame);
</span><span class="cx"> 
</span><del>-    document.body.insertBefore(frame, document.body.firstChild);
</del><ins>+    this._frameContainer.insertBefore(frame, this._frameContainer.firstChild);
</ins><span class="cx">     this._frame = frame;
</span><span class="cx">     return frame;
</span><span class="cx"> }
</span><span class="lines">@@ -167,21 +158,21 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-BenchmarkRunner.prototype.runMultipleIterations = function(iterationCount)
</del><ins>+BenchmarkRunner.prototype.runMultipleIterations = function()
</ins><span class="cx"> {
</span><span class="cx">     var self = this;
</span><span class="cx">     var currentIteration = 0;
</span><span class="cx"> 
</span><span class="cx">     this._runNextIteration = function() {
</span><span class="cx">         currentIteration++;
</span><del>-        if (currentIteration &lt; iterationCount)
</del><ins>+        if (currentIteration &lt; self._client.iterationCount)
</ins><span class="cx">             self.runAllSteps();
</span><span class="cx">         else if (this._client &amp;&amp; this._client.didFinishLastIteration)
</span><span class="cx">             self._client.didFinishLastIteration();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (self._client &amp;&amp; self._client.willStartFirstIteration)
</span><del>-        self._client.willStartFirstIteration(iterationCount);
</del><ins>+        self._client.willStartFirstIteration();
</ins><span class="cx"> 
</span><span class="cx">     self.runAllSteps();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerrunnerresourcesgraphjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/runner/resources/graph.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/runner/resources/graph.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/runner/resources/graph.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -1,8 +1,10 @@
</span><del>-function graph(selector, size, margins, axes, samples, samplingTimeOffset)
</del><ins>+function graph(selector, margins, axes, samples, samplingTimeOffset)
</ins><span class="cx"> {
</span><span class="cx">     var element = document.querySelector(selector);
</span><del>-    element.textContent = null;
</del><ins>+    element.innerHTML = '';
</ins><span class="cx"> 
</span><ins>+    var size = Point.elementClientSize(element).subtract(margins.size);
+
</ins><span class="cx">     var x = d3.scale.linear()
</span><span class="cx">             .range([0, size.width])
</span><span class="cx">             .domain(d3.extent(samples, function(d) { return d.timeOffset; }));            
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsbouncingparticlesresourcesbouncingsvgimagesjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx">     
</span><span class="cx">     var attrs = { x: 0, y: 0, width: this._size.x, height: this._size.y };
</span><span class="cx">     var xlinkAttrs = { href: stage.imageSrc };
</span><del>-    this.element = Utilities.createSvgElement(&quot;image&quot;, attrs, xlinkAttrs, stage.element);
</del><ins>+    this.element = DocumentExtension.createSvgElement(&quot;image&quot;, attrs, xlinkAttrs, stage.element);
</ins><span class="cx">     this._move();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsbouncingparticlesresourcesbouncingsvgparticlesjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx"> 
</span><span class="cx"> BouncingSvgParticlesStage.prototype._createDefs = function()
</span><span class="cx"> {
</span><del>-    return Utilities.createSvgElement(&quot;defs&quot;, {}, {}, this.element);
</del><ins>+    return DocumentExtension.createSvgElement(&quot;defs&quot;, {}, {}, this.element);
</ins><span class="cx"> }
</span><span class="cx">                                                                
</span><span class="cx"> BouncingSvgParticlesStage.prototype._ensureDefsIsCreated = function()
</span><span class="lines">@@ -50,10 +50,10 @@
</span><span class="cx"> BouncingSvgParticlesStage.prototype._createClipStar = function()
</span><span class="cx"> {
</span><span class="cx">     var attrs = { id: &quot;star-clip&quot;, clipPathUnits: &quot;objectBoundingBox&quot; };
</span><del>-    var clipPath  = Utilities.createSvgElement(&quot;clipPath&quot;, attrs, {}, this._ensureDefsIsCreated());
</del><ins>+    var clipPath  = DocumentExtension.createSvgElement(&quot;clipPath&quot;, attrs, {}, this._ensureDefsIsCreated());
</ins><span class="cx"> 
</span><span class="cx">     attrs = { d: &quot;M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z&quot; };
</span><del>-    Utilities.createSvgElement(&quot;path&quot;, attrs, {}, clipPath);
</del><ins>+    DocumentExtension.createSvgElement(&quot;path&quot;, attrs, {}, clipPath);
</ins><span class="cx">     return clipPath;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsbouncingparticlesresourcesbouncingsvgshapesjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -19,13 +19,13 @@
</span><span class="cx">     switch (this._shape) {
</span><span class="cx">     case &quot;rect&quot;:
</span><span class="cx">         var attrs = { x: 0, y: 0, width: this._size.x, height: this._size.y };
</span><del>-        this.element = Utilities.createSvgElement(&quot;rect&quot;, attrs, {}, stage.element);
</del><ins>+        this.element = DocumentExtension.createSvgElement(&quot;rect&quot;, attrs, {}, stage.element);
</ins><span class="cx">         break;
</span><span class="cx">     
</span><span class="cx">     case &quot;circle&quot;:
</span><span class="cx">     default:
</span><span class="cx">         var attrs = { cx: this._size.x / 2, cy: this._size.y / 2, r: Math.min(this._size.x, this._size.y) / 2 };
</span><del>-        this.element = Utilities.createSvgElement(&quot;circle&quot;, attrs, {}, stage.element);
</del><ins>+        this.element = DocumentExtension.createSvgElement(&quot;circle&quot;, attrs, {}, stage.element);
</ins><span class="cx">         break;        
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -58,11 +58,11 @@
</span><span class="cx"> BouncingSvgShapesStage.prototype.createGradient = function(stops)
</span><span class="cx"> {
</span><span class="cx">     var attrs = { id: &quot;gadient-&quot; + ++this._gradientsCount };
</span><del>-    var gradient = Utilities.createSvgElement(&quot;linearGradient&quot;, attrs, {}, this._ensureDefsIsCreated());    
</del><ins>+    var gradient = DocumentExtension.createSvgElement(&quot;linearGradient&quot;, attrs, {}, this._ensureDefsIsCreated());    
</ins><span class="cx">     
</span><span class="cx">     for (var i = 0; i &lt; stops; ++i) {
</span><span class="cx">         attrs = { offset: i * 100 / stops + &quot;%&quot;, 'stop-color': this.randomColor() };
</span><del>-        Utilities.createSvgElement(&quot;stop&quot;, attrs, {}, gradient);
</del><ins>+        DocumentExtension.createSvgElement(&quot;stop&quot;, attrs, {}, gradient);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return gradient;
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsresourcesmainjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/resources/main.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/resources/main.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/resources/main.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">         var currentFrameRate = Math.floor(1000 / (measureTimeDelta / this._measureFrameCount));
</span><span class="cx">          
</span><span class="cx">         // Use Kalman filter to get a more non-fluctuating frame rate.
</span><del>-        if (this._benchmark.options.estimatedFrameRate)
</del><ins>+        if (this._benchmark.options[&quot;estimated-frame-rate&quot;])
</ins><span class="cx">             currentFrameRate = this._estimator.estimate(measureTimeDelta, currentFrameRate);
</span><span class="cx">         
</span><span class="cx">         // Adjust the test to reach the desired FPS.
</span><span class="lines">@@ -146,9 +146,9 @@
</span><span class="cx">     var lowValue = -parseInt(this._options[&quot;addLimit&quot;]) || 1;
</span><span class="cx">     var highValue = parseInt(this._options[&quot;removeLimit&quot;]) || 1;
</span><span class="cx">     
</span><del>-    this._controller = new PIDController(gain, options.frameRate, lowValue, highValue);
</del><ins>+    this._controller = new PIDController(gain, options[&quot;frame-rate&quot;], lowValue, highValue);
</ins><span class="cx">     this._sampler = new Sampler(2);
</span><del>-    this._state = new BenchmarkState(this.options.testInterval);    
</del><ins>+    this._state = new BenchmarkState(this.options[&quot;test-interval&quot;] * 1000);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Benchmark.prototype =
</span><span class="lines">@@ -179,7 +179,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         var tuneValue = 0;
</span><del>-        if (!(this._isSampling &amp;&amp; this.options.fixTestComplexity)) {
</del><ins>+        if (!(this._isSampling &amp;&amp; this.options[&quot;fix-test-complexity&quot;])) {
</ins><span class="cx">             // The relationship between frameRate and test complexity is inverse-proportional so we
</span><span class="cx">             // need to use the negative of PIDController.tune() to change the complexity of the test.
</span><span class="cx">             tuneValue = -this._controller.tune(currentFrameRate, timeDelta / 1000);
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsresourcesstagejs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/resources/stage.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/resources/stage.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/resources/stage.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -177,7 +177,7 @@
</span><span class="cx">     if (!this._recordTable || !this._progressBar || !this._test)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (this.options.showRunningResults)
</del><ins>+    if (this.options[&quot;show-running-results&quot;])
</ins><span class="cx">         this._recordTable.showRecord(this._test.name, message, this._sampler.toJSON(true, false));
</span><span class="cx"> 
</span><span class="cx">     this._progressBar.setPos(progress);
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometertestsresourcesutilitiesjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/resources/utilities.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/resources/utilities.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/resources/utilities.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -39,22 +39,5 @@
</span><span class="cx">     mergeObjects: function(obj1, obj2)
</span><span class="cx">     {
</span><span class="cx">         return this.extendObject(this.copyObject(obj1), obj2);
</span><del>-    },
-    
-    createSvgElement: function(name, attrs, xlinkAttrs, parent)
-    {
-        const svgNamespace = &quot;http://www.w3.org/2000/svg&quot;;
-        const xlinkNamespace = &quot;http://www.w3.org/1999/xlink&quot;;
-
-        var element = document.createElementNS(svgNamespace, name);
-        
-        for (var key in attrs)
-            element.setAttribute(key, attrs[key]);
-            
-        for (var key in xlinkAttrs)
-            element.setAttributeNS(xlinkNamespace, key, xlinkAttrs[key]);
-            
-        parent.appendChild(element);
-        return element;
</del><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerteststextlayeringtexthtml"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/text/layering-text.html (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/text/layering-text.html        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/text/layering-text.html        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -3,12 +3,12 @@
</span><span class="cx"> &lt;head&gt;
</span><span class="cx">     &lt;style&gt;
</span><span class="cx">         .text-layer {
</span><del>-            font-size: 5.5px;
</del><span class="cx">             position: absolute;
</span><span class="cx">             left: 0px;
</span><span class="cx">             top: 0px;
</span><span class="cx">             padding: 3px;
</span><span class="cx">             background-color: transparent;
</span><ins>+            line-height: 1.2;
</ins><span class="cx">         }
</span><span class="cx">     &lt;/style&gt;  
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../resources/stage.css&quot;&gt;
</span></span></pre></div>
<a id="trunkPerformanceTestsAnimometerteststextresourceslayeringtextjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/Animometer/tests/text/resources/layering-text.js        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -6,6 +6,7 @@
</span><span class="cx">     this._textItemIndex = 0;
</span><span class="cx">     this._colorIndex = 0;
</span><span class="cx">     this._animateCounts = 0;
</span><ins>+    this._setFontSize();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LayeringTextStage.textItems = [
</span><span class="lines">@@ -137,6 +138,14 @@
</span><span class="cx"> LayeringTextStage.prototype = Object.create(Stage.prototype);
</span><span class="cx"> LayeringTextStage.prototype.constructor = LayeringTextStage;
</span><span class="cx"> 
</span><ins>+LayeringTextStage.prototype._setFontSize = function()
+{
+    var lineHeight = this.size.height / LayeringTextStage.colorableTextItems;
+    var fontHeight = lineHeight / 1.5;
+    var fontSize = fontHeight * 72.0 / 96.0;
+    DocumentExtension.insertCssRuleAfter(&quot;.text-layer&quot;, &quot;.text-layer { font-size: &quot; + fontSize.toFixed(2) + &quot;px; }&quot;);
+}
+
</ins><span class="cx"> LayeringTextStage.prototype._nextTextItem = function(textItemFlags)
</span><span class="cx"> {
</span><span class="cx">     var textItem = LayeringTextStage.textItems[this._textItemIndex];
</span></span></pre></div>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (191852 => 191853)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2015-11-01 07:54:38 UTC (rev 191852)
+++ trunk/PerformanceTests/ChangeLog        2015-11-01 08:26:46 UTC (rev 191853)
</span><span class="lines">@@ -1,3 +1,226 @@
</span><ins>+2015-11-01  Said Abou-Hallawa  &lt;sabouhallawa@apple,com&gt;
+
+        Make the size of the benchmark canvas adaptive to the screen size and screen resolution
+        https://bugs.webkit.org/show_bug.cgi?id=150530
+
+        Reviewed by Darin Adler.
+        
+        We want to set the size of the benchmark stage dynamically such that it
+        depends on the screen resolution and the device scale factor. This patch 
+        does more than that because the home page css was not done properly. To
+        use the flex box layout, the animometer.css has to be rewritten almost from
+        scratch. The suites tree has to be rewritten also because it was not collapsing
+        and with the flex box layout it was going outside of the window area. The 
+        options handling and the local storage handling had to be rewritten to
+        allow more flexibility with this patch and the future patches. The code
+        in animometer.js was reorganized into objects to allow distributing the code
+        nicely among separate entities.
+
+        * Animometer/resources/extensions.js:
+        (Point.elementClientSize): Returns the client size of an HTMLElement as a Point object.
+        (Insets.prototype.get width): Follow the function opening brace style guidelines.
+        (Insets.prototype.get height):
+        (Insets.prototype.get size): Returns the size of an Insets as a Point object.
+        
+        (window.DocumentExtension): Provides document helper functions. It should be assailable from the runner and the tests.
+        (window.DocumentExtension.createElement): Creates an HTMLElement given its name, attributes and parentElement. 
+        (window.DocumentExtension.createSvgElement): Creates an SVGElement given its name, attributes and parentElement (moved from utilities.js). 
+        (window.DocumentExtension.insertCssRuleAfter): Inserts a CSS rule after an exiting rule given its text.
+        
+        (ResultsTable.prototype._showHeader): Use DocumentExtension functions.
+        (ResultsTable.prototype._showGraph): Use DocumentExtension functions and create a real button for &quot;Graph...&quot; option.
+        (ResultsTable.prototype._showJSON): Use DocumentExtension functions and create a real button for &quot;JSON...&quot; option.
+        (Options): Deleted.
+        
+        * Animometer/runner/animometer.html: Restructure the page to use the flex box layout.
+        
+        * Animometer/runner/resources/animometer.css:
+        (html,body):
+        (button):
+        
+        (button.large-button):The large button appears in the animometer.html.
+        (button.large-button:active):
+        (button.large-button:disabled):
+        
+        (button.small-button): The small button appears in the results table.
+        (button.small-button:active):
+        
+        (.tree): The tree class is used to list the suites and their tests.
+        (.tree .expand-button): This button expands a tree element.
+        (.tree .expand-button ~ ul): Hide the children (&lt;ul&gt;...&lt;/ul&gt;) of a parent node by default.
+        (.tree .expand-button:checked ~ ul): Show the children of a parent node only when checked.
+        (.tree ul): Hide the list bullets.
+        (.tree li): Indent every node in the tree relative to its parent.
+        (.tree ul li): Indent all the non top level nodes only (the tests nodes in our case).
+        (.tree &gt; li:last-child): Do not indent the bottom of the last child node.
+        (.tree-label): Style for all the labels in the tree.
+        (label.tree-label): Style for the labels in the top level only (the suites nodes in our case).
+        (label.tree-label:before): Style the unchecked case of the expand-button.
+        (:checked ~ label.tree-label:before): Style the checked case of the expand-button.
+        
+        (table.results-table): The results table appears while running the test and at the end.
+        (.results-table td):
+        (.results-table th):
+        
+        (div.results-json): The JSON div appears per test or for the whole run.
+        
+        (main): This is the flex box container.
+        
+        (section): A section is displayed exclusively inside the &lt;main&gt;. It is hidden by default.
+        (section.selected): When it is selected, its layout is flex layout.
+        (section &gt; footer): The header or the footer of a section should not take more than 15% of the container.
+        
+        (section#home): The home section has &lt;suites&gt; and &lt;options&gt; parts to be laid out in the middle.
+        (section#home &gt; options): 
+        (section#home &gt; suites): The &lt;suites&gt; should not take more than 40% of the width.
+        (section#home &gt; options &gt; label): The benchmark title.
+        (section#home &gt; header &gt; h2): The benchmark title.
+        (section#home &gt; options &gt; label &gt; input[type=&quot;number&quot;]): Sets the width of the option edit control.
+        
+        (section#running): The running section contain the runner &lt;iframe&gt; which takes the whole area of the &lt;main&gt;.
+        (section#running &gt; #running-test): This is the &lt;iframe&gt; container.
+        (section#running &gt; #running-test &gt; iframe): The &lt;iframe&gt; is created by the runner for each test.
+        (section#running &gt; #progress): This is the progress bar.
+        (section#running &gt; #progress &gt; #progress-completed): This is another element which grows while the runner is progressing.
+        (section#running &gt; #record): This the container of the record results table which is shown while running a test.
+        
+        (section#results):
+        (section#json):
+        (section#test-json):
+        (section#test-graph): All these sections have the same layout. A &lt;data&gt; element is laid out between &lt;header&gt; and &lt;footer&gt;.
+
+        (section#results &gt; data):
+        (section#json &gt; data):
+        (section#test-json &gt; data):
+        (section#test-graph &gt; data): The &lt;data&gt; element should take 70% of the &lt;section&gt;.
+        
+        (section#test-graph &gt; data &gt; svg):
+        (.axis line):
+        (.left-samples): These styles are for the d3 graph.
+        
+        (section#test-json &gt; data): This is the style of the JSON &lt;data&gt; element.
+        
+        (iframe): Deleted.
+        (label, p): Deleted.
+        (section &gt; p): Deleted.
+        (section#home &gt; p): Deleted.
+        (section#home &gt; p:first-child): Deleted.
+        (#testContainer): Deleted.
+        (section#running #progress-completed): Deleted.
+        (section#results &gt; table): Deleted.
+        (section#results &gt; table td, th): Deleted.
+        (section#results &gt; table tr.alt, td): Deleted.
+        (section#results &gt; table th): Deleted.
+        (section#json &gt; textarea): Deleted.
+        (.options): Deleted.
+        (.options p): Deleted.
+        (#suites ul): Deleted.
+        (#suites ul ul): Deleted.
+        (#suites ul ul input, #suites ul ul label): Deleted.
+        (#suites.showTests ul ul): Deleted.
+        (.column): Deleted.
+        (input[type=&quot;number&quot;]): Deleted.
+        (.buttons): Deleted.
+        (.small-button): Deleted.
+        (#graphContainer): Deleted.
+        (.right-samples): Deleted.
+        (.sample-time): Deleted.
+        (.left-mean): Deleted.
+        (.right-mean): Deleted.
+        
+        * Animometer/runner/resources/animometer.js:
+        (window.benchmarkRunnerClient.initialize): Initialize the client object with the options and the suites.
+        (window.benchmarkRunnerClient.willStartFirstIteration): Use new css selectors for results and the record table.
+        (window.benchmarkRunnerClient.didFinishLastIteration): Move the code which sets the JSON text to sectionsManager.showJSON().
+        
+        (window.sectionsManager): Responsible of managing the &lt;section&gt;s elements inside animometer.html.
+        (window.sectionsManager._sectionHeaderH1Element): Return the &lt;h1&gt; inside the &lt;header&gt; of a given section.
+        (window.sectionsManager._sectionDataDivElement): Return the &lt;div&gt; inside the &lt;data&gt; of a given section.
+        (window.sectionsManager.showScore): Show the score of the last benchmark run.
+        (window.sectionsManager.showTestName): Show the test name for detailed results &lt;section&gt;.
+        (window.sectionsManager.showJSON): Shows the JSON text of the last benchmark or for a specific test.
+        (window.sectionsManager.showSection): Shows a specific &lt;section&gt; in the &lt;main&gt; container.
+        (window.sectionsManager.setupSectionStyle): Sets css attributes for all the &lt;section&gt;s.
+        (window.sectionsManager.setupRunningSectionStyle): Sets the css attributes for the running &lt;section&gt; only.
+        
+        (window.optionsManager): Responsible of managing the user options and streaming them to/form the localStorage.
+        (window.optionsManager._optionsElements): Returns the children &lt;input&gt; elements of the &lt;options&gt;.
+        (window.optionsManager.updateUIFromLocalStorage): Restore the values of the &lt;options&gt; UI elements from the local storage.
+        (window.optionsManager.updateLocalStorageFromUI): Saves the values of the &lt;options&gt; UI elements to the local storage.
+        
+        (window.suitesManager): Responsible of managing the user suites and streaming them to/form the localStorage.
+        (window.suitesManager._treeElement): Returns the suites tree container element.
+        (window.suitesManager._suitesElements): Returns a list of the suites elements.
+        (window.suitesManager._checkboxElement): Returns the checkbox element of a given suite.
+        (window.suitesManager._localStorageNameForTest): Generates a string for the tuple &lt;suite, test&gt; to be saved in the localStorage.
+        (window.suitesManager._updateSuiteCheckboxState): Updates the state of a suite checkbox from the state of its tests' checkboxes.
+        (window.suitesManager._updateStartButtonState): Updates the state of the start button from the state of the suites' checkboxes.
+        (window.suitesManager._onChangeSuiteCheckbox): Called when a suite checkbox is clicked.
+        (window.suitesManager._onChangeTestCheckbox): Called when a test checkbox is clicked.
+        (window.suitesManager._createSuiteElement): Creates suite node in the suites tree.
+        (window.suitesManager._createTestElement): Creates test node in the suites tree.
+        (window.suitesManager.createElements): Creates the suites tree dynamically from the array Suites.
+        (window.suitesManager.updateUIFromLocalStorage): Restore the values of the &lt;suites&gt; UI elements from the local storage.
+        (window.suitesManager.updateLocalStorageFromUI): aves the values of the &lt;suites&gt; UI elements to the local storage.
+        
+        (window.benchmarkController): This is the UI controller of the animometer.html page.
+        (window.benchmarkController.initialize): Called when the animometer.html page is loaded.
+        (window.benchmarkController._runBenchmark): Starts a benchmark run.
+        (window.benchmarkController.startTest): Called when the &quot;Start Test&quot; button is clicked.
+        (window.benchmarkController.showResults): Called at the end of the test to show the final results.
+        (window.benchmarkController.showJson): Called from the results page to show the JSON of the last benchmark run.
+        (window.benchmarkController.showTestGraph): Called from the results the table to show a graph for the samples of a specific test.
+        (window.benchmarkController.showTestJSON): Called from the results the table to show a JSON for the samples of a specific test.
+        
+        (showSection): Deleted.
+        (startTest): Deleted.
+        (showResults): Deleted.
+        (showJson): Deleted.
+        (showTestGraph): Deleted.
+        (showTestJSON): Deleted.
+        (initialize.toggleTestsCheckbox.onchange): Deleted.
+        (initialize): Deleted.
+        (updateSuiteSelection): Deleted.
+        (updateTestSelection): Deleted.
+        (updateSuiteCheckbox): Deleted.
+        (localStorageNameForTest): Deleted.
+        (populateSettings.): Deleted.
+        (populateSettings): Deleted.
+        
+        * Animometer/runner/resources/benchmark-runner.js:
+        (BenchmarkRunner): Pass the frameContainer element to the BenchmarkRunner.
+        (BenchmarkRunner.prototype._appendFrame): Remove unused parameter unwanted styling code.
+        (BenchmarkRunner.prototype.runMultipleIterations):  Use the this._client.iterationCount instead of passing it as a parameter also.
+
+        * Animometer/runner/resources/graph.js:
+        (graph): Calculate the size of the chart from the container element.
+        
+        * Animometer/tests/bouncing-particles/resources/bouncing-svg-images.js:
+        (BouncingSvgImage):
+        * Animometer/tests/bouncing-particles/resources/bouncing-svg-particles.js:
+        (BouncingSvgParticlesStage.prototype._createDefs):
+        (BouncingSvgParticlesStage.prototype._createClipStar):        
+        * Animometer/tests/bouncing-particles/resources/bouncing-svg-shapes.js:
+        (BouncingSvgShape.prototype._createShape):
+        (BouncingSvgShapesStage.prototype.createGradient):
+        Call DocumentExtension.createSvgElement() instead of calling Utilities.createSvgElement().
+        
+        * Animometer/tests/resources/main.js:
+        (Animator.prototype.animate):
+        (Benchmark):
+        (Benchmark.prototype.update):
+        * Animometer/tests/resources/stage.js:
+        (StageBenchmark.prototype.showResults):
+        Rename the options to match the &lt;input&gt; ids in animometer.html.
+        
+        * Animometer/tests/resources/utilities.js:
+        (window.Utilities.createSvgElement): Deleted.
+        
+        * Animometer/tests/text/layering-text.html:
+        * Animometer/tests/text/resources/layering-text.js:
+        (LayeringTextStage):
+        (LayeringTextStage.prototype._setFontSize): Sets the size of the text dynamically such that they all fit in one stage.
+
</ins><span class="cx"> 2015-10-29  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Animometer computes frame rate incorrectly
</span></span></pre>
</div>
</div>

</body>
</html>