<commit_before>import {
  favIconFallback,
  alertCircle,
  tabList,
  searchInput,
} from './constants';
// Store all the bad favIcons so we don't get loading jank if a favIcon !exist
function badFavIconCache() {
  const badIconCache = [];
  return () => badIconCache;
}

function initializeTabs() {
  const tabs = browser.tabs.query({ currentWindow: true });
  return () => tabs;
}

export const badFavIcons = badFavIconCache();
export const getAllTabs = initializeTabs();

export function clearChildren(node) {
  while (node.firstChild) {
    node.removeChild(node.firstChild);
  }
}

function handleBadSvg() {
  badFavIcons().push(this.src);
  this.src = favIconFallback;
}

function shortenString(str) {
  return str.length >= 120
    ? `${str.slice(0, 90)}...`
    : str;
}

function isChromeLink(src) {
  return /chrome:\/\//.test(src);
}

function isURL(src) {
  return /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.test(src);
}

function getBasePath(src) {
  const { origin } = new URL(src);
  return origin;
}


export function switchActiveTab(id) {
  const numId = parseInt(id, 10);
  browser.tabs.update(numId, { active: true });
  window.close();
}

export function switchTabs() {
  // this: should be the tab-object node
  const tabId = this.dataset.id;
  switchActiveTab(tabId);
}

export function clearInput(node) {
  node.value = '';
}

export function populateTabList() {
  getAllTabs().then(injectTabsInList);
}

export function tabToTag({ favIconUrl, title, id, url }) {
  const isValidFavIconUrl = favIconUrl
    && !isChromeLink(favIconUrl)
    && !badFavIcons().includes(favIconUrl);
  const favIconLink = isValidFavIconUrl
    ? favIconUrl
    : favIconFallback;
  // Just check if it's a url for now so we can shorten it
  const tabTitle = isURL(title)
    ? getBasePath(title)
    : title;

  return createTabObject({
    id,
    url,
    tabTitle,
    favIconLink,
  });
}

function createTabObject({
  id,
  url,
  tabTitle,
  favIconLink,
}) {
  // Create the parent div
  // <div class="tab-object" data-id="${id}" tabIndex="0">
  const tabObjectNode = document.createElement('div');
  tabObjectNode.setAttribute('data-id', id);
  tabObjectNode.setAttribute('tabindex', '0');
  tabObjectNode.classList.add('tab-object');

  // favicon
  // <img src="${favIconLink}">
  const favIconNode = document.createElement('img');
  favIconNode.setAttribute('src', favIconLink);
  favIconNode.onerror = handleBadSvg;

  // tab-info
  //    <div class="tab-info">
  const tabInfoNode = document.createElement('div');
  tabInfoNode.setAttribute('class', 'tab-info');

  //      <strong>${title}</strong>
  const titleNode = document.createElement('strong');
  titleNode.classList.add('tab-title');
  titleNode.appendChild(document.createTextNode(tabTitle));

  //      <p>${url}</p>
  const urlNode = document.createElement('p');
  urlNode.appendChild(document.createTextNode(url));

  // Append all block elements
  tabInfoNode.appendChild(titleNode);
  tabInfoNode.appendChild(urlNode);

  tabObjectNode.appendChild(favIconNode);
  tabObjectNode.appendChild(tabInfoNode);

  return tabObjectNode;
}

// Get focused node's position relative to the current scrolled view
export function getNodePositions(parentNode, selectedNode) {
  return {
    parentHeight: parentNode.offsetHeight,
    selectedBottom: selectedNode.offsetHeight + (
      selectedNode.offsetTop - parentNode.offsetTop
    ) - parentNode.scrollTop,
    selectedTop: (
      selectedNode.offsetTop - parentNode.offsetTop
    ) - parentNode.scrollTop,
  };
}

