Title: [115131] trunk/Tools
Revision
115131
Author
[email protected]
Date
2012-04-24 16:33:40 -0700 (Tue, 24 Apr 2012)

Log Message

Replace garden-o-matic accordion UI with a panel UI
https://bugs.webkit.org/show_bug.cgi?id=84081

Reviewed by Dimitri Glazkov.

This is a nicer UI to work with and makes it easier to embed the flakiness dashboard,
since we can reuse the same iframe without moving it in the DOM.

Also, excise unnecessary jquery-isms.

* BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js:
* BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js:
* BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css:

Modified Paths

Diff

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js (115130 => 115131)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js	2012-04-24 23:16:03 UTC (rev 115130)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js	2012-04-24 23:33:40 UTC (rev 115131)
@@ -170,21 +170,18 @@
         this._delegate.fetchResultsURLs(this._failureInfo, function(resultsURLs) {
             var resultsGrid = new ui.results.ResultsGrid();
             resultsGrid.addResults(resultsURLs);
+
             $(this).empty().append(
                 new ui.actions.List([
                     new ui.actions.Previous(),
                     new ui.actions.Next()
                 ])).append(resultsGrid);
+
+
         }.bind(this));
     },
 });
 
-// jQuery's builtin accordion overrides mousedown, which means you can't select the header text
-// or click on the link to the flakiness dashboard.
-$('.ui-accordion-header').live('click', function() {
-    $(this).trigger('customaccordionclick');
-})
-
 function isAnyReftest(testName, resultsByTest)
 {
     return Object.keys(resultsByTest[testName]).map(function(builder) {
@@ -199,95 +196,119 @@
     {
         this.className = 'test-selector';
         this._delegate = delegate;
-        this._length = 0;
+        this._resultsByTest = resultsByTest;
 
+        var topPanel = document.createElement('div');
+        topPanel.className = 'top-panel';
+        this.appendChild(topPanel);
+
+        this._appendResizeHandle();
+
+        var bottomPanel = document.createElement('div');
+        bottomPanel.className = 'bottom-panel';
+        this.appendChild(bottomPanel);
+
         Object.keys(resultsByTest).sort().forEach(function(testName) {
             var nonLinkTitle = document.createElement('a');
-            $(nonLinkTitle).addClass('non-link-title');
-            $(nonLinkTitle).text(testName);
+            nonLinkTitle.classList.add('non-link-title');
+            nonLinkTitle.textContent = testName;
 
             var linkTitle = document.createElement('a');
-            $(linkTitle).addClass('link-title');
-            $(linkTitle).attr('href', ui.urlForFlakinessDashboard([testName])).text(testName);
+            linkTitle.classList.add('link-title');
+            linkTitle.setAttribute('href', ui.urlForFlakinessDashboard([testName]))
+            linkTitle.textContent = testName;
 
             var header = document.createElement('h3');
-            if (isAnyReftest(testName, resultsByTest))
-                $(header).append('<div class="non-action-button">Reftests cannot be rebaselined. Email [email protected] if unsure how to fix this.</div>');
-            else
-                $(header).append(new ui.actions.List([new ui.actions.Rebaseline().makeDefault()]));
-
-            $(header).append(nonLinkTitle).append(linkTitle);
-            this.appendChild(header);
-            this.appendChild(this._delegate.contentForTest(testName));
-            ++this._length; // There doesn't seem to be any good way to get this information from accordion.
+            header.appendChild(nonLinkTitle);
+            header.appendChild(linkTitle);
+            header.addEventListener('click', this._showResults.bind(this, header));
+            topPanel.appendChild(header);
         }, this);
+    },
+    _appendResizeHandle: function()
+    {
+        var resizeHandle = document.createElement('div');
+        resizeHandle.className = 'resize-handle';
+        this.appendChild(resizeHandle);
 
-        $(this).accordion({
-            collapsible: true,
-            autoHeight: false,
-            event: 'customaccordionclick',
-        });
-        $(this).accordion('activate', false);
-        $(this).bind('accordionchange', function(event, ui) {
-            // jQuery accordion has a bug where it scrolls to the top of the page if you click on
-            // any item. Scroll offscreen content into view. This isn't pretty after the animation,
-            // but it's better than having to manually scroll all the time.
-            var header = $('.ui-state-active.ui-accordion-header')[0];
-            var results = $('.ui-accordion-content-active')[0];
-            // Since the results load async, we need to guess what the height will be.
-            var estimatedResultsHeight = 1000;
-            if (header.offsetTop < document.body.scrollTop || results.offsetTop + estimatedResultsHeight > document.body.scrollTop + document.documentElement.clientHeight) {
-                var offsetFromWindowTop = header.offsetHeight;
-                document.body.scrollTop = header.offsetTop - offsetFromWindowTop;
-            }
-        });
+        resizeHandle.addEventListener('mousedown', function(event) {
+            this._is_resizing = true;
+            event.preventDefault();
+        }.bind(this));
+
+        var cancelResize = function(event) { this._is_resizing = false; }.bind(this);
+        this.addEventListener('mouseup', cancelResize);
+        // FIXME: Use addEventListener once WebKit adds support for mouseleave/mouseenter.
+        $(window).bind('mouseleave', cancelResize);
+
+        this.addEventListener('mousemove', function(event) {
+            if (!this._is_resizing)
+                return;
+            var mouseY = event.clientY + document.body.scrollTop - this.offsetTop;
+            var percentage = 100 * mouseY / this.offsetHeight;
+            document.querySelector('.top-panel').style.maxHeight = percentage + '%';
+        }.bind(this))
     },
+    _showResults: function(header)
+    {
+        if (!header)
+            return false;
+
+        var activeHeader = this.querySelector('.active')
+        if (activeHeader)
+            activeHeader.classList.remove('active');
+        header.classList.add('active');
+
+        var bottomPanel = this.querySelector('.bottom-panel')
+        bottomPanel.innerHTML = '';
+        bottomPanel.appendChild(this._delegate.contentForTest(this.currentTestName()));
+
+        var topPanel = this.querySelector('.top-panel');
+        topPanel.scrollTop = header.offsetTop;
+        if (header.offsetTop - topPanel.scrollTop < header.offsetHeight)
+            topPanel.scrollTop = topPanel.scrollTop - header.offsetHeight;
+
+        var resultsDetails = this.querySelectorAll('.results-detail');
+        if (resultsDetails.length)
+            resultsDetails[0].show();
+        setTimeout(function() {
+            Array.prototype.forEach.call(resultsDetails, function(resultsDetail) {
+                resultsDetail.show();
+            });
+        }, kResultsPrefetchDelayMS);
+
+        return true;
+    },
     nextResult: function()
     {
-        var activeIndex = $(this).accordion('option', 'active');
-        if ($('.builder-selector', this)[activeIndex].nextResult())
+        if (this.querySelector('.builder-selector').nextResult())
             return true;
         return this.nextTest();
     },
     previousResult: function()
     {
-        var activeIndex = $(this).accordion('option', 'active');
-        if ($('.builder-selector', this)[activeIndex].previousResult())
+        if (this.querySelector('.builder-selector').previousResult())
             return true;
         return this.previousTest();
     },
     nextTest: function()
     {
-        var nextIndex = $(this).accordion('option', 'active') + 1;
-        if (nextIndex >= this._length) {
-            $(this).accordion('option', 'active', false);
-            return false;
-        }
-        $(this).accordion('option', 'active', nextIndex);
-        $('.builder-selector', this)[nextIndex].firstResult();
-        return true;
+        return this._showResults(this.querySelector('.active').nextSibling);
     },
     previousTest: function()
     {
-        var previousIndex = $(this).accordion('option', 'active') - 1;
-        if (previousIndex < 0) {
-            $(this).accordion('option', 'active', false);
-            return false;
-        }
-        $(this).accordion('option', 'active', previousIndex);
-        $('.builder-selector', this)[previousIndex].lastResult();
-        return true;
+        var succeeded = this._showResults(this.querySelector('.active').previousSibling);
+        if (succeeded)
+            this.querySelector('.builder-selector').lastResult();
+        return succeeded;
     },
     firstResult: function()
     {
-        $(this).accordion('option', 'active', 0);
-        var builderSelector = $('.builder-selector', this)[0];
-        builderSelector && builderSelector.firstResult();
+        this._showResults(this.querySelector('h3'));
     },
     currentTestName: function()
     {
-        var currentIndex = $(this).accordion('option', 'active');
-        return $('h3 .non-link-title', this)[currentIndex].textContent;
+        return this.querySelector('.active .non-link-title').textContent;
     }
 });
 
@@ -347,7 +368,15 @@
     },
     contentForTest: function(testName)
     {
+        var rebaselineAction;
+        if (isAnyReftest(testName, this._resultsByTest))
+            rebaselineAction = $('<div class="non-action-button">Reftests cannot be rebaselined. Email [email protected] if unsure how to fix this.</div>');
+        else
+            rebaselineAction = new ui.actions.List([new ui.actions.Rebaseline().makeDefault()]);
+        $(rebaselineAction).addClass('rebaseline-action');
+
         var builderSelector = new ui.results.BuilderSelector(this, testName, this._resultsByTest[testName]);
+        $(builderSelector).append(rebaselineAction).append($('<br style="clear:both">'));
         $(builderSelector).bind('tabsselect', function(event, ui) {
             // We will probably have pre-fetched the tab already, but we need to make sure.
             ui.panel.show();
@@ -364,18 +393,6 @@
         $(this).empty();
         this._resultsByTest = resultsByTest;
         this._testSelector = new ui.results.TestSelector(this, resultsByTest);
-        $(this._testSelector).bind("accordionchangestart", function(event, ui) {
-            // Prefetch the first results from the network.
-            var resultsDetails = $('.results-detail', ui.newContent);
-            if (resultsDetails.length)
-                resultsDetails[0].show();
-            // Prefetch the rest kResultsPrefetchDelayMS later.
-            setTimeout(function() {
-                resultsDetails.each(function() {
-                    this.show();
-                });
-            }, kResultsPrefetchDelayMS);
-        });
         this.appendChild(this._testSelector);
     },
     fetchResultsURLs: function(failureInfo, callback)

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js (115130 => 115131)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js	2012-04-24 23:16:03 UTC (rev 115130)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js	2012-04-24 23:33:40 UTC (rev 115131)
@@ -72,26 +72,43 @@
     }
 };
 
