blob: 2725f842b5acb81c41bfea46cc0f4d140a28acc9 [file] [log] [blame]
// Copyright 2018 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.
'use strict';
/** @type {snippetsInternals.mojom.PageHandlerPtr} */
let pageHandler = null;
/** @type {snippetsInternals.mojom.PageImpl} */
let page = null;
/* Javascript module for chrome://snippets-internals. */
(function() {
/* Utility functions*/
/**
* Sets all the properties contained in the mapping in the page.
* property map {id -> value}.
* @param {Map} propertyMap Property name to value mapping.
*/
function setPropertiesInPage(propertyMap) {
propertyMap.forEach(function(value, field) {
setPropertyInPage(field, value);
});
}
/**
* Sets the given value as textContent for the given field.
* @param {string} field Id of the element to set the property on.
* @param {string} value Property to be set in the page.
*/
function setPropertyInPage(field, value) {
$(field).textContent = value;
}
/**
* Downloads the given data under filename with the given datatype.
* Acceptable values for data type include: text/plain, application/json, etc.
* @param {string} fileName Name of the file to download.
* @param {string} dataType The content-type to download.
* @param {string} data The data to download.
*/
function downloadData(fileName, dataType, data) {
let dataToReport = data;
if (data === '') {
dataToReport = 'None';
}
const link = document.createElement('a');
link.download = fileName;
link.href = 'data:' + dataType + ',' + encodeURI(dataToReport);
link.click();
}
/**
* Wrapper funciton for downloadData that stringifies json.
* @param {string} fileName Name of file to download.
* @param {string} data JSON data to download.
*/
function downloadJson(fileName, data) {
downloadData(fileName, 'application/json', data);
}
/**
* Clears children of the given domId.
* @param {string} domId Id of the DOM element to be cleared.
*/
function clearChildrenForId(domId) {
const parent = $(domId);
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}
/* Page functions, as the elements appear of the page. */
function updateGeneralProperties() {
pageHandler.getGeneralProperties().then(
response => setPropertiesInPage(response.properties));
}
function getUserClassifierProperties() {
pageHandler.getUserClassifierProperties().then(
response => setPropertiesInPage(response.properties));
}
function getCategoryRankerProperties() {
pageHandler.getCategoryRankerProperties().then(function(response) {
const domId = 'category-ranker-table';
clearChildrenForId(domId);
const table = $(domId);
const rowTemplate = $('category-ranker-row');
response.properties.forEach(function(value, field) {
const row = document.importNode(rowTemplate.content, true);
const td = row.querySelectorAll('td');
td[0].textContent = field;
td[1].textContent = value;
table.appendChild(row);
});
});
}
/* Check if pushing dummy suggestions is possible. */
function checkIfPushingDummySuggestionPossible() {
pageHandler.isPushingDummySuggestionPossible().then(function(response) {
$('push-dummy-suggestion').disabled = !response.result;
});
}
/* Retrieve the remote content suggestions properties. */
function getRemoteContentSuggestionsProperties() {
pageHandler.getRemoteContentSuggestionsProperties().then(function(response) {
setPropertiesInPage(response.properties);
});
}
/* Retrieve suggestions, ordered by category. */
function getSuggestionsByCategory() {
pageHandler.getSuggestionsByCategory().then(function(response) {
const domId = 'content-suggestions';
const toggleClass = 'hidden-toggler';
jstProcess(new JsEvalContext(response), $(domId));
let text;
let display;
if (response.categories.length > 0) {
text = '';
display = 'inline';
} else {
text = 'The list is empty.';
display = 'none';
}
const emptyNode = $(`${domId}-empty`);
if (emptyNode)
emptyNode.textContent = text;
const clearNode = $(`${domId}-clear`);
if (clearNode)
clearNode.style.display = display;
// Toggle visibility for suggestions.
const links = document.getElementsByClassName(toggleClass);
for (const link of links) {
link.onclick = function(event) {
const id = event.currentTarget.getAttribute('hidden-id');
$(id).classList.toggle('hidden');
};
}
// Clear dismissed suggestions.
const clearDismissedButtons =
document.getElementsByClassName('submit-clear-dismissed-suggestions');
for (const button of clearDismissedButtons) {
button.onclick = function(event) {
// This is an attribute set on the elements.
const id = parseInt(event.currentTarget.dataset.categoryId, 10);
// Clear the suggestions and hide the table.
pageHandler.clearDismissedSuggestions(id);
const table = $('dismissed-category-' + id);
table.classList.add('hidden');
// Reload the data.
getSuggestionsByCategory();
};
}
// Toggle viewing dismissed suggestions.
const toggleDismissedButtons =
document.getElementsByClassName('toggle-dismissed-suggestions');
for (const button of toggleDismissedButtons) {
button.onclick = function(event) {
// This is an attribute set on the elements.
const id = parseInt(event.currentTarget.dataset.categoryId, 10);
const table = $('dismissed-category-' + id);
table.classList.toggle('hidden');
};
}
});
}
/* Wrapper functions for setting up page. */
/* Refresh data. */
function refreshContent() {
updateGeneralProperties();
getUserClassifierProperties();
getCategoryRankerProperties();
getRemoteContentSuggestionsProperties();
checkIfPushingDummySuggestionPossible();
}
/* Setup buttons and other event listeners. */
function setupEventListeners() {
$('clear-classification').addEventListener('click', function(event) {
pageHandler.clearUserClassifierProperties();
});
$('reload-suggestions').addEventListener('click', function(event) {
pageHandler.reloadSuggestions();
});
$('debug-log-dump').addEventListener('click', function(event) {
pageHandler.getDebugLog().then(function(response) {
let logs = response.debugLog;
if (logs === '')
logs = 'No data yet. Have you enabled debug logging in chrome://flags?';
downloadData('debug_log.txt', 'text/plain', logs);
});
});
$('clear-cached-suggestions').addEventListener('click', function(event) {
pageHandler.clearCachedSuggestions();
});
$('background-fetch-button').addEventListener('click', function(event) {
$('background-fetch-button').disabled = true;
pageHandler.fetchSuggestionsInBackground(2).then(function(response) {
$('background-fetch-button').disabled = false;
$('last-json-container').classList.add('hidden');
$('last-json-button').textContent = 'Show the last JSON';
// After we've fetched, update the page.
getRemoteContentSuggestionsProperties();
});
});
$('push-dummy-suggestion').addEventListener('click', function(event) {
const content = $('push-dummy-suggestion').textContent;
$('push-dummy-suggestion').textContent = '...';
pageHandler.pushDummySuggestionInBackground(10).then(function(response) {
$('push-dummy-suggestion').textContent = content;
});
});
$('last-json-button').addEventListener('click', function(event) {
pageHandler.getLastJson().then(function(response) {
const container = $('last-json-container');
container.classList.toggle('hidden');
$('last-json-text').textContent = response.json;
$('last-json-button').textContent =
container.classList.contains('hidden') ? 'Show the last JSON' :
'Hide the last JSON';
});
});
$('last-json-dump').addEventListener('click', function(event) {
pageHandler.getLastJson().then(function(response) {
downloadJson('last_snippets.json', response.json);
});
});
$('reset-notifications-state-button')
.addEventListener('click', function(event) {
pageHandler.resetNotificationState();
});
$('reset-notifications-state-button')
.addEventListener('click', function(event) {
pageHandler.resetNotificationState();
});
$('submit-dump').addEventListener('click', function(event) {
pageHandler.getSuggestionsByCategory().then(function(response) {
downloadJson('snippets.json', JSON.stringify(response.categories));
});
});
window.addEventListener('focus', getSuggestionsByCategory);
}
/* Represents the js-side of the IPC link. Backend talks to this. */
/** @implements {snippetsInternals.mojom.PageImpl} */
class SnippetsInternalsPageImpl {
constructor(request) {
this.binding_ =
new mojo.Binding(snippetsInternals.mojom.Page, this, request);
}
/* Callback for when suggestions change on the backend. */
onSuggestionsChanged() {
getSuggestionsByCategory();
}
}
/* Main entry point. */
document.addEventListener('DOMContentLoaded', function() {
// Setup frontend mojo.
const client = new snippetsInternals.mojom.PagePtr;
assert(client);
page = new SnippetsInternalsPageImpl(mojo.makeRequest(client));
// Setup backend mojo.
const pageHandlerFactory = new snippetsInternals.mojom.PageHandlerFactoryPtr;
Mojo.bindInterface(
snippetsInternals.mojom.PageHandlerFactory.name,
mojo.makeRequest(pageHandlerFactory).handle);
// Give backend mojo a reference to frontend mojo.
pageHandlerFactory.createPageHandler(client).then((response) => {
pageHandler = response.handler;
// Populate value fields.
refreshContent();
getSuggestionsByCategory();
setInterval(refreshContent, 2000);
// Setup events.
setupEventListeners();
});
});
}());