<commit_before>import 'site/client/owid.scss'
import 'charts/client/chart.scss'
import './oldScripts.js'
// From https://fontawesome.com/how-to-use/on-the-web/other-topics/server-side-rendering:
// "If the CSS is missing when this icon displays in the browser it will flash
// from a very large icon down to a properly sized one a moment later."
import '@fortawesome/fontawesome-svg-core/styles.css'

import {Analytics} from './Analytics'
import {runChartsIndexPage} from './runChartsIndexPage'
import {runHeaderMenus} from './SiteHeaderMenus'
import {runSearchPage} from './SearchPageMain'
import {runFeedback} from './Feedback'
import {runDonateForm} from './DonateForm'
import {getParent} from './utils'
import {Grapher} from 'site/client/Grapher'
import {ChartView} from 'charts/ChartView'

declare var window: any
window.Grapher = Grapher
window.ChartView = ChartView
window.App = window.App || {}
window.runChartsIndexPage = runChartsIndexPage
window.runHeaderMenus = runHeaderMenus
window.runSearchPage = runSearchPage
window.runFeedback = runFeedback
window.runDonateForm = runDonateForm

Analytics.logEvent("OWID_PAGE_LOAD")

const search = document.querySelector("form#search-nav") as HTMLFormElement
if (search) {
    const input = search.querySelector("input[type=search]") as HTMLInputElement
    search.addEventListener('submit', (ev) => {
        ev.preventDefault()
        Analytics.logEvent("OWID_SITE_SEARCH", { query: input.value }).then(() => search.submit()).catch(() => search.submit())
    })
}

const trackedLinkExists: boolean = !!document.querySelector("[data-track-click]")

if (trackedLinkExists) {
    document.addEventListener("click", (ev) => {
        const targetElement = ev.target as HTMLElement
        const trackedElement = getParent(targetElement, (el: HTMLElement) => el.getAttribute("data-track-click") != null)
        if (trackedElement) {
            // Note this will not work on anchor tags without target=_blank, as
            // they immediately navigate away before the event can be sent.
            // To handle those we need to wait before navigating.
            Analytics.logEvent("OWID_SITE_CLICK", {
                text: trackedElement.innerText,
                href: trackedElement.getAttribute("href"),
                note: trackedElement.getAttribute("data-track-note")
            })
        }
    })
}<commit_msg>Add a delay for tracked links before redirecting<commit_after>import 'site/client/owid.scss'
import 'charts/client/chart.scss'
import './oldScripts.js'
// From https://fontawesome.com/how-to-use/on-the-web/other-topics/server-side-rendering:
// "If the CSS is missing when this icon displays in the browser it will flash
// from a very large icon down to a properly sized one a moment later."
import '@fortawesome/fontawesome-svg-core/styles.css'

import {Analytics} from './Analytics'
import {runChartsIndexPage} from './runChartsIndexPage'
import {runHeaderMenus} from './SiteHeaderMenus'
import {runSearchPage} from './SearchPageMain'
import {runFeedback} from './Feedback'
import {runDonateForm} from './DonateForm'
import {getParent} from './utils'
import {Grapher} from 'site/client/Grapher'
import {ChartView} from 'charts/ChartView'

declare var window: any
window.Grapher = Grapher
window.ChartView = ChartView
window.App = window.App || {}
window.runChartsIndexPage = runChartsIndexPage
window.runHeaderMenus = runHeaderMenus
window.runSearchPage = runSearchPage
window.runFeedback = runFeedback
window.runDonateForm = runDonateForm

Analytics.logEvent("OWID_PAGE_LOAD")

const search = document.querySelector("form#search-nav") as HTMLFormElement
if (search) {
    const input = search.querySelector("input[type=search]") as HTMLInputElement
    search.addEventListener('submit', (ev) => {
        ev.preventDefault()
        Analytics.logEvent("OWID_SITE_SEARCH", { query: input.value }).then(() => search.submit()).catch(() => search.submit())
    })
}

const trackedLinkExists: boolean = !!document.querySelector("[data-track-click]")

function createFunctionWithTimeout(callback: () => void, timeout?: number) {
    let called = false
    function fn() {
        if (!called) {
            called = true
            callback()
        }
    }
    setTimeout(fn, timeout || 500)
    return fn
}

if (trackedLinkExists) {
    document.addEventListener("click", (ev) => {
        const targetElement = ev.target as HTMLElement
        const trackedElement = getParent(targetElement, (el: HTMLElement) => el.getAttribute("data-track-click") != null)
        if (trackedElement) {
            // In order for events to be send for all anchor tags, there needs
            // to be a delay to send the event to amplitude before navigating
            // away from the page.
            const href = trackedElement.getAttribute("href")
            const target = trackedElement.getAttribute("target")
            if (href && target !== "_blank") {
                ev.preventDefault() // prevent immediate redirect
                Analytics.logEvent("OWID_SITE_CLICK", {
                    text: trackedElement.innerText,
                    href: href,
                    note: trackedElement.getAttribute("data-track-note")
                }).then(createFunctionWithTimeout(() => {
                    window.location = href
                }))
            } else {
                Analytics.logEvent("OWID_SITE_CLICK", {
                    text: trackedElement.innerText,
                    href: href,
                    note: trackedElement.getAttribute("data-track-note")
                })
            }
        }
    })
}
{'fraction_non_alphanumeric': 0.11725978647686833, 'fraction_numerical': 0.0005338078291814947, 'mean_word_length': 3.1452802359882006, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '5077823', 'n_tokens_mistral': 1590, 'n_tokens_neox': 1569, 'n_words': 403}