-test('View', 8, function() {
+test('View', 16, function() {
     var delegate = {
         fetchResultsURLs: function(failureInfo, callback) { return; }
     };
 
     var view = new ui.results.View(delegate);
     view.setResultsByTest(kExampleResultsByTest);
+
     view.firstResult();
+    var testSelector = view.querySelector('.test-selector');
+    var topPanel = testSelector.querySelector('.top-panel');
+    equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
+    equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 0);
 
     view.nextResult();
-    equals($('.test-selector', view).accordion('option', 'active'), 0);
+    equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
     equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 1);
     equals(view.currentTestName(), 'scrollbars/custom-scrollbar-with-incomplete-style.html');
+
     view.nextResult();
-    equals($('.test-selector', view).accordion('option', 'active'), 1);
-    equals($($('.builder-selector', view)[1]).tabs('option', 'selected'), 0);
+    equals(topPanel.childNodes[1], topPanel.querySelector('.active'));;
+    equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 0);
     equals(view.currentTestName(), 'userscripts/another-test.html');
+
     view.previousResult();
-    equals($('.test-selector', view).accordion('option', 'active'), 0);
+    equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
     equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 1);
+
+    view.nextTest();
+    equals(topPanel.childNodes[1], topPanel.querySelector('.active'));;
+    equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 0);
+    equals(view.currentTestName(), 'userscripts/another-test.html');
+
+    view.previousTest();
+    equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
+    equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 1);
+    equals(view.currentTestName(), 'scrollbars/custom-scrollbar-with-incomplete-style.html');
 });
 
 test('View', 2, function() {
@@ -101,8 +118,9 @@
 
     var view = new ui.results.View(delegate);
     view.setResultsByTest(kExampleReftestResults);
+    view.firstResult();
 
-    equals($('.non-action-button', view).length, 2);
+    equals($('.non-action-button', view).length, 1);
     equals($('.action', view).length, 0);
 });
 

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css (115130 => 115131)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css	2012-04-24 23:16:03 UTC (rev 115130)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css	2012-04-24 23:33:40 UTC (rev 115131)
@@ -35,6 +35,14 @@
     padding: 5px;
 }
 
