Make zuul javascript app more modular
Refactor the zuul status app to be more modular. This allows the
controlling page (eg index.html) to load in only the components
it requires. This will make it easier to format just one patchset
or change where the layout controls are etc.
This is to work towards overlaying zuul results in gerrit.
Change-Id: Idfba9f08c25850c340cc962fa0f5f9652306b877
diff --git a/etc/status/public_html/app.js b/etc/status/public_html/app.js
index 8616201..d6f93c8 100644
--- a/etc/status/public_html/app.js
+++ b/etc/status/public_html/app.js
@@ -19,19 +19,6 @@
'use strict';
(function ($) {
- var $container, $msg, $indicator, $queueInfo, $queueEventsNum,
- $queueResultsNum, $pipelines, $jq;
- var xhr, zuul,
- zuul_graph_update_count = 0,
- zuul_sparkline_urls = {},
- current_filter = '',
- demo = location.search.match(/[?&]demo=([^?&]*)/),
- source_url = location.search.match(/[?&]source_url=([^?&]*)/),
- source = demo ?
- './status-' + (demo[1] || 'basic') + '.json-sample' :
- 'status.json';
- source = source_url ? source_url[1] : source;
-
function set_cookie(name, value) {
document.cookie = name + '=' + value + '; path=/';
}
@@ -51,96 +38,50 @@
return default_value;
}
+ $.zuul = function(options) {
+ var options = $.extend({
+ 'enabled': true,
+ 'graphite_url': '',
+ 'source': 'status.json',
+ 'msg_id': '#zuul_msg',
+ 'pipelines_id': '#zuul_pipelines',
+ 'queue_events_num': '#zuul_queue_events_num',
+ 'queue_results_num': '#zuul_queue_results_num',
+ }, options);
- zuul = {
- enabled: true,
- graphite_url: '',
- collapsed_exceptions: [],
+ var collapsed_exceptions = [];
+ var current_filter = read_cookie('zuul_filter_string', current_filter);
+ var $jq;
- schedule: function () {
- if (!zuul.enabled) {
- setTimeout(zuul.schedule, 5000);
- return;
- }
- zuul.update().complete(function () {
- setTimeout(zuul.schedule, 5000);
- });
+ var xhr,
+ zuul_graph_update_count = 0,
+ zuul_sparkline_urls = {};
- /* Only update graphs every minute */
- if (zuul_graph_update_count > 11) {
- zuul_graph_update_count = 0;
- zuul.update_sparklines();
- }
- },
-
- /** @return {jQuery.Promise} */
- update: function () {
- // Cancel the previous update if it hasn't completed yet.
- if (xhr) {
- xhr.abort();
- }
-
- zuul.emit('update-start');
-
- xhr = $.getJSON(source)
- .done(function (data) {
- if ('message' in data) {
- $msg.removeClass('alert-danger').addClass('alert-info');
- $msg.text(data.message);
- $msg.show();
- } else {
- $msg.empty();
- $msg.hide();
- }
-
- if ('zuul_version' in data) {
- $('#zuul-version-span').text(data.zuul_version);
- }
- if ('last_reconfigured' in data) {
- var last_reconfigured =
- new Date(data.last_reconfigured);
- $('#last-reconfigured-span').text(
- last_reconfigured.toString());
- }
-
- $pipelines.html('');
- $.each(data.pipelines, function (i, pipeline) {
- $pipelines.append(zuul.format.pipeline(pipeline));
+ function get_sparkline_url(pipeline_name) {
+ if (options.graphite_url !== '') {
+ if (!(pipeline_name in zuul_sparkline_urls)) {
+ zuul_sparkline_urls[pipeline_name] = $.fn.graphite
+ .geturl({
+ url: options.graphite_url,
+ from: "-8hours",
+ width: 100,
+ height: 26,
+ margin: 0,
+ hideLegend: true,
+ hideAxes: true,
+ hideGrid: true,
+ target: [
+ "color(stats.gauges.zuul.pipeline." + pipeline_name
+ + ".current_changes, '6b8182')"
+ ]
});
+ }
+ return zuul_sparkline_urls[pipeline_name];
+ }
+ return false;
+ }
- $queueEventsNum.text(
- data.trigger_event_queue ?
- data.trigger_event_queue.length : '0'
- );
- $queueResultsNum.text(
- data.result_event_queue ?
- data.result_event_queue.length : '0'
- );
- })
- .fail(function (err, jqXHR, errMsg) {
- $msg.text(source + ': ' + errMsg).show();
- $msg.removeClass('zuul-msg-wrap-off');
- })
- .complete(function () {
- xhr = undefined;
- zuul.emit('update-end');
- });
-
- return xhr;
- },
-
- update_sparklines: function() {
- $.each(zuul_sparkline_urls, function(name, url) {
- var newimg = new Image();
- var parts = url.split('#');
- newimg.src = parts[0] + '#' + new Date().getTime();
- $(newimg).load(function (x) {
- zuul_sparkline_urls[name] = newimg.src;
- });
- });
- },
-
- format: {
+ var format = {
job: function(job) {
var $job_line = $('<span />');
@@ -160,7 +101,7 @@
);
}
- $job_line.append(zuul.format.job_status(job));
+ $job_line.append(this.job_status(job));
if (job.voting === false) {
$job_line.append(
@@ -180,11 +121,11 @@
}
if (result === 'in progress') {
- return zuul.format.job_progress_bar(job.elapsed_time,
+ return this.job_progress_bar(job.elapsed_time,
job.remaining_time);
}
else {
- return zuul.format.status_label(result);
+ return this.status_label(result);
}
},
@@ -237,7 +178,7 @@
var now = Date.now();
var delta = now - ms;
var status = 'text-success';
- var text = zuul.format.time(delta, true);
+ var text = this.time(delta, true);
if (delta > (4 * hours)) {
status = 'text-danger';
} else if (delta > (2 * hours)) {
@@ -338,7 +279,7 @@
.append($change_link);
var $change_progress_row_right = $('<div />')
.addClass('col-xs-9')
- .append(zuul.format.change_total_progress_bar(change));
+ .append(this.change_total_progress_bar(change));
var $change_progress_row = $('<div />')
.addClass('row')
@@ -353,9 +294,9 @@
.addClass('col-xs-8')
.append($project_span, $change_progress_row);
- var remaining_time = zuul.format.time(
+ var remaining_time = this.time(
change.remaining_time, true);
- var enqueue_time = zuul.format.enqueue_time(
+ var enqueue_time = this.enqueue_time(
change.enqueue_time);
var $remaining_time = $('<small />').addClass('time')
.attr('title', 'Remaining Time').html(remaining_time);
@@ -373,6 +314,7 @@
},
change_list: function(jobs) {
+ var format = this;
var $list = $('<ul />')
.addClass('list-group zuul-patchset-body');
@@ -380,7 +322,7 @@
var $item = $('<li />')
.addClass('list-group-item')
.addClass('zuul-change-job')
- .append(zuul.format.job(job));
+ .append(format.job(job));
$list.append($item);
});
@@ -390,7 +332,7 @@
change_panel: function (change) {
var $header = $('<div />')
.addClass('panel-heading zuul-patchset-header')
- .append(zuul.format.change_header(change));
+ .append(this.change_header(change));
var panel_id = change.id ? change.id.replace(',', '_')
: change.project.replace('/', '_') +
@@ -399,9 +341,9 @@
.attr('id', panel_id)
.addClass('panel panel-default zuul-change')
.append($header)
- .append(zuul.format.change_list(change.jobs));
+ .append(this.change_list(change.jobs));
- $header.click(zuul.toggle_patchset);
+ $header.click(this.toggle_patchset);
return $panel;
},
@@ -458,7 +400,7 @@
if (i === change._tree_index) {
$tree_cell.append(
- zuul.format.change_status_icon(change));
+ this.change_status_icon(change));
}
if (change._tree_branches.indexOf(i) !== -1) {
var $image = $('<img />')
@@ -481,7 +423,7 @@
var $change_column = $('<td />')
.css('width', change_width + 'px')
.addClass('zuul-change-cell')
- .append(zuul.format.change_panel(change));
+ .append(this.change_panel(change));
$change_row.append($change_column);
@@ -495,10 +437,10 @@
},
pipeline_sparkline: function(pipeline_name) {
- if (zuul.graphite_url !== '') {
+ if (options.graphite_url !== '') {
var $sparkline = $('<img />')
.addClass('pull-right')
- .attr('src', zuul.get_sparkline_url(pipeline_name));
+ .attr('src', get_sparkline_url(pipeline_name));
return $sparkline;
}
return false;
@@ -519,7 +461,7 @@
.css('margin-top', '0.5em')
.text(count)
)
- .append(zuul.format.pipeline_sparkline(pipeline.name));
+ .append(this.pipeline_sparkline(pipeline.name));
$header_div.append($heading);
@@ -533,11 +475,11 @@
return $header_div;
},
- pipeline: function (pipeline) {
- var count = zuul.create_tree(pipeline);
+ pipeline: function (pipeline, count) {
+ var format = this;
var $html = $('<div />')
.addClass('zuul-pipeline col-md-4')
- .append(zuul.format.pipeline_header(pipeline, count));
+ .append(this.pipeline_header(pipeline, count));
$.each(pipeline.change_queues,
function (queue_i, change_queue) {
@@ -562,16 +504,215 @@
$.each(changes, function (change_i, change) {
var $change_box =
- zuul.format.change_with_status_tree(
+ format.change_with_status_tree(
change, change_queue);
$html.append($change_box);
- zuul.display_patchset($change_box);
+ format.display_patchset($change_box);
});
});
});
return $html;
},
+ toggle_patchset: function(e) {
+ // Toggle showing/hiding the patchset when the header is
+ // clicked.
+
+ // Grab the patchset panel
+ var $panel = $(e.target).parents('.zuul-change');
+ var $body = $panel.children('.zuul-patchset-body');
+ $body.toggle(200);
+ var collapsed_index = collapsed_exceptions.indexOf(
+ $panel.attr('id'));
+ if (collapsed_index === -1 ) {
+ // Currently not an exception, add it to list
+ collapsed_exceptions.push($panel.attr('id'));
+ }
+ else {
+ // Currently an except, remove from exceptions
+ collapsed_exceptions.splice(collapsed_index, 1);
+ }
+ },
+
+ display_patchset: function($change_box, animate) {
+ // Determine if to show or hide the patchset and/or the results
+ // when loaded
+
+ // See if we should hide the body/results
+ var $panel = $change_box.find('.zuul-change');
+ var panel_change = $panel.attr('id');
+ var $body = $panel.children('.zuul-patchset-body');
+ var expand_by_default = $('#expand_by_default')
+ .prop('checked');
+
+ var collapsed_index = collapsed_exceptions
+ .indexOf(panel_change);
+
+ if (expand_by_default && collapsed_index === -1 ||
+ !expand_by_default && collapsed_index !== -1) {
+ // Expand by default, or is an exception
+ $body.show(animate);
+ }
+ else {
+ $body.hide(animate);
+ }
+
+ // Check if we should hide the whole panel
+ var panel_project = $panel.find('.change_project').text()
+ .toLowerCase();
+
+
+ var panel_pipeline = $change_box
+ .parents('.zuul-pipeline')
+ .find('.zuul-pipeline-header > h3')
+ .html()
+ .toLowerCase();
+
+ if (current_filter !== '') {
+ var show_panel = false;
+ var filter = current_filter.trim().split(/[\s,]+/);
+ $.each(filter, function(index, f_val) {
+ if (f_val !== '') {
+ f_val = f_val.toLowerCase();
+ if (panel_project.indexOf(f_val) !== -1 ||
+ panel_pipeline.indexOf(f_val) !== -1 ||
+ panel_change.indexOf(f_val) !== -1) {
+ show_panel = true;
+ }
+ }
+ });
+ if (show_panel === true) {
+ $change_box.show(animate);
+ }
+ else {
+ $change_box.hide(animate);
+ }
+ }
+ else {
+ $change_box.show(animate);
+ }
+ },
+ };
+
+ var app = {
+ schedule: function (app) {
+ var app = app || this;
+ if (!options.enabled) {
+ setTimeout(function() {app.schedule(app);}, 5000);
+ return;
+ }
+ app.update().complete(function () {
+ setTimeout(function() {app.schedule(app);}, 5000);
+ });
+
+ /* Only update graphs every minute */
+ if (zuul_graph_update_count > 11) {
+ zuul_graph_update_count = 0;
+ zuul.update_sparklines();
+ }
+ },
+
+ /** @return {jQuery.Promise} */
+ update: function () {
+ // Cancel the previous update if it hasn't completed yet.
+ if (xhr) {
+ xhr.abort();
+ }
+
+ this.emit('update-start');
+ var app = this;
+
+ var $msg = $(options.msg_id)
+ xhr = $.getJSON(options.source)
+ .done(function (data) {
+ if ('message' in data) {
+ $msg.removeClass('alert-danger')
+ .addClass('alert-info')
+ .text(data.message)
+ .show();
+ } else {
+ $msg.empty()
+ .hide();
+ }
+
+ if ('zuul_version' in data) {
+ $('#zuul-version-span').text(data.zuul_version);
+ }
+ if ('last_reconfigured' in data) {
+ var last_reconfigured =
+ new Date(data.last_reconfigured);
+ $('#last-reconfigured-span').text(
+ last_reconfigured.toString());
+ }
+
+ var $pipelines = $(options.pipelines_id);
+ $pipelines.html('');
+ $.each(data.pipelines, function (i, pipeline) {
+ var count = app.create_tree(pipeline);
+ $pipelines.append(
+ format.pipeline(pipeline, count));
+ });
+
+ $(options.queue_events_num).text(
+ data.trigger_event_queue ?
+ data.trigger_event_queue.length : '0'
+ );
+ $(options.queue_results_num).text(
+ data.result_event_queue ?
+ data.result_event_queue.length : '0'
+ );
+ })
+ .fail(function (err, jqXHR, errMsg) {
+ $msg.text(source + ': ' + errMsg).show();
+ $msg.removeClass('zuul-msg-wrap-off');
+ })
+ .complete(function () {
+ xhr = undefined;
+ app.emit('update-end');
+ });
+
+ return xhr;
+ },
+
+ update_sparklines: function() {
+ $.each(zuul_sparkline_urls, function(name, url) {
+ var newimg = new Image();
+ var parts = url.split('#');
+ newimg.src = parts[0] + '#' + new Date().getTime();
+ $(newimg).load(function (x) {
+ zuul_sparkline_urls[name] = newimg.src;
+ });
+ });
+ },
+
+ emit: function () {
+ $jq.trigger.apply($jq, arguments);
+ return this;
+ },
+ on: function () {
+ $jq.on.apply($jq, arguments);
+ return this;
+ },
+ one: function () {
+ $jq.one.apply($jq, arguments);
+ return this;
+ },
+
+ control_form: function() {
+ // Build the filter form filling anything from cookies
+
+ var $control_form = $('<form />')
+ .attr('role', 'form')
+ .addClass('form-inline')
+ .submit(this.handle_filter_change);
+
+ $control_form
+ .append(this.filter_form_group())
+ .append(this.expand_form_group());
+
+ return $control_form;
+ },
+
filter_form_group: function() {
// Update the filter form with a clear button if required
@@ -590,7 +731,7 @@
'separated')
.attr('value', current_filter);
- $input.change(zuul.handle_filter_change);
+ $input.change(this.handle_filter_change);
var $clear_icon = $('<span />')
.addClass('form-control-feedback')
@@ -621,7 +762,7 @@
.attr('type', 'checkbox')
.attr('id', 'expand_by_default')
.prop('checked', expand_by_default)
- .change(zuul.handle_expand_by_default);
+ .change(this.handle_expand_by_default);
var $label = $('<label />')
.css('padding-left', '1em')
@@ -634,284 +775,103 @@
return $form_group;
},
- control_form: function() {
- // Build the filter form filling anything from cookies
-
- var $control_form = $('<form />')
- .attr('role', 'form')
- .addClass('form-inline')
- .submit(zuul.handle_filter_change);
-
- $control_form
- .append(zuul.format.filter_form_group())
- .append(zuul.format.expand_form_group());
-
- return $control_form;
- },
- },
-
- emit: function () {
- $jq.trigger.apply($jq, arguments);
- return this;
- },
- on: function () {
- $jq.on.apply($jq, arguments);
- return this;
- },
- one: function () {
- $jq.one.apply($jq, arguments);
- return this;
- },
-
- toggle_patchset: function(e) {
- // Toggle showing/hiding the patchset when the header is clicked
- // Grab the patchset panel
- var $panel = $(e.target).parents('.zuul-change');
- var $body = $panel.children('.zuul-patchset-body');
- $body.toggle(200);
- var collapsed_index = zuul.collapsed_exceptions.indexOf(
- $panel.attr('id'));
- if (collapsed_index === -1 ) {
- // Currently not an exception, add it to list
- zuul.collapsed_exceptions.push($panel.attr('id'));
- }
- else {
- // Currently an except, remove from exceptions
- zuul.collapsed_exceptions.splice(collapsed_index, 1);
- }
- },
-
- display_patchset: function($change_box, animate) {
- // Determine if to show or hide the patchset and/or the results
- // when loaded
-
- // See if we should hide the body/results
- var $panel = $change_box.find('.zuul-change');
- var panel_change = $panel.attr('id');
- var $body = $panel.children('.zuul-patchset-body');
- var expand_by_default = $('#expand_by_default').prop('checked');
-
- var collapsed_index = zuul.collapsed_exceptions.indexOf(panel_change);
-
- if (expand_by_default && collapsed_index === -1 ||
- !expand_by_default && collapsed_index !== -1) {
- // Expand by default, or is an exception
- $body.show(animate);
- }
- else {
- $body.hide(animate);
- }
-
- // Check if we should hide the whole panel
- var panel_project = $panel.find('.change_project').text()
- .toLowerCase();
-
-
- var panel_pipeline = $change_box
- .parents('.zuul-pipeline')
- .find('.zuul-pipeline-header > h3')
- .html()
- .toLowerCase();
-
- if (current_filter !== '') {
- var show_panel = false;
- var filter = current_filter.trim().split(/[\s,]+/);
- $.each(filter, function(index, f_val) {
- if (f_val !== '') {
- f_val = f_val.toLowerCase();
- if (panel_project.indexOf(f_val) !== -1 ||
- panel_pipeline.indexOf(f_val) !== -1 ||
- panel_change.indexOf(f_val) !== -1) {
- show_panel = true;
- }
- }
- });
- if (show_panel === true) {
- $change_box.show(animate);
+ handle_filter_change: function() {
+ // Update the filter and save it to a cookie
+ current_filter = $('#filter_string').val();
+ set_cookie('zuul_filter_string', current_filter);
+ if (current_filter === '') {
+ $('#filter_form_clear_box').hide();
}
else {
- $change_box.hide(animate);
+ $('#filter_form_clear_box').show();
}
- }
- else {
- $change_box.show(animate);
- }
- },
- handle_filter_change: function() {
- // Update the filter and save it to a cookie
- current_filter = $('#filter_string').val();
- set_cookie('zuul_filter_string', current_filter);
- if (current_filter === '') {
- $('#filter_form_clear_box').hide();
- }
- else {
- $('#filter_form_clear_box').show();
- }
-
- $('.zuul-change-box').each(function(index, obj) {
- var $change_box = $(obj);
- zuul.display_patchset($change_box, 200);
- });
- return false;
- },
-
- handle_expand_by_default: function(e) {
- // Handle toggling expand by default
- set_cookie('zuul_expand_by_default', e.target.checked);
- zuul.collapsed_exceptions = [];
- $('.zuul-change-box').each(function(index, obj) {
- var $change_box = $(obj);
- zuul.display_patchset($change_box, 200);
- });
- },
-
- create_tree: function(pipeline) {
- var count = 0;
- var pipeline_max_tree_columns = 1;
- $.each(pipeline.change_queues, function(change_queue_i,
- change_queue) {
- var tree = [];
- var max_tree_columns = 1;
- var changes = [];
- var last_tree_length = 0;
- $.each(change_queue.heads, function(head_i, head) {
- $.each(head, function(change_i, change) {
- changes[change.id] = change;
- change._tree_position = change_i;
- });
+ $('.zuul-change-box').each(function(index, obj) {
+ var $change_box = $(obj);
+ format.display_patchset($change_box, 200);
});
- $.each(change_queue.heads, function(head_i, head) {
- $.each(head, function(change_i, change) {
- count += 1;
- var idx = tree.indexOf(change.id);
- if (idx > -1) {
- change._tree_index = idx;
- // remove...
- tree[idx] = null;
- while (tree[tree.length - 1] === null) {
- tree.pop();
- }
- } else {
- change._tree_index = 0;
- }
- change._tree_branches = [];
- change._tree = [];
- if (typeof(change.items_behind) === 'undefined') {
- change.items_behind = [];
- }
- change.items_behind.sort(function(a, b) {
- return (changes[b]._tree_position -
- changes[a]._tree_position);
- });
- $.each(change.items_behind, function(i, id) {
- tree.push(id);
- if (tree.length>last_tree_length &&
- last_tree_length > 0) {
- change._tree_branches.push(
- tree.length - 1);
- }
- });
- if (tree.length > max_tree_columns) {
- max_tree_columns = tree.length;
- }
- if (tree.length > pipeline_max_tree_columns) {
- pipeline_max_tree_columns = tree.length;
- }
- change._tree = tree.slice(0); // make a copy
- last_tree_length = tree.length;
- });
- });
- change_queue._tree_columns = max_tree_columns;
- });
- pipeline._tree_columns = pipeline_max_tree_columns;
- return count;
- },
-
- get_sparkline_url: function(pipeline_name) {
- if (zuul.graphite_url !== '') {
- if (!(pipeline_name in zuul_sparkline_urls)) {
- zuul_sparkline_urls[pipeline_name] = $.fn.graphite.geturl({
- url: zuul.graphite_url,
- from: "-8hours",
- width: 100,
- height: 26,
- margin: 0,
- hideLegend: true,
- hideAxes: true,
- hideGrid: true,
- target: [
- "color(stats.gauges.zuul.pipeline."+pipeline_name+".current_changes, '6b8182')"
- ]
- });
- }
- return zuul_sparkline_urls[pipeline_name];
- }
- return false;
- },
- };
-
- current_filter = read_cookie('zuul_filter_string', current_filter);
-
- $jq = $(zuul);
-
- $jq.on('update-start', function () {
- $container.addClass('zuul-container-loading');
- $indicator.addClass('zuul-spinner-on');
- });
-
- $jq.on('update-end', function () {
- $container.removeClass('zuul-container-loading');
- setTimeout(function () {
- $indicator.removeClass('zuul-spinner-on');
- }, 500);
- });
-
- $jq.one('update-end', function () {
- // Do this asynchronous so that if the first update adds a message, it
- // will not animate while we fade in the content. Instead it simply
- // appears with the rest of the content.
- setTimeout(function () {
- // Fade in the content
- $container.addClass('zuul-container-ready');
- });
- });
-
- $(function ($) {
- $msg = $('<div />').addClass('alert').hide();
- $indicator = $('<button class="btn pull-right zuul-spinner">' +
- 'updating ' +
- '<span class="glyphicon glyphicon-refresh"></span>' +
- '</button>');
- $queueInfo = $('<p>Queue lengths: <span>0</span> events, ' +
- '<span>0</span> results.</p>');
- $queueEventsNum = $queueInfo.find('span').eq(0);
- $queueResultsNum = $queueEventsNum.next();
-
- var $control_form = zuul.format.control_form();
-
- $pipelines = $('<div class="row"></div>');
- var $zuulVersion = $('<p>Zuul version: <span id="zuul-version-span">' +
- '</span></p>');
- var $lastReconf = $('<p>Last reconfigured: ' +
- '<span id="last-reconfigured-span"></span></p>');
-
- $container = $('#zuul-container').append($msg, $indicator,
- $queueInfo, $control_form,
- $pipelines, $zuulVersion,
- $lastReconf);
-
- //zuul.graphite_url = 'http://graphite.openstack.org/render/'
- zuul.schedule();
-
- $(document).on({
- 'show.visibility': function () {
- zuul.enabled = true;
- zuul.update();
+ return false;
},
- 'hide.visibility': function () {
- zuul.enabled = false;
- }
- });
- });
+
+ handle_expand_by_default: function(e) {
+ // Handle toggling expand by default
+ set_cookie('zuul_expand_by_default', e.target.checked);
+ collapsed_exceptions = [];
+ $('.zuul-change-box').each(function(index, obj) {
+ var $change_box = $(obj);
+ format.display_patchset($change_box, 200);
+ });
+ },
+
+ create_tree: function(pipeline) {
+ var count = 0;
+ var pipeline_max_tree_columns = 1;
+ $.each(pipeline.change_queues, function(change_queue_i,
+ change_queue) {
+ var tree = [];
+ var max_tree_columns = 1;
+ var changes = [];
+ var last_tree_length = 0;
+ $.each(change_queue.heads, function(head_i, head) {
+ $.each(head, function(change_i, change) {
+ changes[change.id] = change;
+ change._tree_position = change_i;
+ });
+ });
+ $.each(change_queue.heads, function(head_i, head) {
+ $.each(head, function(change_i, change) {
+ count += 1;
+ var idx = tree.indexOf(change.id);
+ if (idx > -1) {
+ change._tree_index = idx;
+ // remove...
+ tree[idx] = null;
+ while (tree[tree.length - 1] === null) {
+ tree.pop();
+ }
+ } else {
+ change._tree_index = 0;
+ }
+ change._tree_branches = [];
+ change._tree = [];
+ if (typeof(change.items_behind) === 'undefined') {
+ change.items_behind = [];
+ }
+ change.items_behind.sort(function(a, b) {
+ return (changes[b]._tree_position -
+ changes[a]._tree_position);
+ });
+ $.each(change.items_behind, function(i, id) {
+ tree.push(id);
+ if (tree.length>last_tree_length &&
+ last_tree_length > 0) {
+ change._tree_branches.push(
+ tree.length - 1);
+ }
+ });
+ if (tree.length > max_tree_columns) {
+ max_tree_columns = tree.length;
+ }
+ if (tree.length > pipeline_max_tree_columns) {
+ pipeline_max_tree_columns = tree.length;
+ }
+ change._tree = tree.slice(0); // make a copy
+ last_tree_length = tree.length;
+ });
+ });
+ change_queue._tree_columns = max_tree_columns;
+ });
+ pipeline._tree_columns = pipeline_max_tree_columns;
+ return count;
+ },
+ };
+
+ $jq = $(app);
+ return {
+ options: options,
+ format: format,
+ app: app,
+ jq: $jq
+ };
+ }
}(jQuery));