HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers95/rentman.io/resources/assets/js/kms/kms.js
// 'use strict';
document.addEventListener('DOMContentLoaded', function () {

    //Make the tabs work
    new TabsController('tab-content', 'entity-tabs', 'active', true, 'input[name="tabslug"]');

    //Add a style manager for the visible save button

    //enable save button when present add add a
    let visibleSaveButton = document.getElementById('save-button');
    let saveButtonStyleController = new styleClassController(visibleSaveButton);
    if(visibleSaveButton) {
        visibleSaveButton.addEventListener('click', function (visibleSaveButtonClickEvent) {

            visibleSaveButtonClickEvent.preventDefault();
            const sendThroughFreshnessSubmit = shouldUseNormalSubmit();

            if( sendThroughFreshnessSubmit ) {
                let realSaveButton = document.querySelector('input[value="submit-cloaked"]');
                saveButtonStyleController.requestAddClass('disabled');

                const componentInputs = document.querySelectorAll('.js-components input, .js-components select, .js-components textarea');

                realSaveButton.click();
            }
        });
    }

    //Make the trash button only work when it is confirmed by a model
    let trashButton = document.querySelector('input.trash.confirm');
    if(trashButton) new ConfirmationController(trashButton);

    //Get the form and its translations
    let form = document.getElementById('entity-form');
    let globalTranslations = (form) ? form.dataset.globalTranslations :{};

    //Create an entityInitializer that will look inside of the selected element and when something changes in it, triggers callbacks if needed
    let entityInitializer = new Initializer('#entity-form');

    //Make sure all component areas will be initialized when they show up
    entityInitializer.bindSelectorToCallback('.js-components-area', function(attributesInitializer, componentAreaAttributeElement) {
        let componentAreaManager = new ComponentAreaManager(componentAreaAttributeElement, new ComponentManagerApiController());
    });

    //Make sure all documents attributes are initialized when they show up.
    entityInitializer.bindSelectorToCallback('.entity-attribute-documents', function(attributesInitializer, documentsGroupAttributeElement) {
        let uploadRoute = form.dataset.uploadRoute;
        let maxPostSize = form.dataset.maxPostSize;
        let maxUploadSize = form.dataset.maxUploadSize;
        let html5Uploader = new HTML5Uploader(uploadRoute, maxPostSize, maxUploadSize, globalTranslations);
        let documentManager = new DocumentManager(documentsGroupAttributeElement, html5Uploader);

        new FileDragAndDropHandler(documentsGroupAttributeElement.querySelector('.drag-and-drop-area'))
            .hookTo(documentManager);


        //Enable or disable the save button depending on the uploads
        html5Uploader.on('uploadStart', function () {
            saveButtonStyleController.requestAddClass('disabled')
        });
        html5Uploader.on('uploadComplete', function () {
            saveButtonStyleController.requestRemoveClass('disabled')
        });
        html5Uploader.on('uploadCanceled', function () {
            saveButtonStyleController.requestRemoveClass('disabled')
        });
        html5Uploader.on('uploadFailed', function () {
            saveButtonStyleController.requestRemoveClass('disabled')
        });
    });

    entityInitializer.bindSelectorToCallback('.js-text-field', function(attributesInitializer, TextFieldElement) {
        let TextFieldStuff = new TextField(TextFieldElement);
    });

    entityInitializer.bindSelectorToCallback('.entity-attribute-autocomplete-combo-box', function(attributesInitializer, autocompleteComboBoxAttributeElement) {
        if(autocompleteComboBoxAttributeElement.dataset.readonly === 'false') {
            let autoCompleteInputManager = new AutoCompleteInputManager(autocompleteComboBoxAttributeElement);
        }
    });

    entityInitializer.bindSelectorToCallback('.entity-attribute-on-off', function(attributesInitializer, onOffAttributeElement) {
        let onOff = new OnOff(onOffAttributeElement);
    });

    entityInitializer.bindSelectorToCallback('.js-video', function(attributesInitializer, videoAttributeElement) {
        let video = new Video(videoAttributeElement);
    });

    entityInitializer.bindSelectorToCallback('.entity-attribute-data-table', function (attributesInitializer, dataTableAttributeElement) {
        let dataTable = new DataTable(dataTableAttributeElement);
    });

    //Make sure all confirmable things are initialized when they show up
    entityInitializer.bindSelectorToCallback('.confirm', function(attributesInitializer, confirmableHtmlElement) {
        // console.log('Making the next htmlElement confirmable: ', confirmableHtmlElement);
        new ConfirmationController(confirmableHtmlElement);
    });

    entityInitializer.bindSelectorToCallback('.entity-attribute-select', function(attributesInitializer, selectAttributeElement) {
        let select = new Select(selectAttributeElement);
    });


    entityInitializer.bindSelectorToCallback('[data-to-copy]', function(attributesInitializer, element) {
        // console.log('found copy text element');
        new CopyText(element);
    });

    //Make sure all tiny mce editors are initialized
    entityInitializer.bindSelectorToCallback('.tiny-mce', function (attributesInitializer, inputElement) {
        if(!inputElement.id) inputElement.id = (new Date().getTime())+Math.random().toString(36).substring(7); //Gives the element a random id if it does not have any. Makes it selectable by tinyMce's remove method.

        tinymce.remove('#'+inputElement.id); //Removes the previous tiny mce editor instance if any.
        tinymce.init({
            target: inputElement,
            skin: 'kms',
            menubar: false,
            statusbar: false,
            plugins: ['code', 'paste', 'link'],
            toolbar: 'undo redo | styleselect | bold italic underline | bullist numlist  | indent | link |  alignleft aligncenter alignright  | code',
            rel_list: [
                {title: 'None', value: 'none'},
                {title: 'No opener', value: 'noopener'},
                {title: 'No referrer', value: 'noreferrer'},
                {title: 'No follow', value: 'nofollow'}
            ],
            height: '200',
            paste_as_text: true,
            style_formats: [{title: 'Titel 1', block: 'h1'}, {title: 'Titel 2', block: 'h2'}, {title: 'Titel 3', block: 'h3'}, {title: 'Titel 4', block: 'h4'}, {title: 'Titel 5', block: 'h5'},  {title: 'Titel 6', block: 'h6'}, {title: 'Subheading 1', block: 'h5', classes: 'is-sub'}, {title: 'Subheading 2', block: 'h6', classes: 'is-sub'}, {title: 'Subheading 3', block: 'h6', classes: 'is-alternative-sub'}, {title: 'UL Checklist', selector: 'ul', classes: 's-checklist'}, {title: 'Intro', block: 'p', classes: 'is-intro'},],
            convert_urls: false,
            setup: function(editor) {
                editor.on('change', function(changeEvent) {
                    updateOriginalInput(editor, inputElement);
                });
            }
        });

        function updateOriginalInput(tinyMceEditor, inputElement) {
            tinyMceEditor.save();
            let changeEvent = createNewEvent('change');
            dispatchEventForElement(inputElement, changeEvent);
        }
    }, false);

    //Make sure all tiny mce editors are initialized
    entityInitializer.bindSelectorToCallback('.tiny-mce-on-click', function (attributesInitializer, inputElement) {
        if(!inputElement.id) inputElement.id = (new Date().getTime())+Math.random().toString(36).substring(7); //Gives the element a random id if it does not have any. Makes it selectable by tinyMce's remove method.



        inputElement.addEventListener('click', function () {

            // Remove the overlay
            let parent = inputElement.parentNode.parentNode;
            parent.querySelector('.js-tinymce-overlay').remove();

            tinymce.remove('#' + inputElement.id); //Removes the previous tiny mce editor instance if any.
            // console.log('TinyMCE init!');
            tinymce.init({
                target: inputElement,
                skin: 'kms',
                menubar: false,
                statusbar: false,
                plugins: ['code', 'paste', 'link'],
                toolbar: 'undo redo | styleselect | bold italic underline | bullist numlist  | indent | link |  alignleft aligncenter alignright  | code',
                rel_list: [
                    {title: 'None', value: 'none'},
                    {title: 'No opener', value: 'noopener'},
                    {title: 'No referrer', value: 'noreferrer'},
                    {title: 'No follow', value: 'nofollow'}
                ],
                height: '200',
                paste_as_text: true,
                style_formats: [{title: 'Titel 1', block: 'h1'}, {title: 'Titel 2', block: 'h2'}, {title: 'Titel 3', block: 'h3'}, {title: 'Titel 4', block: 'h4'}, {title: 'Titel 5', block: 'h5'},  {title: 'Titel 6', block: 'h6'}, {title: 'Subheading 1', block: 'h5', classes: 'is-sub'}, {title: 'Subheading 2', block: 'h6', classes: 'is-sub'}, {title: 'Subheading 3', block: 'h6', classes: 'is-alternative-sub'}, {title: 'UL Checklist', selector: 'ul', classes: 's-checklist'}, {title: 'Intro', block: 'p', classes: 'is-intro'}],
                convert_urls: false,
                setup: function (editor) {
                    editor.on('change', function (changeEvent) {
                        updateOriginalInput(editor, inputElement);
                    });
                }
            });

            function updateOriginalInput(tinyMceEditor, inputElement) {
                tinyMceEditor.save();
                let changeEvent = createNewEvent('change');
                dispatchEventForElement(inputElement, changeEvent);
            }
        });
    }, false);

    //Start looking for changes in #entity-form. And if one occurs, check if it did include one of the bound selector.
    entityInitializer.startObserving();

    new PreventNavigationController(document.querySelector('.entity-attributes'));
});

