<commit_before>import _each from '../_each';

class InstrumentPageLoad {
    constructor() {
        this._inited = false;
        this._span = null;
    }

    name() {
        return 'instrument_page_load';
    }

    addOptions(tracerImp) {
        tracerImp.addOption('instrument_page_load', { type : 'bool', defaultValue : false });
    }

    start(tracerImp) {
        if (this._inited) {
            return;
        }
        this._inited = true;

        if (typeof window !== 'object' || typeof document !== 'object') {
            return;
        }

        const currentOptions = tracerImp.options();
        if (currentOptions.instrument_page_load) {
            this._ensureSpanStarted(tracerImp);
            document.addEventListener('readystatechange', this._handleReadyStateChange.bind(this));
        }
    }

    stop() {
    }

    _ensureSpanStarted(tracerImp) {
        if (!this._span) {
            this._span = tracerImp.startSpan('document/load');
            tracerImp.addActiveRootSpan(this._span);
        }
    }

    _handleReadyStateChange() {
        if (!this._span) {
            return;
        }

        let span = this._span;
        let state = document.readyState;
        let payload = undefined;
        if (state === 'complete') {
            payload = {};
            if (window.performance && performance.timing) {
                this._addTimingSpans(span, performance.timing);
                payload['window.performance.timing'] = performance.timing;
            }
        }

        span.logEvent(`document.readystatechange ${state}`, payload);

        if (state === 'complete') {
            if (span.tracer()) {
                span.tracer().removeActiveRootSpan(span.tracer());
            }
            span.finish();
        }
    }

    _copyNavigatorProperties(nav) {
        let dst = {};
        for (let key in nav) { // eslint-disable-line guard-for-in
            try {
                let value = nav[key];
                switch (key) {

                case 'plugins': {
                    let p = [];
                    for (let i = 0; i < value.length; i++) {
                        let item = value.item(i);
                        p.push({
                            name        : item.name,
                            description : item.description,
                        });
                    }
                    dst[key] = p;
                } break;

                case 'mimeTypes': {
                    let p = [];
                    for (let i = 0; i < value.length; i++) {
                        let item = value.item(i);
                        p.push({
                            type        : item.type,
                            description : item.description,
                            suffixes    : item.suffixes,
                        });
                    }
                    dst[key] = p;
                } break;

                default:
                    dst[key] = value;
                    break;
                }
            } catch (e) {
                // Skip, just in case
            }
        }
        return dst;
    }

    // Retroactively create the appropriate spans and logs
    _addTimingSpans(parentImp, timing) {
        // NOTE: this currently relies on LightStep-specific APIs
        if (!parentImp) {
            return;
        }

        parentImp.setTag('user_agent', navigator.userAgent);

        _each(timing, (value, key) => {
            // e.g. secureConnectionStart is not always set
            if (typeof value !== 'number' || value === 0) {
                return;
            }

            let payload = undefined;

            if (key === 'navigationStart' && typeof navigator === 'object') {
                payload = {
                    navigator : this._copyNavigatorProperties(navigator),
                };
            }
            parentImp.log({
                message : `document ${key}`,
                payload : payload,
            }, value);
        });

        if (window.chrome && window.chrome.loadTimes) {
            let chromeTimes = window.chrome.loadTimes();
            if (chromeTimes) {
                parentImp.log({
                    message : 'window.chrome.loadTimes()',
                    payload : chromeTimes,
                }, timing.domComplete);
            }
        }

        parentImp.setBeginMicros(timing.navigationStart * 1000.0);<commit_msg>Remove deprecated chrome.loadTimes() code (#157)<commit_after>import _each from '../_each';

class InstrumentPageLoad {
    constructor() {
        this._inited = false;
        this._span = null;
    }

    name() {
        return 'instrument_page_load';
    }

    addOptions(tracerImp) {
        tracerImp.addOption('instrument_page_load', { type : 'bool', defaultValue : false });
    }

    start(tracerImp) {
        if (this._inited) {
            return;
        }
        this._inited = true;

        if (typeof window !== 'object' || typeof document !== 'object') {
            return;
        }

        const currentOptions = tracerImp.options();
        if (currentOptions.instrument_page_load) {
            this._ensureSpanStarted(tracerImp);
            document.addEventListener('readystatechange', this._handleReadyStateChange.bind(this));
        }
    }

    stop() {
    }

    _ensureSpanStarted(tracerImp) {
        if (!this._span) {
            this._span = tracerImp.startSpan('document/load');
            tracerImp.addActiveRootSpan(this._span);
        }
    }

    _handleReadyStateChange() {
        if (!this._span) {
            return;
        }

        let span = this._span;
        let state = document.readyState;
        let payload = undefined;
        if (state === 'complete') {
            payload = {};
            if (window.performance && performance.timing) {
                this._addTimingSpans(span, performance.timing);
                payload['window.performance.timing'] = performance.timing;
            }
        }

        span.logEvent(`document.readystatechange ${state}`, payload);

        if (state === 'complete') {
            if (span.tracer()) {
                span.tracer().removeActiveRootSpan(span.tracer());
            }
            span.finish();
        }
    }

    _copyNavigatorProperties(nav) {
        let dst = {};
        for (let key in nav) { // eslint-disable-line guard-for-in
            try {
                let value = nav[key];
                switch (key) {

                case 'plugins': {
                    let p = [];
                    for (let i = 0; i < value.length; i++) {
                        let item = value.item(i);
                        p.push({
                            name        : item.name,
                            description : item.description,
                        });
                    }
                    dst[key] = p;
                } break;

                case 'mimeTypes': {
                    let p = [];
                    for (let i = 0; i < value.length; i++) {
                        let item = value.item(i);
                        p.push({
                            type        : item.type,
                            description : item.description,
                            suffixes    : item.suffixes,
                        });
                    }
                    dst[key] = p;
                } break;

                default:
                    dst[key] = value;
                    break;
                }
            } catch (e) {
                // Skip, just in case
            }
        }
        return dst;
    }

    // Retroactively create the appropriate spans and logs
    _addTimingSpans(parentImp, timing) {
        // NOTE: this currently relies on LightStep-specific APIs
        if (!parentImp) {
            return;
        }

        parentImp.setTag('user_agent', navigator.userAgent);

        _each(timing, (value, key) => {
            // e.g. secureConnectionStart is not always set
            if (typeof value !== 'number' || value === 0) {
                return;
            }

            let payload = undefined;

            if (key === 'navigationStart' && typeof navigator === 'object') {
                payload = {
                    navigator : this._copyNavigatorProperties(navigator),
                };
            }
            parentImp.log({
                message : `document ${key}`,
                payload : payload,
            }, value);
        });

        parentImp.setBeginMicros(timing.navigationStart * 1000.0);
{'fraction_non_alphanumeric': 0.11133085155886459, 'fraction_numerical': 0.0022103303862261517, 'mean_word_length': 1.1936718550650676, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '918356', 'n_tokens_mistral': 2281, 'n_tokens_neox': 2117, 'n_words': 447}