/**
* Copyright 2019-2023 Nicolas Jonas
* License: GPL 3.0
*
* Based on: https://gist.github.com/pento/cf38fd73ce0f13fcf0f0ae7d6c4b685d
* Copyright 2019 Gary Pendergast
* License: GPL 2.0+
*/
import json from './block.json';
import './editor.scss';
import { __ } from '@wordpress/i18n';
import ServerSideRender from '@wordpress/server-side-render';
import {
MediaUpload,
MediaUploadCheck,
InspectorControls,
useBlockProps,
} from '@wordpress/block-editor';
import {
BaseControl,
TextControl,
Button,
ToggleControl,
SelectControl,
PanelBody,
ResponsiveWrapper,
DropZone,
} from '@wordpress/components';
import { registerBlockType } from '@wordpress/blocks';
import classnames from 'classnames';
export {};
declare global {
interface Window {
ArveBlockJsBefore: inlineScriptJSON;
Sanitizer?: any;
}
}
interface inlineScriptJSON {
settings: Record< string, OptionProps >;
options: Record< string, boolean | number | string >;
}
interface sectionControls {
main: Array< JSX.Element >;
pro: Array< JSX.Element >;
html5: Array< JSX.Element >;
'sticky-videos': Array< JSX.Element >;
'random-video': Array< JSX.Element >;
}
interface SelectOption {
label: string;
value: string;
disabled?: boolean;
}
interface OptionProps {
label: string;
tag: string;
type: string;
description?: string;
descriptionlink?: string;
descriptionlinktext?: string;
placeholder?: string;
options?;
}
const { name } = json;
const { settings, options } = window.ArveBlockJsBefore;
delete settings.align.options.center;
const domParser = new DOMParser();
/*
* Keypair to gutenberg component
*/
function PrepareSelectOptions( selectOptions: OptionProps ) {
const gboptions = [] as Array< SelectOption >;
Object.entries( selectOptions ).forEach( ( [ key, value ] ) => {
const o: SelectOption = {
label: value,
value: key,
};
gboptions.push( o );
} );
return gboptions;
}
function maybeSetAspectRatio( key: string, value: string, props ) {
if ( 'url' === key ) {
const iframe = domParser.parseFromString( value, 'text/html' ).querySelector( 'iframe' );
if ( iframe && iframe.getAttribute( 'src' ) ) {
value = iframe.src;
const w = iframe.width;
const h = iframe.height;
if ( w && h ) {
props.setAttributes( {
aspect_ratio: aspectRatio( w, h ),
} );
}
}
}
}
const mediaUploadRender = ( open: VoidFunction, val, url ) => {
return (
// @ts-ignore
{ /* @ts-ignore */ }
{ /* @ts-ignore */ }
);
};
function buildControls( props ) {
const controls = [] as Array< JSX.Element >;
const sectionControls = {} as sectionControls;
const mediaUploadInstructions = (
{ __( 'To edit the featured image, you need permission to upload media.' ) }
);
let selectedMedia;
Object.values( settings ).forEach( ( option: OptionProps ) => {
sectionControls[ option.tag ] = [];
} );
Object.entries( settings ).forEach( ( [ key, option ]: [ string, OptionProps ] ) => {
const val = props.attributes[ key ];
const url = '';
sectionControls[ option.tag ].push(
<>
{ 'boolean' === option.type && (
// @ts-ignore
{
return props.setAttributes( {
[ key ]: value,
} );
} }
/>
) }
{ 'select' === option.type && (
{
return props.setAttributes( {
[ key ]: value,
} );
} }
/>
) }
{ 'string' === option.type && (
// @ts-ignore
{
maybeSetAspectRatio( key, value, props );
return props.setAttributes( {
[ key ]: value,
} );
} }
/>
) }
{ 'attachment' === option.type && (
// @ts-ignore
{ /* @ts-ignore */ }
{ /* @ts-ignore */ }
{
selectedMedia = media;
return props.setAttributes( {
[ key ]: media.id.toString(),
[ key + '_url' ]: media.url,
} );
} }
allowedTypes={ [ 'image' ] }
modalClass="editor-post-featured-image__media-modal"
// @ts-ignore
render={ ( { open } ) => {
return mediaUploadRender( open, val, url );
} }
value={ val }
/>
{ !! val && !! url && (
// @ts-ignore
{ /* @ts-ignore */ }
{
selectedMedia = media;
return props.setAttributes( {
[ key ]: media.id.toString(),
[ key + '_url' ]: media.url,
} );
} }
allowedTypes={ [ 'image' ] }
modalClass="editor-post-featured-image__media-modal"
render={ ( { open } ) => (
// @ts-ignore
) }
/>
) }
{ !! val && (
// @ts-ignore
{ /* @ts-ignore */ }
) }
) }
>
);
} );
let open = true;
sectionControls.main.push(
{ /* @ts-ignore */ }
{ __( 'Info', 'advanced-responsive-video-embedder' ) }
);
Object.keys( sectionControls ).forEach( ( key ) => {
controls.push(
// @ts-ignore
{ sectionControls[ key ] }
);
open = false;
} );
return controls;
}
function createHelp( option: OptionProps ) {
if ( typeof option.description !== 'string' ) {
return '';
}
if ( typeof option.descriptionlinktext === 'string' ) {
const textSplit = option.description.split( option.descriptionlinktext );
return (
<>
{ textSplit[ 0 ] }
{ option.descriptionlinktext }
{ textSplit[ 1 ] }
>
);
}
return option.description;
}
function capitalizeFirstLetter( string ) {
return string.charAt( 0 ).toUpperCase() + string.slice( 1 );
}
function Edit( props ) {
const {
attributes: { mode, align, maxwidth },
} = props;
let pointerEvents = true;
const style = {} as React.CSSProperties;
const attrCopy = JSON.parse( JSON.stringify( props.attributes ) );
delete attrCopy.align;
delete attrCopy.maxwidth;
if ( maxwidth && ( 'left' === align || 'right' === align ) ) {
style.width = '100%';
style.maxWidth = maxwidth;
} else if ( 'left' === align || 'right' === align ) {
style.width = '100%';
style.maxWidth = options.align_maxwidth as string | number;
}
const blockProps = useBlockProps( { style } );
if ( 'normal' === mode || ( ! mode && 'normal' === options.mode ) ) {
pointerEvents = false;
}
return (
<>
{ /* @ts-ignore */ }
{ /* @ts-ignore */ }
{ /* @ts-ignore */ }
{ buildControls( props ) }
>
);
}
// @ts-ignore
registerBlockType( name, {
edit: Edit,
} );
function aspectRatio( w, h ) {
const arGCD = gcd( w, h );
return w / arGCD + ':' + h / arGCD;
}
function gcd( a, b ) {
if ( ! b ) {
return a;
}
return gcd( b, a % b );
}
/*
wp.data.dispatch( 'core/edit-post' ).hideBlockTypes( [
'core-embed/youtube',
'core-embed/vimeo',
'core-embed/dailymotion',
'core-embed/collegehumor',
'core-embed/ted',
] );
*/
/*
TODO when the sanitizer API
function sanitizeHelpHTML( option: OptionProps ) {
if ( typeof option.description !== 'string' ) {
return '';
}
const div = document.createElement( 'div' );
if ( 'Sanitizer' in window ) {
const sanitizer = new window.Sanitizer( {
allowElements: [ 'a' ],
allowAttributes: {
target: [ 'a' ],
href: [ 'a' ],
},
} );
// @ts-ignore
div.setHTML( option.description, { sanitizer } );
return ;
}
return stripHTML( option.description );
}
function stripHTML( html ) {
const doc = new DOMParser().parseFromString( html, 'text/html' );
return doc.body.textContent || '';
}
*/