<commit_before>/**
 * Inner class which performs selection from either `text` or `target`
 * properties and then executes copy or cut operations.
 */
class ClipboardAction {
    /**
     * @param {Object} options
     */
    constructor(options) {
        this.resolveOptions(options);
        this.initSelection();
    }

    /**
     * Defines base properties passed from constructor.
     * @param {Object} options
     */
    resolveOptions(options = {}) {
        this.action  = options.action;
        this.emitter = options.emitter;
        this.target  = options.target;
        this.text    = options.text;
        this.trigger = options.trigger;

        this.selectedText = '';
    }

    /**
     * Decides which selection strategy is going to be applied based
     * on the existence of `text` and `target` properties.
     */
    initSelection() {
        if (this.text && this.target) {
            throw new Error('Multiple attributes declared, use either "target" or "text"');
        }
        else if (this.text) {
            this.selectFake();
        }
        else if (this.target) {
            this.selectTarget();
        }
        else {
            throw new Error('Missing required attributes, use either "target" or "text"');
        }
    }

    /**
     * Creates a fake textarea element, sets its value from `text` property,
     * and makes a selection on it.
     */
    selectFake() {
        this.removeFake();

        this.fakeHandler = document.body.addEventListener('click', () => this.removeFake());

        this.fakeElem = document.createElement('textarea');
        this.fakeElem.style.position = 'absolute';
        this.fakeElem.style.left = '-9999px';
        this.fakeElem.style.top = document.body.scrollTop + 'px';
        this.fakeElem.setAttribute('readonly', '');
        this.fakeElem.value = this.text;
        this.selectedText = this.text;

        document.body.appendChild(this.fakeElem);

        this.fakeElem.select();
        this.copyText();
    }

    /**
     * Only removes the fake element after another click event, that way
     * an user can hit `Ctrl+C` to copy because selection still exists.
     */
    removeFake() {
        if (this.fakeHandler) {
            document.body.removeEventListener('click');
            this.fakeHandler = null;
        }

        if (this.fakeElem) {
            document.body.removeChild(this.fakeElem);
            this.fakeElem = null;<commit_msg>Fix for scrolling to top in unsupported firefox<commit_after>/**
 * Inner class which performs selection from either `text` or `target`
 * properties and then executes copy or cut operations.
 */
class ClipboardAction {
    /**
     * @param {Object} options
     */
    constructor(options) {
        this.resolveOptions(options);
        this.initSelection();
    }

    /**
     * Defines base properties passed from constructor.
     * @param {Object} options
     */
    resolveOptions(options = {}) {
        this.action  = options.action;
        this.emitter = options.emitter;
        this.target  = options.target;
        this.text    = options.text;
        this.trigger = options.trigger;

        this.selectedText = '';
    }

    /**
     * Decides which selection strategy is going to be applied based
     * on the existence of `text` and `target` properties.
     */
    initSelection() {
        if (this.text && this.target) {
            throw new Error('Multiple attributes declared, use either "target" or "text"');
        }
        else if (this.text) {
            this.selectFake();
        }
        else if (this.target) {
            this.selectTarget();
        }
        else {
            throw new Error('Missing required attributes, use either "target" or "text"');
        }
    }

    /**
     * Creates a fake textarea element, sets its value from `text` property,
     * and makes a selection on it.
     */
    selectFake() {
        this.removeFake();

        this.fakeHandler = document.body.addEventListener('click', () => this.removeFake());

        this.fakeElem = document.createElement('textarea');
        this.fakeElem.style.position = 'absolute';
        this.fakeElem.style.left = '-9999px';
        this.fakeElem.style.top = (window.pageYOffset || document.documentElement.scrollTop) + 'px';
        this.fakeElem.setAttribute('readonly', '');
        this.fakeElem.value = this.text;
        this.selectedText = this.text;

        document.body.appendChild(this.fakeElem);

        this.fakeElem.select();
        this.copyText();
    }

    /**
     * Only removes the fake element after another click event, that way
     * an user can hit `Ctrl+C` to copy because selection still exists.
     */
    removeFake() {
        if (this.fakeHandler) {
            document.body.removeEventListener('click');
            this.fakeHandler = null;
        }

        if (this.fakeElem) {
            document.body.removeChild(this.fakeElem);
            this.fakeElem = null;
{'fraction_non_alphanumeric': 0.11775325977933801, 'fraction_numerical': 0.0016048144433299899, 'mean_word_length': 2.0911345319280845, 'pattern_counts': {'":': 0, '<': 3, '<?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': '2064202', 'n_tokens_mistral': 1354, 'n_tokens_neox': 1313, 'n_words': 349}