| // Copyright 2020 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. |
| |
| (function() { |
| 'use strict'; |
| |
| /** |
| * Reference to the backend providing all the data. |
| * @type {mojom.ConversionInternalsHandlerRemote} |
| */ |
| let pageHandler = null; |
| |
| /** |
| * All impressions held in storage at last update. |
| * @type {!Array<!mojom.Impression>} |
| */ |
| let impressions = null; |
| |
| /** |
| * All impressions held in storage at last update. |
| * @type {!Array<!mojom.Impression>} |
| */ |
| let reports = null; |
| |
| /** |
| * Remove all rows from the given table. |
| * @param {!HTMLElement} table DOM element corresponding to table body. |
| */ |
| function clearTable(table) { |
| table.innerHTML = trustedTypes.emptyHTML; |
| } |
| |
| /** |
| * Converts a mojo origin into a user-readable string, omitting default ports. |
| * @param {url.mojom.Origin} origin Origin to convert |
| * @return {string} |
| */ |
| function UrlToText(origin) { |
| if (origin.host.length == 0) { |
| return 'Null'; |
| } |
| |
| let result = origin.scheme + '://' + origin.host; |
| |
| if (origin.scheme == 'https' && origin.port != '443') { |
| result += ':' + origin.port; |
| } |
| return result; |
| } |
| |
| /** |
| * Creates a single row for the impression table. |
| * @param {!mojom.Impression} impression The info to create the row. |
| * @return {!HTMLElement} |
| */ |
| function createImpressionRow(impression) { |
| const template = $('impressionrow').cloneNode(true); |
| const td = template.content.querySelectorAll('td'); |
| |
| td[0].textContent = '0x' + impression.impressionData; |
| td[1].textContent = UrlToText(impression.impressionOrigin); |
| td[2].textContent = UrlToText(impression.conversionDestination); |
| td[3].textContent = UrlToText(impression.reportingOrigin); |
| td[4].textContent = new Date(impression.impressionTime).toLocaleString(); |
| td[5].textContent = new Date(impression.expiryTime).toLocaleString(); |
| return document.importNode(template.content, true); |
| } |
| |
| /** |
| * Creates a single row for the impression table. |
| * @param {!mojom.Impression} impression The info to create the row. |
| * @return {!HTMLElement} |
| */ |
| function createReportRow(report) { |
| const template = $('reportrow').cloneNode(true); |
| const td = template.content.querySelectorAll('td'); |
| |
| td[0].textContent = '0x' + report.impressionData; |
| td[1].textContent = '0x' + report.conversionData; |
| td[2].textContent = UrlToText(report.conversionOrigin); |
| td[3].textContent = UrlToText(report.reportingOrigin); |
| td[4].textContent = new Date(report.reportTime).toLocaleString(); |
| td[5].textContent = report.attributionCredit; |
| return document.importNode(template.content, true); |
| } |
| |
| /** |
| * Regenerates the impression table from |impressions|. |
| */ |
| function renderImpressionTable() { |
| const impressionTable = $('impression-table-body'); |
| clearTable(impressionTable); |
| impressions.forEach( |
| impression => |
| impressionTable.appendChild(createImpressionRow(impression))); |
| |
| // If there are no impressions, add an empty row to indicate the table is |
| // purposefully empty. |
| if (!impressions.length) { |
| const template = $('impressionrow').cloneNode(true); |
| const td = template.content.querySelectorAll('td'); |
| td[0].textContent = 'No active impressions.'; |
| impressionTable.appendChild(document.importNode(template.content, true)); |
| } |
| } |
| |
| /** |
| * Regenerates the report table from |reports|. |
| */ |
| function renderReportTable() { |
| const reportTable = $('report-table-body'); |
| clearTable(reportTable); |
| reports.forEach(report => reportTable.appendChild(createReportRow(report))); |
| |
| // If there are no reports, add an empty row to indicate the table is |
| // purposefully empty. |
| if (!reports.length) { |
| const template = $('reportrow').cloneNode(true); |
| const td = template.content.querySelectorAll('td'); |
| td[0].textContent = 'No pending reports.'; |
| reportTable.appendChild(document.importNode(template.content, true)); |
| } |
| } |
| |
| /** |
| * Fetch all active impressions and pending reports from the backend and |
| * populate the tables. Also update measurement enabled status. |
| */ |
| function updatePageData() { |
| // Get the feature status for ConversionMeasurement and populate it. |
| pageHandler.isMeasurementEnabled().then((response) => { |
| $('feature-status-content').innerText = |
| response.enabled ? 'enabled' : 'disabled'; |
| }); |
| |
| pageHandler.getActiveImpressions().then((response) => { |
| impressions = response.impressions; |
| renderImpressionTable(); |
| }); |
| |
| pageHandler.getPendingReports().then((response) => { |
| reports = response.reports; |
| renderReportTable(); |
| }); |
| } |
| |
| /** |
| * Deletes all data stored by the conversions backend, and refreshes |
| * page data once this operation has finished. |
| */ |
| function clearStorage() { |
| pageHandler.clearStorage().then(() => { |
| updatePageData(); |
| }); |
| } |
| |
| /** |
| * Sends all conversion reports, and updates the page once they are sent. |
| * Disables the button while the reports are still being sent. |
| */ |
| function sendReports() { |
| const button = $('send-reports'); |
| const previousText = $('send-reports').innerText; |
| |
| button.disabled = true; |
| button.innerText = 'Sending...'; |
| pageHandler.sendPendingReports().then(() => { |
| updatePageData(); |
| button.disabled = false; |
| button.innerText = previousText; |
| }); |
| } |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| // Setup the mojo interface. |
| pageHandler = mojom.ConversionInternalsHandler.getRemote(); |
| |
| $('refresh').addEventListener('click', updatePageData); |
| $('clear-data').addEventListener('click', clearStorage); |
| $('send-reports').addEventListener('click', sendReports); |
| |
| // Automatically refresh every 2 minutes. |
| setInterval(updatePageData, 2 * 60 * 1000); |
| updatePageData(); |
| }); |
| })(); |