From 6e73923fbb07bdf8e959bb7926cc38ce09368d3b Mon Sep 17 00:00:00 2001
From: Piotr Sarnacki <drogus@gmail.com>
Date: Wed, 30 Dec 2015 10:36:08 +0100
Subject: [PATCH] Convert log-content component to js

---
 app/components/log-content.coffee | 157 ---------------------
 app/components/log-content.js     | 227 ++++++++++++++++++++++++++++++
 2 files changed, 227 insertions(+), 157 deletions(-)
 delete mode 100644 app/components/log-content.coffee
 create mode 100644 app/components/log-content.js

diff --git a/app/components/log-content.coffee b/app/components/log-content.coffee
deleted file mode 100644
index 09b5a225..00000000
--- a/app/components/log-content.coffee
+++ /dev/null
@@ -1,157 +0,0 @@
-`import Ember from 'ember'`
-`import LinesSelector from 'travis/utils/lines-selector'`
-`import LogFolder from 'travis/utils/log-folder'`
-`import config from 'travis/config/environment'`
-`import { plainTextLog as plainTextLogUrl } from 'travis/utils/urls'`
-
-Log.DEBUG = false
-Log.LIMIT = 10000
-
-Log.Scroll = (options) ->
-  options ||= {}
-  @beforeScroll = options.beforeScroll
-  this
-Log.Scroll.prototype = $.extend new Log.Listener,
-  insert: (log, data, pos) ->
-    @tryScroll() if @numbers
-    true
-
-  tryScroll: ->
-    if element = $("#log p:visible.highlight:first")
-      if @beforeScroll
-        @beforeScroll()
-      $('#main').scrollTop(0)
-      $('html, body').scrollTop(element.offset()?.top - (window.innerHeight / 3)) # weird, html works in chrome, body in firefox
-
-Log.Limit = (max_lines, limitedLogCallback) ->
-  @max_lines = max_lines || 1000
-  @limitedLogCallback = limitedLogCallback || (->)
-  this
-
-Log.Limit.prototype = Log.extend new Log.Listener,
-  count: 0,
-  insert: (log, node, pos) ->
-    if node.type == 'paragraph' && !node.hidden
-      @count += 1
-      if @limited
-        @limitedLogCallback()
-      return @count
-
-Object.defineProperty Log.Limit.prototype, 'limited',
-  get: ->
-    @count >= @max_lines
-
-LogContentComponent = Ember.Component.extend
-  popup: Ember.inject.service()
-
-  currentUserBinding: 'auth.currentUser'
-
-  didInsertElement: ->
-    console.log 'log view: did insert' if Log.DEBUG
-    @_super.apply this, arguments
-    @createEngine()
-
-  willDestroyElement: ->
-    console.log 'log view: will destroy' if Log.DEBUG
-    @teardownLog()
-
-  teardownLog: (log) ->
-    if log || log = @get('log')
-      parts = log.get('parts')
-      parts.removeArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
-      parts.destroy()
-      log.notifyPropertyChange('parts')
-      @lineSelector?.willDestroy()
-      if logElement = this.$('#log')
-        logElement.empty()
-
-  createEngine: (log) ->
-    if log || log = @get('log')
-      if logElement = this.$('#log')
-        logElement.empty()
-
-      log.onClear =>
-        @teardownLog()
-        @createEngine()
-
-      @scroll = new Log.Scroll beforeScroll: =>
-        @unfoldHighlight()
-      @limit = new Log.Limit Log.LIMIT, =>
-        @set('limited', true)
-      @engine = Log.create(listeners: [@scroll, @limit])
-      @engine.limit = @limit
-      @logFolder = new LogFolder(@$('#log'))
-      @lineSelector = new LinesSelector(@$('#log'), @scroll, @logFolder)
-      @observeParts(log)
-
-  didUpdateAttrs: (changes) ->
-    @_super.apply(this, arguments)
-
-    return unless changes.oldAttrs
-
-    if changes.newAttrs.job.value && changes.oldAttrs.job.value &&
-       changes.newAttrs.job.value != changes.oldAttrs.job.value
-
-      @teardownLog(changes.oldAttrs.job.value.get('log'))
-      @createEngine(changes.newAttrs.job.value.get('log'))
-
-  unfoldHighlight: ->
-    @lineSelector.unfoldLines()
-
-  observeParts: (log) ->
-    if log || log = @get('log')
-      parts = log.get('parts')
-      parts.addArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
-      parts = parts.slice(0)
-      @partsDidChange(parts, 0, null, parts.length)
-
-  partsDidChange: (parts, start, _, added) ->
-    console.log 'log view: parts did change' if Log.DEBUG
-    return unless @get('state') == 'inDOM'
-
-    for part, i in parts.slice(start, start + added)
-      # console.log "limit in log view: #{@get('limited')}"
-      break if @engine?.limit?.limited
-      @engine.set(part.number, part.content)
-
-  plainTextLogUrl: (->
-    if id = @get('log.job.id')
-      url = plainTextLogUrl(id)
-      if config.pro
-        url += "&access_token=#{@get('job.log.token')}"
-      url
-  ).property('job.log.id', 'job.log.token')
-
-  hasPermission: (->
-    if permissions = @get('currentUser.permissions')
-      permissions.contains parseInt(@get('job.repo.id'))
-  ).property('currentUser.permissions.length', 'job.repo.id')
-
-  canRemoveLog: (->
-    if job = @get('job')
-      job.get('canRemoveLog') && @get('hasPermission')
-  ).property('job.canRemoveLog', 'hasPermission')
-
-  showToTop: (->
-    @get('log.hasContent') && @get('job.canRemoveLog')
-  ).property('log.hasContent', 'job.canRemoveLog')
-  showTailing: Ember.computed.alias('showToTop')
-
-  actions:
-    toTop: () ->
-      Travis.tailing.stop()
-      $(window).scrollTop(0)
-
-    toggleTailing: ->
-      Travis.tailing.toggle()
-      @engine.autoCloseFold = !Travis.tailing.isActive()
-      event.preventDefault()
-
-    removeLogPopup: ->
-      if @get('canRemoveLog')
-        @get('popup').open('remove-log-popup')
-        return false
-
-  noop: -> # TODO required?
-
-`export default LogContentComponent`
diff --git a/app/components/log-content.js b/app/components/log-content.js
new file mode 100644
index 00000000..14110bc4
--- /dev/null
+++ b/app/components/log-content.js
@@ -0,0 +1,227 @@
+import Ember from 'ember';
+import LinesSelector from 'travis/utils/lines-selector';
+import LogFolder from 'travis/utils/log-folder';
+import config from 'travis/config/environment';
+import { plainTextLog as plainTextLogUrl } from 'travis/utils/urls';
+
+Log.DEBUG = false;
+
+Log.LIMIT = 10000;
+
+Log.Scroll = function(options) {
+  options = options || {};
+  this.beforeScroll = options.beforeScroll;
+  return this;
+};
+
+Log.Scroll.prototype = $.extend(new Log.Listener(), {
+  insert: function(log, data, pos) {
+    if (this.numbers) {
+      this.tryScroll();
+    }
+    return true;
+  },
+  tryScroll: function() {
+    var element, ref;
+    if (element = $("#log p:visible.highlight:first")) {
+      if (this.beforeScroll) {
+        this.beforeScroll();
+      }
+      $('#main').scrollTop(0);
+      return $('html, body').scrollTop(((ref = element.offset()) != null ? ref.top : void 0) - (window.innerHeight / 3));
+    }
+  }
+});
+
+Log.Limit = function(max_lines, limitedLogCallback) {
+  this.max_lines = max_lines || 1000;
+  this.limitedLogCallback = limitedLogCallback || (function() {});
+  return this;
+};
+
+Log.Limit.prototype = Log.extend(new Log.Listener(), {
+  count: 0,
+  insert: function(log, node, pos) {
+    if (node.type === 'paragraph' && !node.hidden) {
+      this.count += 1;
+      if (this.limited) {
+        this.limitedLogCallback();
+      }
+      return this.count;
+    }
+  }
+});
+
+Object.defineProperty(Log.Limit.prototype, 'limited', {
+  get: function() {
+    return this.count >= this.max_lines;
+  }
+});
+
+export default Ember.Component.extend({
+  popup: Ember.inject.service(),
+  currentUserBinding: 'auth.currentUser',
+
+  didInsertElement() {
+    if (Log.DEBUG) {
+      console.log('log view: did insert');
+    }
+    this._super.apply(this, arguments);
+    return this.createEngine();
+  },
+
+  willDestroyElement() {
+    if (Log.DEBUG) {
+      console.log('log view: will destroy');
+    }
+    return this.teardownLog();
+  },
+
+  teardownLog(log) {
+    var logElement, parts, ref;
+    if (log || (log = this.get('log'))) {
+      parts = log.get('parts');
+      parts.removeArrayObserver(this, {
+        didChange: 'partsDidChange',
+        willChange: 'noop'
+      });
+      parts.destroy();
+      log.notifyPropertyChange('parts');
+      if ((ref = this.lineSelector) != null) {
+        ref.willDestroy();
+      }
+      if (logElement = this.$('#log')) {
+        return logElement.empty();
+      }
+    }
+  },
+
+  createEngine(log) {
+    var logElement;
+    if (log || (log = this.get('log'))) {
+      if (logElement = this.$('#log')) {
+        logElement.empty();
+      }
+      log.onClear(() => {
+        this.teardownLog();
+        return this.createEngine();
+      });
+      this.scroll = new Log.Scroll({
+        beforeScroll: () => {
+          return this.unfoldHighlight();
+        }
+      });
+      this.limit = new Log.Limit(Log.LIMIT, () => {
+        return this.set('limited', true);
+      });
+      this.engine = Log.create({
+        listeners: [this.scroll, this.limit]
+      });
+      this.engine.limit = this.limit;
+      this.logFolder = new LogFolder(this.$('#log'));
+      this.lineSelector = new LinesSelector(this.$('#log'), this.scroll, this.logFolder);
+      return this.observeParts(log);
+    }
+  },
+
+  didUpdateAttrs(changes) {
+    this._super.apply(this, arguments);
+    if (!changes.oldAttrs) {
+      return;
+    }
+    if (changes.newAttrs.job.value && changes.oldAttrs.job.value && changes.newAttrs.job.value !== changes.oldAttrs.job.value) {
+      this.teardownLog(changes.oldAttrs.job.value.get('log'));
+      return this.createEngine(changes.newAttrs.job.value.get('log'));
+    }
+  },
+
+  unfoldHighlight() {
+    return this.lineSelector.unfoldLines();
+  },
+
+  observeParts(log) {
+    var parts;
+    if (log || (log = this.get('log'))) {
+      parts = log.get('parts');
+      parts.addArrayObserver(this, {
+        didChange: 'partsDidChange',
+        willChange: 'noop'
+      });
+      parts = parts.slice(0);
+      return this.partsDidChange(parts, 0, null, parts.length);
+    }
+  },
+
+  partsDidChange(parts, start, _, added) {
+    var i, j, len, part, ref, ref1, ref2, results;
+    if (Log.DEBUG) {
+      console.log('log view: parts did change');
+    }
+    if (this.get('state') !== 'inDOM') {
+      return;
+    }
+    ref = parts.slice(start, start + added);
+    results = [];
+    for (i = j = 0, len = ref.length; j < len; i = ++j) {
+      part = ref[i];
+      if ((ref1 = this.engine) != null ? (ref2 = ref1.limit) != null ? ref2.limited : void 0 : void 0) {
+        break;
+      }
+      results.push(this.engine.set(part.number, part.content));
+    }
+    return results;
+  },
+
+  plainTextLogUrl: function() {
+    var id, url;
+    if (id = this.get('log.job.id')) {
+      url = plainTextLogUrl(id);
+      if (config.pro) {
+        url += "&access_token=" + (this.get('job.log.token'));
+      }
+      return url;
+    }
+  }.property('job.log.id', 'job.log.token'),
+
+  hasPermission: function() {
+    var permissions;
+    if (permissions = this.get('currentUser.permissions')) {
+      return permissions.contains(parseInt(this.get('job.repo.id')));
+    }
+  }.property('currentUser.permissions.length', 'job.repo.id'),
+
+  canRemoveLog: function() {
+    var job;
+    if (job = this.get('job')) {
+      return job.get('canRemoveLog') && this.get('hasPermission');
+    }
+  }.property('job.canRemoveLog', 'hasPermission'),
+
+  showToTop: function() {
+    return this.get('log.hasContent') && this.get('job.canRemoveLog');
+  }.property('log.hasContent', 'job.canRemoveLog'),
+
+  showTailing: Ember.computed.alias('showToTop'),
+
+  actions: {
+    toTop() {
+      Travis.tailing.stop();
+      return $(window).scrollTop(0);
+    },
+
+    toggleTailing() {
+      Travis.tailing.toggle();
+      this.engine.autoCloseFold = !Travis.tailing.isActive();
+      return false;
+    },
+
+    removeLogPopup() {
+      if (this.get('canRemoveLog')) {
+        this.get('popup').open('remove-log-popup');
+        return false;
+      }
+    }
+  },
+
+  noop() {}
+});