blob: 6d028e12b658a74eeda18cb016adacb6afbe4f2b [file] [log] [blame]
/* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
Logs = {
controller_: null,
/**
* Initializes the logs UI.
*/
init: function() {
Logs.controller_ = new LogsListController();
var clearLogsButton = document.getElementById('clear-logs-button');
clearLogsButton.onclick = function() {
WebUI.clearLogs();
};
var saveLogsButton = document.getElementById('save-logs-button');
saveLogsButton.onclick = () => {
this.saveLogs();
};
WebUI.getLogMessages();
},
saveLogs: function() {
var blob = new Blob(
[document.getElementById('logs-list').innerText],
{type: 'text/plain;charset=utf-8'});
var url = URL.createObjectURL(blob);
var anchorEl = document.createElement('a');
anchorEl.href = url;
anchorEl.download = 'proximity_auth_logs_' + new Date().toJSON() + '.txt';
document.body.appendChild(anchorEl);
anchorEl.click();
window.setTimeout(function() {
document.body.removeChild(anchorEl);
window.URL.revokeObjectURL(url);
}, 0);
},
};
/**
* Interface with the native WebUI component for LogBuffer events. The functions
* contained in this object will be invoked by the browser for each operation
* performed on the native LogBuffer.
*/
LogBufferInterface = {
/**
* Called when a new log message is added.
*/
onLogMessageAdded: function(log) {
if (Logs.controller_) {
Logs.controller_.add(log);
}
},
/**
* Called when the log buffer is cleared.
*/
onLogBufferCleared: function() {
if (Logs.controller_) {
Logs.controller_.clear();
}
},
/**
* Called in response to chrome.send('getLogMessages') with the log messages
* currently in the buffer.
*/
onGotLogMessages: function(messages) {
if (Logs.controller_) {
Logs.controller_.set(messages);
}
},
};
/**
* Controller for the logs list element, updating it based on user input and
* logs received from native code.
*/
class LogsListController {
constructor() {
this.logsList_ = document.getElementById('logs-list');
this.itemTemplate_ = document.getElementById('item-template');
this.shouldSnapToBottom_ = true;
this.logsList_.onscroll = this.onScroll_.bind(this);
}
/**
* Listener for scroll event of the logs list element, used for snap to bottom
* logic.
*/
onScroll_() {
const list = this.logsList_;
this.shouldSnapToBottom_ =
list.scrollTop + list.offsetHeight == list.scrollHeight;
}
/**
* Clears all log items from the logs list.
*/
clear() {
var items = this.logsList_.querySelectorAll('.log-item');
for (var i = 0; i < items.length; ++i) {
items[i].remove();
}
this.shouldSnapToBottom_ = true;
}
/**
* Adds a log to the logs list.
*/
add(log) {
var directories = log.file.split('/');
var source = directories[directories.length - 1] + ':' + log.line;
var t = this.itemTemplate_.content;
t.querySelector('.log-item').attributes.severity.value = log.severity;
t.querySelector('.item-time').textContent = log.time;
t.querySelector('.item-source').textContent = source;
t.querySelector('.item-text').textContent = log.text;
var newLogItem = document.importNode(this.itemTemplate_.content, true);
this.logsList_.appendChild(newLogItem);
if (this.shouldSnapToBottom_) {
this.logsList_.scrollTop = this.logsList_.scrollHeight;
}
}
/**
* Initializes the log list from an array of logs.
*/
set(logs) {
this.clear();
for (var i = 0; i < logs.length; ++i) {
this.add(logs[i]);
}
}
}