stackviz/app/js/directives/codemirror-console.js
Tim Buckley c5a38e44e1 Add console.html summary and viewer
This adds a new console.html summary and details view that can
gives overview information about console output, organizes output
by section, and can also determine the currently running script at
job failure time. The console viewer is a CodeMirror-based widget
that provides basic highlighting and folding capabilities to make
console output easier to browse.

Change-Id: I27a9a532ae117d2914dc2f3a866c780378e79f72
2016-04-29 20:06:31 -06:00

131 lines
2.8 KiB
JavaScript

'use strict';
var CodeMirror = require('codemirror');
require('codemirror/addon/mode/simple');
require('codemirror/addon/fold/foldcode');
require('codemirror/addon/fold/foldgutter');
var directivesModule = require('./_index.js');
CodeMirror.defineSimpleMode('console', {
start: [
{
token: 'comment',
regex: /[\d\-]+ [\d\:\.]+ \|/,
sol: true
}, {
token: 'keyword',
regex: /\[[a-z\-]+\] \$ .*/
}
]
});
/**
* @ngInject
*/
function codemirrorConsole($compile, $window, datasetService, summaryService) {
var instance = null;
var element = null;
var headers = new Map();
var rangeFinder = function(cm, pos) {
if (!headers.has(pos.line)) {
return null;
}
var foundSelf = false;
var foldEnd = null;
headers.forEach(function(name, lineNo) {
if (!foundSelf && lineNo === pos.line) {
foundSelf = true;
return;
}
if (foundSelf && foldEnd === null) {
foldEnd = lineNo - 1;
}
});
if (foldEnd === null) {
foldEnd = cm.lastLine();
}
return {
from: CodeMirror.Pos(pos.line, cm.getLine(pos.line).length),
to: CodeMirror.Pos(foldEnd, cm.getLine(foldEnd).length)
};
};
var link = function(scope, el, attrs, ctrl) {
instance = CodeMirror(el[0], {
lineNumbers: true,
readOnly: true,
value: 'test test test',
mode: 'console',
theme: 'neat',
foldGutter: {
rangeFinder: rangeFinder
},
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
element = el.find('div');
var updateHeight = function() {
var rect = element[0].getBoundingClientRect();
element[0].style.height = ($window.innerHeight - rect.top) + 'px';
};
scope.$on('windowResize', updateHeight);
updateHeight();
};
/**
* @ngInject
*/
var controller = function($scope) {
$scope.$watch('data', function(data) {
if (!data) {
return;
}
var lines = [];
var currentLine = 0;
headers.clear();
data.scripts.forEach(function(script) {
headers.set(currentLine, script.name);
script.lines.forEach(function(line) {
lines.push(line.date + ' | ' + line.line);
currentLine++;
});
});
instance.setValue(lines.join('\n'));
var doc = instance.getDoc();
headers.forEach(function(text, lineNumber) {
var element = angular.element('<div><span>' + text + '</span></div>');
element.addClass('console-script-header');
doc.addLineWidget(lineNumber, element[0], {
above: true,
noHScroll: true
});
});
});
};
return {
restrict: 'EA',
scope: {
'data': '=',
'show': '='
},
link: link,
controller: controller
};
}
directivesModule.directive('codemirrorConsole', codemirrorConsole);