export function createNoResult() {
  // <div class="no-result">
  //   <object type="image/svg+xml" data="/assets/alert-circle.svg"></object>
  //   <strong>No tabs found</strong>
  // </div>
  const noResultNode = document.createElement('div');
  noResultNode.classList.add('no-result');<commit_msg>Add back handleBadSvg<commit_after>import {
  favIconFallback,
  alertCircle,
  tabList,
  searchInput,
} from './constants';
// Store all the bad favIcons so we don't get loading jank if a favIcon !exist
function badFavIconCache() {
  const badIconCache = [];
  return () => badIconCache;
}

function initializeTabs() {
  const tabs = browser.tabs.query({ currentWindow: true });
  return () => tabs;
}

const badFavIcons = badFavIconCache();
export const getAllTabs = initializeTabs();

function clearChildren(node) {
  while (node.firstChild) {
    node.removeChild(node.firstChild);
  }
}

function isChromeLink(src) {
  return /chrome:\/\//.test(src);
}

function isURL(src) {
  return /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.test(src);
}

function getBasePath(src) {
  const { origin } = new URL(src);
  return origin;
}


export function switchActiveTab(id) {
  const numId = parseInt(id, 10);
  browser.tabs.update(numId, { active: true });
  window.close();
}

function switchTabs() {
  // this: should be the tab-object node
  const tabId = this.dataset.id;
  switchActiveTab(tabId);
}

export function clearInput(node) {
  node.value = '';
}

export function populateTabList() {
  getAllTabs().then(injectTabsInList);
}

export function tabToTag({ favIconUrl, title, id, url }) {
  const isValidFavIconUrl = favIconUrl
    && !isChromeLink(favIconUrl)
    && !badFavIcons().includes(favIconUrl);
  const favIconLink = isValidFavIconUrl
    ? favIconUrl
    : favIconFallback;
  // Just check if it's a url for now so we can shorten it
  const tabTitle = isURL(title)
    ? getBasePath(title)
    : title;

  return createTabObject({
    id,
    url,
    tabTitle,
    favIconLink,
  });
}

function createTabObject({
  id,
  url,
  tabTitle,
  favIconLink,
}) {
  // Create the parent div
  // <div class="tab-object" data-id="${id}" tabIndex="0">
  const tabObjectNode = document.createElement('div');
  tabObjectNode.setAttribute('data-id', id);
  tabObjectNode.setAttribute('tabindex', '0');
  tabObjectNode.classList.add('tab-object');

  // favicon
  // <img src="${favIconLink}">
  const favIconNode = document.createElement('img');
  favIconNode.setAttribute('src', favIconLink);
  favIconNode.onerror = handleBadSvg;

  // tab-info
  //    <div class="tab-info">
  const tabInfoNode = document.createElement('div');
  tabInfoNode.setAttribute('class', 'tab-info');

  //      <strong>${title}</strong>
  const titleNode = document.createElement('strong');
  titleNode.classList.add('tab-title');
  titleNode.appendChild(document.createTextNode(tabTitle));

  //      <p>${url}</p>
  const urlNode = document.createElement('p');
  urlNode.appendChild(document.createTextNode(url));

  // Append all block elements
  tabInfoNode.appendChild(titleNode);
  tabInfoNode.appendChild(urlNode);

  tabObjectNode.appendChild(favIconNode);
  tabObjectNode.appendChild(tabInfoNode);

  return tabObjectNode;
}

function handleBadSvg() {
  badFavIcons().push(this.src);
  this.src = favIconFallback;
}

// Get focused node's position relative to the current scrolled view
export function getNodePositions(parentNode, selectedNode) {
  return {
    parentHeight: parentNode.offsetHeight,
    selectedBottom: selectedNode.offsetHeight + (
      selectedNode.offsetTop - parentNode.offsetTop
    ) - parentNode.scrollTop,
    selectedTop: (
      selectedNode.offsetTop - parentNode.offsetTop
    ) - parentNode.scrollTop,
  };
}

export function createNoResult() {
  // <div class="no-result">
  //   <object type="image/svg+xml" data="/assets/alert-circle.svg"></object>
  //   <strong>No tabs found</strong>
  // </div>
  const noResultNode = document.createElement('div');
  noResultNode.classList.add('no-result');
{'fraction_non_alphanumeric': 0.15151910288173165, 'fraction_numerical': 0.0044334333029078105, 'mean_word_length': 4.029508196721311, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3778580', 'n_tokens_mistral': 2569, 'n_tokens_neox': 2533, 'n_words': 502}