+.results-view ul.actions.rebaseline-action {
+    float: none;
+    position: absolute;
+    right: 4px;
+    top: 7px;
+    padding: 0;
+}
+
 .results-view ul.actions li, .ui-dialog ul.actions li {
     display: inline-block;
 }
@@ -83,18 +91,64 @@
     height: auto;
 }
 
-.ui-state-default .link-title, .ui-state-default .link-title:link, .ui-state-default .link-title:visited {
+.results-view .top-panel {
+    min-height: 100px;
+    max-height: 20%;
+    overflow: auto;
+    position: relative;
+}
+
+.results-view .resize-handle {
+    height: 5px;
+    text-align: center;
+    -webkit-user-select: none;
+    line-height: 5px;
+    cursor: ns-resize;
+    font-size: 5px;
+    font-weight: bold;
+    padding: 1px;
+}
+
+.results-view .resize-handle:before {
+    content: '|||';
+}
+
+.results-view .link-title,
+.results-view .active .non-link-title {
     display: none;
 }
-.ui-state-active .link-title, .ui-state-active .link-title:link, .ui-state-active .link-title:visited {
-    text-decoration: underline;
+
+.results-view .non-link-title,
+.results-view .active .link-title {
     display: inline-block;
 }
-/* Stupid CSS specificity rules. We need the .ui-accordion-header to override the builtin jquery styling on anchor tags in accordion headers. */
-.ui-state-active.ui-accordion-header .non-link-title, .ui-state-active .non-link-title:link, .ui-state-active .non-link-title:visited {
-    display: none;
+
+.results-view h3 {
+    font-size: 16px;
+    border-top: 1px solid #DDD;
+    margin: 0;
+    cursor: pointer;
 }
 
+.results-view h3:not(.active):hover {
+    background-color: #EEE;
+}
+
+.results-view .active {
+    background-color: #CCC;
+}
+
+/* CSS percentages in standards-mode are dumb. You need to have a percentage or fixed height
+   all the way up the tree in order to have percentages resolve. */
+html, body, #onebar, .results-view, .test-selector {
+    height: 100%;
+}
+
+#results {
+    height: -webkit-calc(100% - 39px);
+    box-sizing: border-box;
+}
+
 /*** status console ***/
 .status {
     position: fixed;

Modified: trunk/Tools/ChangeLog (115130 => 115131)


--- trunk/Tools/ChangeLog	2012-04-24 23:16:03 UTC (rev 115130)
+++ trunk/Tools/ChangeLog	2012-04-24 23:33:40 UTC (rev 115131)
@@ -1,3 +1,19 @@
+2012-04-16  Ojan Vafai  <[email protected]>
+
+        Replace garden-o-matic accordion UI with a panel UI
+        https://bugs.webkit.org/show_bug.cgi?id=84081
+
+        Reviewed by Dimitri Glazkov.
+
+        This is a nicer UI to work with and makes it easier to embed the flakiness dashboard,
+        since we can reuse the same iframe without moving it in the DOM.
+
+        Also, excise unnecessary jquery-isms.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results.js:
+        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/results_unittests.js:
+        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/styles/results.css:
+
 2012-04-24  Peter Beverloo  <[email protected]>
 
         [Chromium] DumpRenderTree should depend on base.gyp:test_support_base
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to