Greasy Fork is available in English.

Google Apps Script | Editor Plus

Дополнительные возможности для редактора Google Скриптов.

Verzia zo dňa 03.06.2018. Pozri najnovšiu verziu.

// ==UserScript==
// @name         Google Apps Script | Editor Plus
// @description  Дополнительные возможности для редактора Google Скриптов.
// @iconURL      https://ssl.gstatic.com/images/icons/product/script_chrome_only-256.png
// @screenshot   https://ssl.gstatic.com/images/icons/product/script_chrome_only-256.png
// @version      0.1
// @author       +stomaks (sto.maks+tampermonkey.net@gmail.com)
// @developer    +stomaks (sto.maks+tampermonkey.net@gmail.com)
// @domain       script.google.com
// @include      https://script.google.com/d/*
// @include      https://script.google.com/macros/d/*
// @include      https://script.google.com/a/*/d/*
// @include      https://script.google.com/macros/a/*/d/*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
// @grant        none
// @namespace https://greasyfork.org/users/189193
// ==/UserScript==

(function() {
    'use strict';
    //+--------------------------------------------------------------------------------------------+
    $(`head`).append(`<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">`);
    $(`head`).append(`
        <style class="custom">
            #theme,
            #menu {
              vertical-align: top;
              padding-left: 7px;
              padding-right: 7px;
              margin-top: 4px;
              margin-left: -5px;
              margin-right: -3px;
              border-radius: 2px;
              cursor: pointer;
            }

            #theme {float: right; }

            .hide-menu #menu {
              -webkit-box-shadow: none;
              box-shadow: inset none;
              background-color: transparent;
              background-image: transparent;
              background-image: transparent;
              border-color: transparent;
            }

            #theme:hover,
            #menu:hover,
            #menu {
              -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
              box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
              background-color: #f6f6f6;
              background-image: -webkit-gradient(linear, left top, left bottom, from(top), color-stop(#f6f6f6), to(#f1f1f1));
              background-image: linear-gradient(top, #f6f6f6, #f1f1f1);
              border-color: #c6c6c6;
            }

            #menu {
              font-size: 18px;
              line-height: 25px;
            }

            .hide-menu .gwt-SplitLayoutPanel > div:nth-child(2):hover {
               z-index: 15;
               box-shadow: 3px 0 5px rgba(0, 0, 0, 0.15);
            }

            .hide-menu .gwt-SplitLayoutPanel > div:nth-child(2) .resource-list {
               display: none;
            }

            .hide-menu .gwt-SplitLayoutPanel > div:nth-child(2):hover .resource-list {
               display: block;
            }

            .hide-menu .gwt-SplitLayoutPanel > div:nth-child(3) {
               display: none;
            }

            .hide-menu .gwt-SplitLayoutPanel > div:nth-child(4) {
               left: 9px !important;
            }

            .goog-toolbar-button,
            .editor .code-area .CodeMirror-gutter-text pre,
            .gwt-TabLayoutPanelTab .gwt-Label,
            .project-items-list > * {
              cursor: pointer !important;
            }

            body[theme=dark] {
              color: #bbbbbb;
              background-color: #2b2b2b;
            }

            body[theme=dark] .docs-title-inner {
              color: #ccc;
            }

            body[theme=dark] #gb#gb a.gb_b {
              color: #eee;
            }

            body[theme=dark] #docs-chrome {
              background: #3d3f41;
            }

            body[theme=dark] #docs-toolbar-wrapper {
              border-top: 1px solid #3d3f41;
              border-bottom: 1px solid #242627;
              background-color: #3d3f41;
              background-image: -webkit-linear-gradient(top, #37383a, #3d3f41);
              background-image: -webkit-linear-gradient(top, #37383a, #3d3f41);
              -webkit-box-shadow: inset 0 1px 0 0 #2b2b2b;
              box-shadow: inset 0 1px 0 0 #2b2b2b;
            }

            body[theme=dark] .docs-menubar .goog-control-hover {
              color: #000
            }

            body[theme=dark] .goog-toolbar-separator.goog-inline-block {
              border-left: 1px solid #242627;
            }

            body[theme=dark] .goog-toolbar-button-hover,
            body[theme=dark] .goog-toolbar-button-active,
            body[theme=dark] .goog-toolbar-button-checked,
            body[theme=dark] .goog-toolbar-button-selected {
              color: #fff;
            }

            body[theme=dark] .goog-toolbar-button-selected,
            body[theme=dark] .goog-toolbar-button-checked,
            body[theme=dark] .goog-toolbar-menu-button-open {
              -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
              box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
              background-color: rgba(255, 255, 255, 0.1);
              background-image: -webkit-gradient(linear, left top, left bottom, from(top), color-stop(rgba(255, 255, 255, 0.15)), to(rgba(255, 255, 255, 0.2)));
              background-image: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.2));
              border-color: rgba(255, 255, 255, 0.2);
            }

            body[theme=dark] .goog-toolbar-button,
            body[theme=dark] .goog-toolbar-menu-button,
            body[theme=dark] .project-items-list img {
              -webkit-filter: invert(100%);
              filter: invert(100%);
            }

            .editor .code-area .CodeMirror {
                line-height: 17px !important;
            }

            body[theme=dark] .editor .code-area .CodeMirror {
              background-color: #2B2B2B;
            }

            body[theme=dark] .editor .code-area .CodeMirror pre {
              color: #999;
            }

            body[theme=dark] .editor .code-area .CodeMirror-cursor {
              border-left: 1px solid #fff!important;
            }

            body[theme=dark] .CodeMirror-focused div.CodeMirror-selected {
              background-color: #214283;
            }

            body[theme=dark] div.CodeMirror-selected {
              background-color: #214283;
            }

            body[theme=dark] .autocomplete {
              background-color: #515658;
            }

            body[theme=dark] .autocomplete .selected {
              background-color: #2B2B2B;
              color: #bbbbbb;
            }

            body[theme=dark] .editor .code-area .CodeMirror-gutter {
              background-color: #2B2B2B;
              border-left: 1px solid;
              border-right: 1px solid;
              border-color: #242627;
            }

            body[theme=dark] .editor .code-area .CodeMirror-gutter-text {
              background-color: #2B2B2B;
              -webkit-box-shadow: -1px 0px 0px 0px #242627, 1px 0px 0px 0px #242627;
              box-shadow: -1px 0px 0px 0px #242627, 1px 0px 0px 0px #242627;
            }


            /* Цвета кода */

            body[theme=dark] .cm-s-default span.cm-keyword {
              color: #cc7832;
            }

            body[theme=dark] .cm-s-default span.cm-atom {
              color: #cc7832;
            }

            body[theme=dark] .cm-s-default span.cm-number {
              color: #6897bb;
            }

            body[theme=dark] .cm-s-default span.cm-def {
              color: #ffc66d;
            }

            .cm-s-default span.cm-variable {
              color: #00f;
            }

            body[theme=dark] .cm-s-default span.cm-variable {
              color: #ffc66d;
            }

            body[theme=dark] .cm-s-default span.cm-variable-2 {
              color: #CDD7E0;
            }

            body[theme=dark] .cm-s-default span.cm-variable-3 {
              color: #ffc66d;
            }

            body[theme=dark] .cm-s-default span.cm-property {
              color: #9876aa;
            }

            body[theme=dark] .cm-s-default span.cm-operator {
              color: #bbbbbb;
            }

            .cm-s-default span.cm-comment {
              color: #888888;
            }

            body[theme=dark] .cm-s-default span.cm-comment {
              color: #888888;
            }

            body[theme=dark] .cm-s-default span.cm-string {
              color: #6a8759;
            }

            body[theme=dark] .cm-s-default span.cm-string-2 {
              color: #f50;
            }

            body[theme=dark] .cm-s-default span.cm-meta {
              color: #555;
            }

            body[theme=dark] .cm-s-default span.cm-error {
              color: #FF2E0B;
            }

            body[theme=dark] .cm-s-default span.cm-qualifier {
              color: #FF861E;
            }

            body[theme=dark] .cm-s-default span.cm-builtin {
              color: #FF861E;
            }

            body[theme=dark] .cm-s-default span.cm-bracket {
              color: #997;
            }

            body[theme=dark] .cm-s-default span.cm-tag {
              color: #ffc66d;
            }

            body[theme=dark] .cm-s-default span.cm-attribute {
              color: #A772D0;
            }

            body[theme=dark] .cm-s-default span.cm-header {
              color: #00ECFF;
            }

            body[theme=dark] .cm-s-default span.cm-quote {
              color: #090;
            }

            body[theme=dark] .cm-s-default span.cm-hr {
              color: #999;
            }

            body[theme=dark] .cm-s-default span.cm-link {
              color: #00c;
            }

            body[theme=dark] .editor .gwt-TabLayoutPanelTabs {
              background-color: #3c3f41;
              border-color: #242627;
            }

            body[theme=dark] .editor .gwt-TabLayoutPanelTab {
              background-color: #515658;
              border-color: #242627;
            }

            body[theme=dark] .editor .gwt-TabLayoutPanelTab-selected {
              background-color: #2b2b2b;
            }

            body[theme=dark] .editor .gwt-TabLayoutPanelTab:hover .name,
            body[theme=dark] .editor .gwt-TabLayoutPanelTab-selected .tab-header .name {
              color: #bbbbbb;
            }

            body[theme=dark] .editor .gwt-TabLayoutPanelTab-selected:hover {
              background-color: #2B2B2B;
            }

            body[theme=dark] .editor .gwt-TabLayoutPanelTab:hover {
              background-color: #2B2B2B;
            }

            body[theme=dark] .resource-list {
              background-color: #3c3f41;
              color: #bbbbbb;
            }

            body[theme=dark] .resource-list .project-items-list .item {
              border-bottom: 1px solid #242627;
            }

            body[theme=dark] .resource-list .project-items-list .selected,
            body[theme=dark] .resource-list .project-items-list .selected:hover {
              background-color: #4b6eaf;
              color: #bbbbbb;
            }

            body[theme=dark] .resource-list .project-items-list .focused,
            body[theme=dark] .resource-list .project-items-list .item:hover {
              background-color: #0d293e;
              color: #bbbbbb;
            }

            body[theme=dark] .workspace .gwt-SplitLayoutPanel-HDragger {
              background-color: #3c3f41!important;
              border-left: 1px solid #242627!important;
            }

            body[theme=dark] .workspace .gwt-SplitLayoutPanel-VDragger {
              background-color: #3c3f41 !important;
              border-top: 1px solid #242627!important;
            }

            body[theme=dark] .workspace .gwt-SplitLayoutPanel-HDragger:hover,
            body[theme=dark] .workspace .gwt-SplitLayoutPanel-VDragger:hover {
              background-color: #0d293e!important;
            }

            body[theme=dark] .status-bar {
              background-color: #3c3f41;
              border-top: 1px solid #242627;
            }

            body[theme=dark] .workspace .aux-info {
              background-color: #3c3f41;
            }

            body[theme=dark] .workspace .aux-info .debugger-frame-label {
              background-color: #4b6eaf;
            }

            body[theme=dark] .workspace .aux-info .debugger-frame-label-selected {
              background-color: #0d293e;
              color: #bbbbbb;
            }

            body[theme=dark] .workspace .aux-info .debugger-callstack-wrapper {
              border-left: 1px solid #242627;
              border-top: 1px solid #242627;
            }

            body[theme=dark] .workspace .aux-info .treetable-wrapper {
              border-left: 1px solid #242627;
              border-top: 1px solid #242627;
            }

            body[theme=dark] .workspace .aux-info .treetable-wrapper .treetable-wrapper {
              border-left: none;
              border-top: none;
            }

            body[theme=dark] .workspace .aux-info .treetable-background-2 {
              background-color: #3c3f41;
            }

            body[theme=dark] .workspace .aux-info .treetable-background-1 {
              background-color: #49473f;
            }

            body[theme=dark] .CodeMirror-scroll.cm-s-default::-webkit-scrollbar-thumb {
              background-color: rgba(134, 130, 115, 0.45);
            }

            body[theme=dark] .resource-context-menu {
              color: #3c3f41;
            }

            body[theme=dark] .asc_Folder > .asc_titleContainer {
              color: #8a93ab;
            }

            body[theme=dark] .asc_info_popup {
              color: #bbbbbb;
              background: #2B2B2B;
              border-color: #bbbbbb;
            }

            .CodeMirror-lines > div {
              margin-left: 50px !important;
            }

            /* + пространство для скролла после кода */
            .CodeMirror-lines > div > div:last-child > pre:last-child,
            .CodeMirror-scrollbar-inner {
              margin-bottom: 100px !important;
            }

            /* оформляем статус бар */
            div.status-bar,
            div.status-bar #lines {
              display: flex;
              flex-direction: row;
              flex-wrap: wrap;
              justify-content: space-between;
            }
            div.status-bar {
              padding-left: 58px;
              padding-right: 44px;
            }

            div.status-bar #cursor_position {
              opacity: .75;
            }

            div.status-bar #num_lines {
              padding-left: 15px;
              opacity: .5;
            }

            div.status-bar #type-of-location a {
              font-size: 10px;
              color: #777;
              letter-spacing: 1px;
            }

            /* Маркеры для строк */
            pre.active-line {
              color: #000000 !important;
            }

            body[theme=dark] pre.active-line {
              color: #ffffff !important;
            }

            pre.active-line:after {
              content: "";
              position: absolute;
              width: 100%;
              height: 18px;
              left: 0;
              margin-top: -1px;
              background: rgba(0, 0, 0, 0.05);
            }

            body[theme=dark] pre.active-line:after {
              background: rgba(255, 255, 255, 0.05);
            }



            /* note line */
            pre.note-line:before {
              color: #999;
            }
            pre.note-line {
            }
            .CodeMirror-lines > div > div:last-child pre.note-line:before {
              content: '”';
              position: absolute;
              left: -15px;
              margin-top: 5px;
              font-size: 24px;
            }
            .CodeMirror-lines > div > div:last-child pre.note-line {
            }
            .CodeMirror-lines > div > div:last-child pre.note-line span {
            }
            .CodeMirror-gutter-text pre.note-line:before {
            }
            .CodeMirror-gutter-text pre.note-line {
            }



            /* todo line */
            pre.todo-line:before {
              color: #999;
            }
            pre.todo-line {
            }
            .CodeMirror-lines > div > div:last-child pre.todo-line:before {
              content: "";
              position: absolute;
              left: -15px;
              width: 10px;
              margin-top: 3px;
              border-radius: 2px;
              height: 10px;
              border: 1px solid;
              font-size: 24px;
              /* cursor: pointer; */
              pointer-events: all;
            }
            .CodeMirror-lines > div > div:last-child pre.todo-line {
              pointer-events: none;
            }
            .CodeMirror-lines > div > div:last-child pre.todo-line span {
            }
            .CodeMirror-gutter-text pre.todo-line:before {
            }
            .CodeMirror-gutter-text pre.todo-line {
            }



            /* done line */
            pre.done-line:before,
            pre.done-line:after {
              color: #999;
            }
            pre.done-line {
            }
            .CodeMirror-lines > div > div:last-child pre.done-line:after {
              content: "✓";
              position: absolute;
              left: -14px;
              font-size: 24px;
              margin-top: -2px;
            }
            .CodeMirror-lines > div > div:last-child pre.done-line:before {
              content: "";
              position: absolute;
              left: -15px;
              width: 10px;
              height: 10px;
              margin-top: 3px;
              border-radius: 2px;
              border: 1px solid;
              /* cursor: pointer; */
              pointer-events: all;
            }
            .CodeMirror-lines > div > div:last-child pre.done-line {
              pointer-events: none;
            }
            .CodeMirror-lines > div > div:last-child pre.done-line span {
              text-decoration: line-through;
            }
            .CodeMirror-gutter-text pre.done-line:before {
            }
            .CodeMirror-gutter-text pre.done-line {
            }



            /* strong line */
            pre.strong-line {
              font-weight: 900;
              /* filter: contrast(2); */
            }

            #documentation_in_russian:hover,
            #generator_pryamykh_ssylok:hover {
              background: #eee;
            }



            /* Высплывающие окна */
            .modal-dialog.docs-dialog .script-logging-dialog-content,
            .maestro-dialog > div > table .revisions-box table {
              line-height: 20px;
            }

            .revisions-box .stack .gwt-StackPanelItem {
              letter-spacing: .3px;
            }



            .hide {display: none !important; }
        </style>
    `);
    //+--------------------------------------------------------------------------------------------+



    //+--------------------------------------------------------------------------------------------+
    // Объявление переменных
    var lang = $(`html`).attr(`lang`),
        storage = JSON.parse( localStorage.getItem("storage") ), // Получаем данные из localStorage
        toolbar = $(`#docs-toolbar-wrapper`), // Панель инструментов
        text = {
            'ru': {
                'theme_white': 'Тема: Светлая',
                'theme_dark': 'Тема: Темная',
                'sidebar': 'Боковое меню',
                'сontainer_bound_scripts_gsuite': 'Скрипт, связанный с контейнером (G Suite)',
                'сontainer_bound_scripts': 'Скрипт, связанный с контейнером',
                'standalone_scripts_gsuite': 'Автономный скрипт (G Suite)',
                'standalone_scripts': 'Автономный скрипт',
                'documentation_in_Russian': 'Документация (на Русском)',
                'direct_link_generator': 'Генератор прямых ссылок',
                'direct_link_generator_title': 'Генератор прямых ссылок на файлы в Google Диске',
                'line': 'Строка',
                'lines': 'строк'
            },
            'en': {
                'theme_white': 'Theme: White',
                'theme_dark': 'Theme: Dark',
                'sidebar': 'Sidebar',
                'сontainer_bound_scripts_gsuite': 'Container-bound Scripts (G Suite)',
                'сontainer_bound_scripts': 'Container-bound Scripts',
                'standalone_scripts_gsuite': 'Standalone Scripts (G Suite)',
                'standalone_scripts': 'Standalone Scripts',
                'documentation_in_Russian': 'Documentation (in Russian)',
                'direct_link_generator': 'Direct link generator',
                'direct_link_generator_title': 'Generator of direct links to files in Google Drive',
                'line': 'Line',
                'lines': 'lines'
            }
        };
    //+--------------------------------------------------------------------------------------------+



    if (lang !== 'ru') lang = 'en';
    


    //+--------------------------------------------------------------------------------------------+
    // Проверка, существуют ли данные в localStorage
    if ( !storage ) {

        // Данные не существуют, создаем
        storage = {
            theme: "white",
            menu: "hide"
        };

        // Обновляем localStorage
        localStorage.setItem("storage", JSON.stringify(storage) );
    }



    // Устанавливаем кнопку для смены темы [светлая|темная]
    toolbar.append(`<i id="theme" class="material-icons goog-toolbar-button" theme="white" title='${ text[lang].theme_white }'>hdr_weak</i>`);



    // Устанавливаем обработчик для переключателя темы
    toolbar.on("click", "#theme", function () {
        var theme = $(this).attr('theme');

        if (theme == "white") {
            $("body").attr("theme", "dark");
            $(this).attr("title", text[lang].theme_dark).attr("theme", "dark"); // .text('hdr_strong')

            storage.theme = "dark";
        }
        else {
            $('body').attr('theme', 'white');
            $(this).text('hdr_weak').attr('title', text[lang].theme_white).attr('theme', 'white');

            storage.theme = "white";
        }

        // Обновляем localStorage
        localStorage.setItem("storage", JSON.stringify(storage) );
        return;
    });

    // Если пользователь выбрал темную тему
    if ( storage.theme == "dark" ) {
        $("body").attr("theme", "dark");
        $("#theme").text('hdr_weak').attr("title", text[lang].theme_dark).attr("theme", "dark");
    }
    //+--------------------------------------------------------------------------------------------+





    //+--------------------------------------------------------------------------------------------+
    // Устанавливаем кнопку для меню
    toolbar.prepend(`
        <i id="menu" class="material-icons goog-toolbar-button" title='${ text[lang].sidebar }'>menu</i>
        <div class="goog-toolbar-separator goog-inline-block" aria-disabled="true" role="separator" id=":2c" style="user-select: none;">&nbsp;</div>
    `);

    // Обработка события нажатия на кнопку "меню" блока
    $(`body`).on("click", "#menu", function () {
        var menu = $("body").hasClass("hide-menu");

        if ( menu ) {
            $("body").removeClass("hide-menu");
            storage.menu = "show";
        } else {
            $("body").addClass("hide-menu");
            storage.menu = "hide";
        }

        // Обновляем localStorage
        localStorage.setItem("storage", JSON.stringify(storage) );
        return;
    });
    //+--------------------------------------------------------------------------------------------+




    //+--------------------------------------------------------------------------------------------+
    // editor
    function editor_() {
        var statusbar = $(`div.status-bar`),
            focused_tab = $(`.CodeMirror-scroll.CodeMirror-focused`).parents(`.CodeMirror`),
            code_panel = focused_tab.find(`.CodeMirror-lines > div > div:last-child`),
            lines = code_panel.find(`pre`),
            num_lines = ($(`.CodeMirror .CodeMirror-scroll.CodeMirror-focused > div`).css(`min-height`) || '0px').replace(`px`, ''),
            active_line= (parseInt(focused_tab.find(`.CodeMirror-lines .CodeMirror-cursor`).css(`top`)) / 17) + 1,
            temp;

        // Определяем количество строк
        if ( num_lines > 0) {
            num_lines = ((parseInt( num_lines ) - 20) / 17);
        } else {
            num_lines = lines.length;
        }

        if ( !$(`*`).is(`.status-bar #lines.status-item`) ) statusbar.append(`<div id="type-of-location" class="status-item"> </div> <div id="lines" class="status-item"> <span id="cursor_position"></span> <span id="num_lines"></span> </div>`);

        lines.each(function( index ) {
            var text = $( this ).text(),
                el = focused_tab.find(`.CodeMirror-gutter-text pre:nth-child(${ index + 1 }), .CodeMirror-lines > div > div:last-child pre:nth-child(${ index + 1 })`);

            if ( new RegExp(/\/\/!/).test( text ) ) el.addClass('strong-line');

            if ( new RegExp(/\/\/\stodo|\/\/!\stodo/i).test( text ) ) el.addClass('todo-line');

            if ( new RegExp(/\/\/\sdone|\/\/!\sdone/i).test( text ) ) el.addClass('done-line');

            if ( new RegExp(/\/\/\snote|\/\/!\snote/i).test( text ) ) el.addClass('note-line');

            return;
        });

        // Установка классов на строки
        focused_tab.find(`.CodeMirror-gutter-text pre`).removeClass('active-line');
        focused_tab.find(`.CodeMirror-gutter-text pre:nth-child(${ active_line })`).addClass('active-line');


        // Установка данных в статусе
        statusbar.find(`#lines #num_lines`).text( `${ num_lines } - ${ text[lang].lines }` );
        statusbar.find(`#lines #cursor_position`).text( `${ text[lang].line } ${ focused_tab.find(`.CodeMirror-gutter-text pre:nth-child(${ active_line })`).text().replace(`●`, '') }` );

        // Определяем тип скрипта
        temp = getTypeOfLocation();
        if ( temp && typeof temp === 'object' ) {
            statusbar.find(`#type-of-location`).html( `<a href='${ temp.href + getUser() }' title='${ temp.title }' target="_blank">${ temp.text }</a>` );
        }

        return;
    }



    // Определяем тип скрипта
    function getTypeOfLocation () {
        var href = window.location.href,
            types = [
                { // Скрипт, связанный с контейнером (G Suite)
                    mask: '^https:\/\/script\.google\.com\/a\/.*?\/macros\/d\/.*$',
                    text: text[lang].сontainer_bound_scripts_gsuite,
                    title: text[lang].сontainer_bound_scripts_gsuite,
                    href: '//g-apps-script.com/skripty-svyazannyye-s-konteynerom/'
                },
                { // Скрипт, связанный с контейнером
                    mask: '^https:\/\/script\.google\.com\/macros\/d\/.*$',
                    text: text[lang].сontainer_bound_scripts,
                    title: text[lang].сontainer_bound_scripts,
                    href: '//g-apps-script.com/skripty-svyazannyye-s-konteynerom/'
                },
                {
                    mask: '^https:\/\/script\.google\.com\/a\/.*?\/d\/.*$',
                    text: text[lang].standalone_scripts_gsuite,
                    title: text[lang].standalone_scripts_gsuite,
                    href: '//g-apps-script.com/avtonomnyye-skripty/'
                },
                {
                    mask: '^https:\/\/script\.google\.com\/d\/.*$',
                    text: text[lang].standalone_scripts,
                    title: text[lang].standalone_scripts,
                    href: '//g-apps-script.com/avtonomnyye-skripty/'
                },
            ];

        for(var min = 0; min < types.length; min++){
            if( new RegExp( types[min].mask ).test(href, 'min') ) return types[min];
        }

        return;
    }

    // Определяем тпользователя
    function getUser () {
        var email = $(`.gb_Cb .gb_Ib`).text() || '',
            first_name = $(`.gb_Cb .gb_Fb.gb_Hb`).text().split(` `)[0] || '',
            last_name = $(`.gb_Cb .gb_Fb.gb_Hb`).text().split(` `)[1] || '';

        return `?source=script.google.com&email=${ email }&first_name=${ first_name }&last_name=${ last_name }`;
    }
    //+--------------------------------------------------------------------------------------------+





    //+--------------------------------------------------------------------------------------------+
    // Добавляем новую кнопку во вкладке "Справка"
    $( `<div class="goog-menuitem apps-menuitem" role="menuitem" aria-disabled="false" id="documentation_in_russian" style="user-select: none;" title="${ text[lang].documentation_in_Russian }">
            <div class="goog-menuitem-content" style="user-select: none;">
                <span class="goog-menuitem-label" style="user-select: none;">${ text[lang].documentation_in_Russian }</span>
            </div>
        </div>` ).insertAfter( ".goog-menu.goog-menu-vertical:eq(6) > :eq(1)" );
    //+--------------------------------------------------------------------------------------------+





    //+--------------------------------------------------------------------------------------------+
    // Добавляем новую кнопку во вкладке "Ресурсы"
    $( `<div class="goog-menuitem apps-menuitem" role="menuitem" aria-disabled="false" id="generator_pryamykh_ssylok" style="user-select: none;" title="${ text[lang].direct_link_generator_title }">
            <div class="goog-menuitem-content" style="user-select: none;">
                <span class="goog-menuitem-label" style="user-select: none;">${ text[lang].direct_link_generator }</span>
            </div>
        </div>` ).insertAfter( ".goog-menu.goog-menu-vertical:eq(5) > :eq(2)" );
    //+--------------------------------------------------------------------------------------------+






    //+--------------------------------------------------------------------------------------------+
    var triggerInterval;
    $(`body`)
        // Определяем положение курсора
        .on("mouseup", ".code-area", function () {return editor_(); })

        // Определяем количество строк
        .keyup(function () {return editor_(); })

        // Обработка события нжатия на кнопку "Документация (на русском)" в меню "Справка".
        .on("click", "#documentation_in_russian", function (e) {
            window.open('https://g-apps-script.com/dokumentatsiya' + getUser(), '_blank');
            return;
        })

        // Обработка события нжатия на кнопку "Генератор прямых ссылок" в меню "Ресурсы".
        .on("click", "#generator_pryamykh_ssylok", function (e) {
            window.open('https://g-apps-script.com/generator-pryamykh-ssylok' + getUser(), '_blank');
            return;
        })

        // Обработка события нжатия на кнопку "todo" в тексте кода.
        .on("click", ".CodeMirror-lines > div > div:last-child pre.todo-line", function (e) {
            console.log('todo');

            // $(this).trigger($.Event('keypress', { keycode: 8 }));
            // $(this).trigger($.Event('keypress', { keycode: 46 }));
            return;
        })

        // Обработка события нжатия на кнопку "todo" в тексте кода.
        .on("click", ".CodeMirror-lines > div > div:last-child pre.done-line", function (e) {
            console.log('done');
            return;
        })

        // Обработка события нжатия на кнопку "Триггеры" на панеле кнопок.
        .on("click", "#triggersButton", function () {
            if ( lang == 'ru' ) {
                // Изменить надпись "Изменение" на "Редактирование" в табличных триггерах
                // начать повторы
                triggerInterval = setInterval(function() {
                    $(`.triggers`).parents(`.maestro-dialog`).attr(`id`, `triggers-dialog`);
                    $(`.triggers tr`).find(`select.gwt-ListBox.listbox:eq(2) option:eq(1)`).text('Редактирование');
                    console.log($(`.triggers tr`));
                }, 500);
            }
            return;
        })

        // Обработка события нжатия на кнопку "Выход" или "Сохранить" в модальном окне Триггеры.
        .on("mousedown", "#triggers-dialog .dialog-close-image, #triggers-dialog .controls > *", function () {
            clearInterval(triggerInterval);
            return;
        })


    ;
    //+--------------------------------------------------------------------------------------------+



    return;
})();