tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

event-telemetry.js (3662B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  FILTER_TEXT_SET,
      9  FILTER_TOGGLE,
     10  DEFAULT_FILTERS_RESET,
     11  EVALUATE_EXPRESSION,
     12  MESSAGES_ADD,
     13  PERSIST_TOGGLE,
     14  REVERSE_SEARCH_INPUT_TOGGLE,
     15  REVERSE_SEARCH_NEXT,
     16  REVERSE_SEARCH_BACK,
     17 } = require("resource://devtools/client/webconsole/constants.js");
     18 
     19 /**
     20 * Event telemetry middleware is responsible for logging specific events to telemetry.
     21 */
     22 function eventTelemetryMiddleware(telemetry, store) {
     23  return next => action => {
     24    const oldState = store.getState();
     25    const res = next(action);
     26 
     27    const state = store.getState();
     28 
     29    const filterChangeActions = [
     30      FILTER_TEXT_SET,
     31      FILTER_TOGGLE,
     32      DEFAULT_FILTERS_RESET,
     33    ];
     34 
     35    if (filterChangeActions.includes(action.type)) {
     36      filterChange({
     37        action,
     38        state,
     39        oldState,
     40        telemetry,
     41      });
     42    } else if (action.type === MESSAGES_ADD) {
     43      messagesAdd({ action });
     44    } else if (action.type === PERSIST_TOGGLE) {
     45      telemetry.recordEvent(
     46        "persist_changed",
     47        "webconsole",
     48        String(state.ui.persistLogs)
     49      );
     50    } else if (action.type === EVALUATE_EXPRESSION) {
     51      // Send telemetry event. If we are in the browser toolbox we send -1 as the
     52      // toolbox session id.
     53 
     54      telemetry.recordEvent("execute_js", "webconsole", null, {
     55        lines: action.expression.split(/\n/).length,
     56        input: state.ui.editor ? "multiline" : "inline",
     57      });
     58 
     59      if (action.from === "reverse-search") {
     60        telemetry.recordEvent("reverse_search", "webconsole", null, {
     61          functionality: "evaluate expression",
     62        });
     63      }
     64    } else if (
     65      action.type === REVERSE_SEARCH_INPUT_TOGGLE &&
     66      state.ui.reverseSearchInputVisible
     67    ) {
     68      telemetry.recordEvent("reverse_search", "webconsole", action.access, {
     69        functionality: "open",
     70      });
     71    } else if (action.type === REVERSE_SEARCH_NEXT) {
     72      telemetry.recordEvent("reverse_search", "webconsole", action.access, {
     73        functionality: "navigate next",
     74      });
     75    } else if (action.type === REVERSE_SEARCH_BACK) {
     76      telemetry.recordEvent("reverse_search", "webconsole", action.access, {
     77        functionality: "navigate previous",
     78      });
     79    }
     80 
     81    return res;
     82  };
     83 }
     84 
     85 function filterChange({ action, state, oldState, telemetry }) {
     86  const oldFilterState = oldState.filters;
     87  const filterState = state.filters;
     88  const activeFilters = [];
     89  const inactiveFilters = [];
     90  for (const [key, value] of Object.entries(filterState)) {
     91    if (value) {
     92      activeFilters.push(key);
     93    } else {
     94      inactiveFilters.push(key);
     95    }
     96  }
     97 
     98  let trigger;
     99  if (action.type === FILTER_TOGGLE) {
    100    trigger = action.filter;
    101  } else if (action.type === DEFAULT_FILTERS_RESET) {
    102    trigger = "reset";
    103  } else if (action.type === FILTER_TEXT_SET) {
    104    if (oldFilterState.text !== "" && filterState.text !== "") {
    105      return;
    106    }
    107 
    108    trigger = "text";
    109  }
    110 
    111  telemetry.recordEvent("filters_changed", "webconsole", null, {
    112    trigger,
    113    active: activeFilters.join(","),
    114    inactive: inactiveFilters.join(","),
    115  });
    116 }
    117 
    118 function messagesAdd({ action }) {
    119  const { messages } = action;
    120  for (const message of messages) {
    121    if (message.level === "error" && message.source === "javascript") {
    122      Glean.devtoolsConsole.javascriptErrorDisplayed[
    123        message.errorMessageName || "Unknown"
    124      ].add(1);
    125    }
    126  }
    127 }
    128 
    129 module.exports = eventTelemetryMiddleware;