Google Forms to Text

Save "Google Forms" forms to a plaintext and copy to clipboard

// ==UserScript==
// @name           Google Forms to Text
// @description    Save "Google Forms" forms to a plaintext and copy to clipboard
// @namespace      https://github.com/limtis0/
// @author         https://github.com/limtis0/
// @license        MIT
// @version        1.1
// @match          http*://docs.google.com/forms/*
// ==/UserScript==

// Radiogroups
const radiogroupSelector = '[role="radiogroup"]';
const radiogroupOptionsSelector = '[role="radiogroup"] > span  span';

// Lists
const listSelector = '[role="list"]:not(:has([role="heading"]))';
const listOptionsSelector = '[role="list"]:not(:has([role="heading"])) span';

// Dropdowns
const dropdownSelector = '[role="listbox"]';
const dropdownOptionsSelector = '[role="listbox"] [role="option"]:not(:nth-of-type(1)) span';

// Text input
const textInputSelector = 'input[type="text"]';

// General
const mainListSelector = '[role="list"]'
const questionsSelector = '[role="list"]:not(:first-of-type) > [role="listitem"]';
const headerSelector = '[role="heading"]:first-child span';

const elementTypes = [
    {
        'elementSelector': radiogroupSelector,
        'additionalText': '[Choose one]',
        'parseOptions': true,
        'optionsSelector': radiogroupOptionsSelector,
    },
    {
        'elementSelector': listSelector,
        'additionalText': '[Choose many]',
        'parseOptions': true,
        'optionsSelector': listOptionsSelector,
    },
    {
        'elementSelector': dropdownSelector,
        'additionalText': '[Choose one]',
        'parseOptions': true,
        'optionsSelector': dropdownOptionsSelector,
    },
    {
        'elementSelector': textInputSelector,
        'additionalText': '[Text answer]',
        'parseOptions': false,
    }
];

function isElement(q, elementSelector) {
    return q.querySelector(elementSelector) !== null;
}

function parseQuestion(q, optionsSelector) {
    const options = q.querySelectorAll(optionsSelector);
    let result = '';

    options.forEach(o => {
        result += o.innerHTML + '\n';
    });

    return result;
}

function getQuestions() {
    let questions = document.querySelectorAll(questionsSelector);
    let parsed = '';

    questions.forEach(q => {
        elementTypes.every(t => {
            // For each type of elements, add additional text, and, if needed, options
            if (isElement(q, t.elementSelector)) {
                parsed += `${q.querySelector(headerSelector).innerHTML} ${t.additionalText}\n`;

                if (t.parseOptions) {
                    parsed += parseQuestion(q, t.optionsSelector);
                }
                parsed += '\n';

                return false;
            }

            return true;
        });
    });

    return parsed.trim();
}

function createButton() {
    // Create a new button element
    const button = document.createElement('button');
    button.textContent = 'Copy questions';

    // Set button styles
    button.style.position = 'fixed';
    button.style.bottom = '1rem';
    button.style.right = '1rem';
    button.style.backgroundColor = '#4285f4';
    button.style.color = '#fff';
    button.style.fontFamily = 'Roboto, Arial, sans-serif';
    button.style.fontSize = '14px';
    button.style.padding = '8px 16px';
    button.style.border = 'none';
    button.style.borderRadius = '4px';
    button.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.25)';
    button.style.cursor = 'pointer';

    // Append button to the body element
    document.body.appendChild(button);

    // Add a callback function to the button
    button.addEventListener('click', () => {
        navigator.clipboard.writeText(getQuestions());
    });
}

(function() {
    'use strict';

    if (isElement(document.body, mainListSelector)) {
        createButton();
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址