view .cms/js/template.js @ 1:1d486627aa1e draft default tip

24.10
author Coffee CMS <info@coffee-cms.ru>
date Sat, 12 Oct 2024 02:51:39 +0000
parents 78edf6b517a0
children
line wrap: on
line source

document.addEventListener( "DOMContentLoaded", function( event ) {

    function _( str ) {
        return __( str, "template.mod.php" );
    }

    // Edit file
    document.querySelectorAll( "#template .template-files .file" ).forEach( function( button ) {
        button.addEventListener( "click", function( e ) {
            let file = this.innerText;
            // get file from server
            api( { fn: "get_template_file", file: file }, function( r ) {
                if ( r.ok == "true" ) {
                    document.querySelector( ".template-editor-title" ).innerText = file;
                    document.querySelector( ".template-editor > textarea" ).value = r.file;

                    // Show Editor
                    document.querySelector( ".template-editor-bg" ).classList.remove( "hidden" );
                    document.body.classList.add( "editor" ); // for notifications

                    let ext = file.match( /\.[^\.]+$/, "" );
                    let aext = {
                        ".php"  : "application/x-httpd-php",
                        ".html" : "application/x-httpd-php",
                        ".css"  : "text/css"
                    }
                    let atags = {
                        ".php"  : "php",
                        ".html" : "html",
                        ".css"  : "css"
                    }

                    // Отображаем подходящие теги, остальные прячем
                    document.querySelectorAll( `#template .template-editor-bg .snip-grid > *` ).forEach( function( el ) {
                        if ( el.classList.contains( atags[ext] ) ) {
                            el.classList.remove( "hidden" );
                        } else {
                            el.classList.add( "hidden" );
                        }
                    } );

                    // Подключаем редактор Codemirror функцией расположенной в admin.js
                    codemirror_connect( "#template .template-editor > textarea", "cmt", { mode: aext[ext] } );

                    // track changes
                    document.querySelector( ".close-template-button" ).setAttribute( "data-changed", "false" );
                    cmt.on( "change", function( cmt, change ) {
                        document.querySelector( ".close-template-button" ).setAttribute( "data-changed", "true" );
                        document.querySelector( ".template-editor-grid" ).setAttribute( "data-changed", "true" );
                    } );

                    // set cursor to editor
                    cmt.focus();

                    // Save Teplate Ctrl+S
                    document.querySelector( "body" ).addEventListener( "keydown", CtrlS );

                    document.querySelector( ".template-editor-grid" ).setAttribute( "data-changed", "false" );
                }
            } );
        } );
    } );

    // Для сниппетов
    document.querySelectorAll( "#template .snip-grid [data-type='snip']" ).forEach( function( btn ) {
        btn.addEventListener( "click", function( e ) {
            let text = this.getAttribute( "data-text" );
            let cm = window["cmt"];
            if ( cm ) {
                let otag = this.getAttribute( "data-otag" );
                let ctag = this.getAttribute( "data-ctag" );
                let selections = cm.getSelections();
                let replacements = [];
                for ( let i = 0; i < selections.length; i++ ) {
                    replacements[i] = otag + selections[i] + ctag;
                }
                cm.replaceSelections( replacements );
                // с курсорами пока не понятен алгоритм
                /*
                selections = cm.listSelections();
                let shift = +this.getAttribute( "data-len" );
                if ( shift != 0 ) {
                    for ( let i = 0; i < selections.length; i++ ) {
                        selections[i].head.ch += shift;
                        selections[i].anchor.ch += shift;
                    }
                }
                */
                cm.focus();
                cm.refresh();
            }
        } );
    } );

    // Close Editor
    document.querySelectorAll( ".close-template-button" ).forEach( function( button ) {
        button.onclick = function( e ) {
            document.querySelector( "body" ).removeEventListener( "keydown", CtrlS );
            // detach
            if ( window.cmt !== undefined ) {
                if ( this.getAttribute( "data-changed" ) === "true" ) {
                    if ( confirm( _( "confirm_save" ) ) ) {
                        document.querySelector( ".save-template-button" ).setAttribute( "data-close", "true" );
                        document.querySelector( ".save-template-button" ).click();
                        return;
                    }
                }
                window.cmt.toTextArea();
                window.cmt = null;
            }
            // hide editor
            document.querySelector( ".template-editor-bg" ).classList.add( "hidden" );
            document.body.classList.remove( "template_editor" );
            //window.prevent_reload = false;
        };
    } );

    // Save File
    document.querySelectorAll( ".save-template-button" ).forEach( function( button ) {
        button.onclick = function( e ) {
            window.cmt.save(); // drop changes to textarea
            let data = {
                fn: "save_template_file",
                file: document.querySelector( ".template-editor-title" ).innerText,
                content: document.querySelector( ".template-editor > textarea" ).value
            }
            api( data, function( r ) {
                if ( r.info_text ) {
                    notify( r.info_text, r.info_class, r.info_time );
                }
                if ( r.ok == "true" ) {
                    //?
                    document.querySelector( ".close-template-button" ).setAttribute( "data-changed", "false" );
                    // hide changed indicator
                    document.querySelector( ".template-editor-grid" ).setAttribute( "data-changed", "false" );
                    // highlight save button
                    document.querySelector( ".save-template-button" ).classList.add( "saved" );
                    setTimeout( function() {
                        document.querySelector( ".save-template-button" ).classList.remove( "saved" );
                    }, 1000 );
                    // close editor after save only if ok
                    if ( document.querySelector( ".save-template-button" ).getAttribute( "data-close" ) === "true" ) {
                        document.querySelector( ".save-template-button" ).setAttribute( "data-close", "false" );
                        document.querySelector( ".close-template-button" ).click();
                    }
                }
            } );
        };
    } );

    function CtrlS( e ) {
        // ы and і - fix for librewolf
        if ( ( e.code == "KeyS" || e.key == "ы" || e.key == "і" ) && e.ctrlKey == true ) {
            e.preventDefault(); // don't save page
            if ( window.location.hash == "#template" ) {
                document.querySelector( ".save-template-button" ).click();
            }
        }
    }

    // Install template (upload template)
    let input = document.querySelector( "#template-upload" );
    input.addEventListener( "change", async function( e ) {
        const formData = new FormData();
        formData.append( "fn", "install_template" );
        for ( let i = 0; i < input.files.length; i++ ) {
            formData.append( "myfile[]", input.files[i] );
        }
        try {
            const response = await fetch( cms.api, { method: "POST", body: formData } );
            const r        = await response.json();
            input.value = ""; // chrome fix
            if ( r.info_text ) {
                notify( r.info_text, r.info_class, r.info_time );
                setTimeout( function() {
                    window.location.reload( true );
                }, r.info_time );
            }
        } catch ( error ) {
            console.error( "Error:", error );
        }
    } );

    // prevent hide cursor when window resize
    window.addEventListener( "resize", function() {
        if ( window.cmt ) {
            let cursor = window.cmt.getCursor();
            window.cmt.scrollIntoView( { line:cursor.line, ch:cursor.ch } );
        }
    } );

    // Select
    document.querySelectorAll( "#template .field-select" ).forEach( function( select ) {
        select.addEventListener( "click", function( e ) {
            e.stopPropagation();
            this.parentElement.classList.toggle( "open" );
            
            // это можно убрать если переставить стили на родителя
            select.nextElementSibling.classList.toggle( "open" );
        } );
    } );
    // Option
    document.querySelectorAll( "#template .field-options .option" ).forEach( function( option ) {
        option.addEventListener( "click", function( e ) {
            let input = this.closest( ".template-select-grid" ).querySelector( ".field-select" );
            input.querySelector( ".value" ).innerText = this.innerText;
            document.querySelector( "#template input[name='template']" ).value = this.innerText;
        } );
    } );
    // Select
    // Закрытие выпадающих списков при кликах вне их, а так же по ним
    document.body.addEventListener( "click", function( e ) {
        document.querySelectorAll( "#template .template-select-grid" ).forEach( function( list ) {
            list.classList.remove( "open" );
        } );

        // это можно убрать если переставить стили на родителя
        document.querySelectorAll( "#template .field-options" ).forEach( function( list ) {
            list.classList.remove( "open" );
        } );
    } );

} );