function checkIfResourceShouldBeFresh() {

    const freshnessFields = document.querySelectorAll('[id^="TextField-last_modified-"]');
    const form = document.getElementById('entity-form');
    const freshnessRoute = form.getAttribute('data-freshness');

    if(freshnessFields.length === 0 || !isset(freshnessRoute)) return false;



}

function shouldUseNormalSubmit() {

    const freshnessFields = document.querySelectorAll('[id^="TextField-last_modified-"]');
    const form = document.getElementById('entity-form');
    const freshnessRoute = form.getAttribute('data-freshness');

    if(freshnessFields.length === 0 || !isset(freshnessRoute)) return true;

    submitIfFresh(freshnessFields, freshnessRoute);

}

function submitIfFresh(freshnessFields, freshnessRoute) {

    // Prepare fields
    let fields = {};
    for(let i =0; i < freshnessFields.length; i++) {

        const freshnessField = freshnessFields[i];
        fields[freshnessField.getAttribute('id')] = freshnessField.getAttribute('value');
    }

    try {

        Ajax.post(freshnessRoute, fields, function (HttpRequest) {

            const status = HttpRequest.status;

            //Success
            if(status === 200){

                const componentInputs = document.querySelectorAll('.js-components input[type="text"], .js-components input[type="checkbox"], .js-components select, .js-components textarea');
                const componentInputsLength = componentInputs.length;
                for(let c = 0; c < componentInputsLength; c++) {
                    componentInputs[c].disabled = true;
                }

                let realSaveButton = document.querySelector('input[value="submit-cloaked"]');
                realSaveButton.click();
            }

            // Show conflicted error
            if(status === 409){

                let html = '<div class="modal">' +
                    '<div class="header"><h4>Conflict found</h4></div>' +
                    '<div class="body">' +
                    '<p class="message  message--large">We have found a conflict when compare the last modified timestamp. A newer version of this resource has been found. Please recreate your edits in a new tab or refresh the browser and do it again.</p>' +
                    '<div class="buttons">' +
                        '<button class="cancel">I understand</button>' +
                    '</div>' +
                    '</div>' +
                    '</div>' +
                    '</div>' +
                    '<div class="shader"></div>';

                let promptElement = document.createElement("div");
                promptElement.setAttribute('id', 'confirmBox');
                promptElement.innerHTML = html;
                promptElement.classList.add('show');
                document.body.appendChild(promptElement);

                let cancelButton = promptElement.querySelector('button.cancel');
                let shader = promptElement.querySelector('div.shader');

                cancelButton.addEventListener('click', function() { promptElement.remove(); });
                shader.addEventListener('click', function() { promptElement.remove(); }); 

                console.log('Freshness: test failed');
            }

            // Show unknown error
            if(status !== 200 && status !== 409) {
                console.log('Freshness: Test unknown error');
            }
        });

    }
    catch (e) {
        console.log(e);
    }
}