Browse Source

[core] Add ko binding for log auto scroller

When attached to an element this binding makes the element act like a log viewer. If the scroll position is at the bottom it will keep scrolling as new data is added, and if the scroll position is elsewhere it will stay there.
Johan Ahlen 10 years ago
parent
commit
4370a62

+ 1 - 1
apps/spark/src/spark/templates/editor_components.mako

@@ -366,7 +366,7 @@ from django.utils.translation import ugettext as _
 
       <div data-bind="visible: showLogs, css: resultsKlass" style="margin-top: 5px">
         <pre data-bind="visible: result.logs().length == 0" class="logs logs-bigger">${ _('No logs available at this moment.') }</pre>
-        <pre data-bind="visible: result.logs().length > 0, text: result.logs" class="logs logs-bigger"></pre>
+        <pre data-bind="visible: result.logs().length > 0, text: result.logs, logScroller: result.logs" class="logs logs-bigger"></pre>
       </div>
 
       <div data-bind="visible: result.errors().length > 0, css: errorsKlass" style="margin-top: 5px">

+ 31 - 0
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -37,6 +37,37 @@ ko.bindingHandlers.fadeVisible = {
   }
 };
 
+ko.bindingHandlers.logScroller = {
+  init: function (element, valueAccessor) {
+    var $element = $(element);
+
+    $element.on("scroll", function () {
+      $element.data('lastScrollTop', $element.scrollTop());
+    });
+
+    function autoLogScroll () {
+      var elementHeight = $element.innerHeight();
+      var lastScrollTop = $element.data('lastScrollTop') || 0;
+      var lastScrollHeight = $element.data('lastScrollHeight') || elementHeight;
+
+      var stickToBottom = (lastScrollTop + elementHeight) === lastScrollHeight;
+
+      if (stickToBottom) {
+        $element.scrollTop(element.scrollHeight - $element.height());
+        $element.data('lastScrollTop', $element.scrollTop());
+      }
+
+      $element.data('lastScrollHeight', element.scrollHeight);
+    }
+
+    var logValue = valueAccessor();
+    logValue.subscribe(function () {
+      window.setTimeout(autoLogScroll, 200);
+    });
+
+    autoLogScroll();
+  }
+};
 
 ko.bindingHandlers.multiCheck = {
   init: function (element, valueAccessor) {