Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

jsarnowski / jsarnowski/oxygen-gutenberg   php

Repository URL to install this package:

/ oxygen-gutenberg.js

const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const el = wp.element.createElement;

let getOxygenbergData = function( blockContent ) {

    let s = decodeURIComponent( escape( window.atob( blockContent ) ) );
    let regex = /<oxygenberg(.|\n)*?>/g;
    let m;
    let oxygenbergTags = [];

    while( ( m = regex.exec( s ) ) !== null ) {

        // This is necessary to avoid infinite loops with zero-width matches
        if ( m.index === regex.lastIndex ) regex.lastIndex++;
        oxygenbergTags.push(m[0]);
    }

    let attributes = {};
    for( let i =0; i<oxygenbergTags.length; i++ ){

        let attRegex = /(\S+)=["']([^\s]*?)["']/g;
        let match;
        let att = {};
        let attId = '';

        while( ( match = attRegex.exec( oxygenbergTags[ i ] ) ) !== null ) {

            att[ match[1] ] = decodeURIComponent( escape( window.atob( match[2] ) ) );
            if( match[1] == "id" ) attId = att[ 'id' ];
        }

        att["full_tag"] = oxygenbergTags[ i ];
        attributes[attId] = att;
    }

    return attributes;
};

function get_attribute_alt_key(attribute, type) {
    var alt_key = attribute.substring(0, attribute.length - type.length) + 'alt';
    return alt_key;
}

window.oxygenbergEventHandlers = {};

function registerOxygenBlock( blockContent, blockName, blockTitle, isFullPageBlock ){

    let attributes = getOxygenbergData( blockContent );
    attributes['align'] = {type: 'string', default: 'full'};

    registerBlockType( 'oxygen-vsb/' + blockName , {

        title: blockTitle,
        icon: 'paperclip',
        category: isFullPageBlock ? 'oxygen-vsb-full-page-blocks' : 'oxygen-vsb-blocks',
        supports: {
            align: ['full']
        },
        attributes: attributes,

        edit(props) {

            // Force full width alignment
            if( 'full' != props.attributes.align ){ props.setAttributes({ align: 'full' }); }
            // Hide the align-full toolbar button (doesn't work good)
            //if( jQuery('svg.dashicons-align-full-width').parent().hasClass('components-toolbar__control')) jQuery('svg.dashicons-align-full-width').parent().css('display', 'none');

            if( typeof window.oxygenMouseTip === 'undefined' ) window.oxygenMouseTip = new MouseTip();

            let blockHtml = decodeURIComponent( escape( window.atob( blockContent ) ) );

            let inspectorControls = [];

            if(window.oxygen_vsb_current_user_can_access) {
                if( !( window.ctBuilderFullPageBlock && window.ctBuilderFullPageBlockName == blockName.substring(5) ) ) inspectorControls.push(el(wp.element.RawHTML, {},
                    '<a class="components-button is-primery is-button" href="' + oxyBuilderUrl + '&oxy_user_library=' + blockName.substring(5) + '" target="_blank" class="oxy-edit-in-oxygen" data-block="' + blockName.substring(5) + '">Edit ' + blockTitle + ' in Oxygen</a><hr>'
                ));
            }

            for (let key in attributes) {
                if(key == 'align') continue;

                var focusFn = function(){
                    var targetElement = jQuery("#"+key.substring(0, key.length-attributes[key]['type'].length-1)+".oxygenberg-"+props.clientId);
                    targetElement.stop().finish();
                    targetElement.animate({"opacity": 0.2},400).animate({"opacity": 1},400);

                };
                var mouseOverFn = function(){
                    var targetElement = jQuery("#"+key.substring(0, key.length-attributes[key]['type'].length-1)+".oxygenberg-"+props.clientId);
                    targetElement.css({
                        "outline": "4px solid #21759b"
                    });
                }
                var mouseOutFn = function(){
                    var targetElement = jQuery("#"+key.substring(0, key.length-attributes[key]['type'].length-1)+".oxygenberg-"+props.clientId);
                    targetElement.css({
                        "outline": "inherit"
                    });
                }

                // The purpose of oxygenbergEventHandlers is to keep track of the events to avoid setting them more
                // than one time even though the edit function is run a thousand times in the block lifetime
                if( typeof oxygenbergEventHandlers[ props.clientId ] === 'undefined' ) oxygenbergEventHandlers[ props.clientId ] = {};

                // Events should be attached only the first time the block is rendered
                if( typeof oxygenbergEventHandlers[ props.clientId ][ key ] === 'undefined' ) {
                    switch( attributes[key]['type'] ) {

                        case 'link':
                            var linkText = props.attributes[key.substring(0, key.length-4)+'string'];
                            if( typeof linkText === 'undefined') {
                                linkText = "Link Wrapper";
                            } else {
                                linkText = '"' + linkText + '"';
                            }
                            inspectorControls.push(
                                el(wp.components.TextControl, {label:'Url for ' + linkText + ':',value: props.attributes[key], onChange:function(newValue){
                                    var newAttr = {};
                                    newAttr[key] = newValue;
                                    props.setAttributes(newAttr);
                                    // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                    window.oxyBlocksEdited=true;
                                    wp.data.dispatch( 'core/editor' ).editPost( { meta: { _my_meta_data: 1 } });
                                },
                                className: 'sidebar-icon-box',
                                onFocus: focusFn,
                                onClick: focusFn,
                                onMouseOver: mouseOverFn,
                                onMouseOut: mouseOutFn,
                                readOnly: true
                                })
                            );
                            inspectorControls.push(
                                el(
                                    wp.components.Button,
                                    {
                                        isDefault: true,
                                        className: 'sidebar-icon-button',
                                        onFocus: focusFn,
                                        onMouseOver: mouseOverFn,
                                        onMouseOut: mouseOutFn,
                                        onClick: function(event){
                                            wpActiveEditor=true;
                                            jQuery('<textarea>')
                                                .attr('id', 'ct-link-dialog-txt')
                                                .css('display', 'none')
                                                .appendTo('body');

                                            wpLink.open('ct-link-dialog-txt');
                                            jQuery('#wp-link-url').val(props.attributes[key]);
                                            jQuery('#wp-link .link-target').hide();
                                            jQuery('#wp-link .wp-link-text-field').hide();
                                            var submitButton = document.getElementById('wp-link-submit');
                                            submitButton.addEventListener('click', function linkSelected(){
                                                submitButton.removeEventListener('click', linkSelected);
                                                var attrs = wpLink.getAttrs();
                                                var newAttr = {};
                                                newAttr[key] = attrs.href;
                                                props.setAttributes(newAttr);
                                                // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                                wpLink.close();
                                            });
                                        },
                                    },
                                    el(wp.element.RawHTML, {}, "Change URL...")
                                )
                            );
                            // No function is added to oxygengergEventHandlers here because inspectorControls must be created each time the block is rendered
                            break;

                        case 'icon':
                            inspectorControls.push(
                                el(wp.components.TextControl, {label:'Icon:',value: props.attributes[key], onChange:function(newValue){
                                    var newAttr = {};
                                    newAttr[key] = newValue;
                                    props.setAttributes(newAttr);
                                    // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                },
                                className: 'sidebar-icon-box',
                                onFocus: focusFn,
                                onClick: focusFn,
                                onMouseOver: mouseOverFn,
                                onMouseOut: mouseOutFn,
                                readOnly: true
                                })
                            );
                            inspectorControls.push(
                                el(
                                    wp.components.Button,
                                    {
                                        isDefault: true,
                                        className: 'sidebar-icon-button',
                                        onFocus: focusFn,
                                        onMouseOver: mouseOverFn,
                                        onMouseOut: mouseOutFn,
                                        onClick: function(event){
                                            showSvgBox(props.attributes[key]);
                                            var cancelButton = document.getElementById("svgBoxCancelBtn");
                                            var saveButton = document.getElementById("svgBoxSaveBtn");
                                            cancelButton.addEventListener("click", function cancelFunction(){
                                                cancelButton.removeEventListener("click", cancelFunction);
                                                hideSvgBox();
                                            });
                                            saveButton.addEventListener("click", function saveFunction(){
                                                saveButton.removeEventListener("click", saveFunction);
                                                hideSvgBox();
                                                var newAttr = {};
                                                newAttr[key] = jQuery(saveButton).data("icon");
                                                props.setAttributes(newAttr);
                                                // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                                window.oxyBlocksEdited=true;
                                                wp.data.dispatch( 'core/editor' ).editPost( { meta: { _my_meta_data: 1 } });
                                            });
                                        },
                                    },
                                    el(wp.element.RawHTML, {}, "Browse Icons...")
                                )
                            );
                            // No function is added to oxygengergEventHandlers here because inspectorControls must be created each time the block is rendered
                            break;

                        case 'string':
                            // Create the event handler specific for this attribute
                            oxygenbergEventHandlers[ props.clientId ][ key ] = function( event ) {
                                props.attributes[key] = jQuery( this ).html();
                                window.oxyBlocksEdited=true;
                                wp.data.dispatch( 'core/editor' ).editPost( { meta: { _my_meta_data: 1 } });
                                // Calling setAtributes makes the CONTENTEDITABLE element lose focus
                                //props.setAttributes(newAttr);
                            };
                            // Attach the event handler to the body element because the first time this function is called there is no blocks markup yet
                            jQuery( 'body' ).on( 'input', '#' + key.substring(0, key.length-7) + '.oxygenberg-' + props.clientId, oxygenbergEventHandlers[ props.clientId ][ key ]);
                            // Additional event because gutenberg requires calling setAttributes()
                            jQuery( 'body' ).on( 'focusout', '#' + key.substring(0, key.length-7) + '.oxygenberg-' + props.clientId, function(){
                                var newAttr = {};
                                newAttr[key] = jQuery( this ).html();
                                props.setAttributes(newAttr);
                                // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                // hack to reflect the changes immetiately on the sidebar
                                // wp.data.dispatch( 'core/editor' ).toggleBlockMode(props.clientId);
                                // wp.data.dispatch( 'core/editor' ).toggleBlockMode(props.clientId);
                                wp.data.dispatch( 'core/editor' ).updateBlock(props.clientId, newAttr);
                                window.oxyBlocksEdited=true;
                                // wp.data.dispatch( 'core/editor' ).editPost( { meta: { _my_meta_data: 1 } });
                            });
                            break;

                        case 'richtext':
                            oxygenbergEventHandlers[ props.clientId ][ key ] = function( event ) {
                                jQuery('body').append('<div id="oxygenVsbRichEditorBackdrop"><textarea id="oxygenVsbRichEditor"></textarea><div class="buttons_block"><div id="oxygenVsbRichEditor_save" class="button">Ok</div><div id="oxygenVsbRichEditor_cancel" class="button">Cancel</div></div></div>');
                                var originalTextEl = jQuery( event.target ).closest('.oxy-rich-text');
                                tinyMCE.init({
                                    target: document.getElementById('oxygenVsbRichEditor'),
                                    width : "50%",
                                    height: "300px",
                                    menubar: false,
                                    plugins: 'lists link',
                                    toolbar: 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent |  numlist bullist checklist | forecolor backcolor casechange permanentpen formatpainter removeformat | link',
                                    'media_buttons': false
                                }).then(function(editors) {
                                    tinyMCE.get("oxygenVsbRichEditor").setContent( originalTextEl.html() );
                                });
                                jQuery('#oxygenVsbRichEditor_save').click(function(){
                                    var newContent = tinyMCE.get("oxygenVsbRichEditor").getContent();
                                    //props.attributes[jQuery( originalTextEl ).attr('id')+'_'+attributes[key]['type']] = newContent;
                                    //props.setAttributes(props.attributes);
                                    var newAttr = {};
                                    newAttr[key] = newContent;
                                    props.setAttributes(newAttr);
                                    // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                    tinymce.remove('#oxygenVsbRichEditor');
                                    jQuery('#oxygenVsbRichEditorBackdrop').remove();
                                    originalTextEl.html(newContent);
                                    window.oxyBlocksEdited=true;
                                    wp.data.dispatch( 'core/editor' ).editPost( { meta: { _my_meta_data: 1 } });
                                });
                                jQuery('#oxygenVsbRichEditor_cancel').click(function(){
                                    tinymce.remove('#oxygenVsbRichEditor');
                                    jQuery('#oxygenVsbRichEditorBackdrop').remove();
                                });
                            };
                            jQuery( 'body' ).on( 'click', '#' + key.substring(0, key.length-9) + '.oxygenberg-' + props.clientId, oxygenbergEventHandlers[ props.clientId ][ key ]);
                            break;

                        case 'image':
                            oxygenbergEventHandlers[ props.clientId ][ key ] = function( event ) {
                                event.preventDefault();
                                event.stopPropagation();
                                var imageElement = this;
                                var file_frame = wp.media.frames.file_frame = wp.media({
                                    title: 'Select a replacement image',
                                    button: {
                                        text: 'Use this image',
                                    },
                                    multiple: false
                                });
                                file_frame.on( 'select', function() {
                                    var attachment = file_frame.state().get('selection').first().toJSON();
                                    
                                    var newAttr = {};
                                    newAttr[key] = attachment.url;
                                    
                                    jQuery( imageElement ).attr('src', attachment.url);
                                    jQuery( imageElement ).removeAttr('srcset');
                                    
                                    if (attachment.alt) {
                                        var alt_key = get_attribute_alt_key(key, 'image');
                                        if (alt_key && attributes.hasOwnProperty(alt_key)) {
                                            newAttr[alt_key] = attachment.alt;
                                        }
                                    }
                                    
                                    props.setAttributes(newAttr);
                                    
                                    window.oxyBlocksEdited=true;
                                    wp.data.dispatch( 'core/editor' ).editPost( { meta: { _my_meta_data: 1 } });
                                });
                                file_frame.open();
                            };
                            jQuery( 'body' ).on( 'click', '#' + key.substring(0, key.length-6) + '.oxygenberg-' + props.clientId, oxygenbergEventHandlers[ props.clientId ][ key ]);
                            break;
                        case 'background':
                            inspectorControls.push(
                                el(wp.components.TextControl, {label:'Background Image URL:',value: props.attributes[key], onChange:function(newValue){
                                        var newAttr = {};
                                        newAttr[key] = newValue;
                                        props.setAttributes(newAttr);
                                        // jQuery('#block-' + props.clientId + ' svg.dashicons-align-full-width').closest('button').trigger('click');
                                    },
                                    className: 'sidebar-icon-box',
                                    onFocus: focusFn,
                                    onClick: focusFn,
                                    onMouseOver: mouseOverFn,
                                    onMouseOut: mouseOutFn,
                                    readOnly: true
                                })
                            );
                            inspectorControls.push(
                                el(
                                    wp.components.Button,
                                    {
                                        isDefault: true,
                                        className: 'sidebar-icon-button',
Loading ...