first commit

This commit is contained in:
CHIEFSOFT\ameye
2023-11-30 13:20:54 -05:00
commit e9e5c0546c
5833 changed files with 1801865 additions and 0 deletions
@@ -0,0 +1,86 @@
/**
* WordPress dependencies
*/
const {
__,
} = wp.i18n;
const {
Component,
Fragment,
} = wp.element;
const {
TextControl,
Notice,
} = wp.components;
/**
* Component
*/
export default class ComponentDimensionControl extends Component {
constructor() {
super(...arguments);
this.isValidValue = this.isValidValue.bind(this);
}
/**
* Check if value valid.
*
* @param {Mixed} value value to check.
* @returns {Boolean}
*/
isValidValue(value) {
const validUnits = ['fr', 'rem', 'em', 'ex', '%', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ch', 'vh', 'vw', 'vmin', 'vmax'];
// Whitelist values.
if (!value || '' === value || 0 === value || '0' === value || 'auto' === value || 'inherit' === value || 'initial' === value) {
return true;
}
// Skip checking if calc().
if (0 <= value.indexOf('calc(') && 0 <= value.indexOf(')')) {
return true;
}
// Get the numeric value.
const numericValue = parseFloat(value);
// Get the unit
const unit = value.replace(numericValue, '');
// Allow unitless.
if (!unit) {
return true;
}
// Check the validity of the numeric value and units.
return (!isNaN(numericValue) && -1 !== validUnits.indexOf(unit));
}
render() {
const {
value,
label,
help,
onChange,
} = this.props;
return (
<Fragment>
<TextControl
label={label}
help={help}
value={value}
onChange={onChange}
/>
{ !this.isValidValue(value) ? (
<Notice status="warning" isDismissible={false}>
{ __('Invalid dimension value.')}
</Notice>
) : ''}
</Fragment>
);
}
}
@@ -0,0 +1,127 @@
const { __ } = wp.i18n;
const {
Component,
} = wp.element;
const {
BaseControl,
DropZone,
Button,
} = wp.components;
const {
MediaPlaceholder,
MediaUpload,
mediaUpload,
} = wp.editor;
/**
* Component
*/
export default class ComponentGalleryControl extends Component {
constructor() {
super(...arguments);
}
render() {
const ALLOWED_MEDIA_TYPES = [ 'image' ];
const {
val,
label,
help,
onChange,
} = this.props;
return (
<BaseControl
label={ label || false }
help={ help || false }
>
{ ! val || ! val.length ? (
<MediaPlaceholder
icon="format-gallery"
labels={ {
title: label,
name: __( 'images' ),
} }
onSelect={ ( images ) => {
const result = images.map( ( image ) => {
return image.id;
} );
onChange( result );
} }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
disableMaxUploadErrorMessages
multiple
onError={ ( e ) => {
// eslint-disable-next-line no-console
console.log( e );
} }
/>
) : '' }
{ val && val.length ? (
<MediaUpload
onSelect={ ( images ) => {
const result = images.map( ( image ) => {
return image.id;
} );
onChange( result );
} }
allowedTypes={ ALLOWED_MEDIA_TYPES }
multiple
gallery
value={ val }
render={ ( { open } ) => (
<div
className="sight-gutenberg-component-gallery"
onClick={ open }
role="presentation"
>
<DropZone
onFilesDrop={ ( files ) => {
const currentImages = val || [];
mediaUpload( {
allowedTypes: ALLOWED_MEDIA_TYPES,
filesList: files,
onFileChange: ( images ) => {
const result = images.map( ( image ) => {
return image.id;
} );
onChange( currentImages.concat( result ) );
},
onError( e ) {
// eslint-disable-next-line no-console
console.log( e );
},
} );
} }
/>
{ val ? (
<div className="sight-gutenberg-component-gallery-list">
{val.map(imageId => {
return (
<img src={ sightBlockConfig.ajax_url + '?action=sight_render_thumbnail&image_id=' + imageId } />
)
})}
</div>
) : '' }
<div className="sight-gutenberg-component-gallery-button">
<Button isDefault={ true }>{ __( 'Edit Gallery' ) }</Button>
</div>
</div>
) }
/>
) : '' }
</BaseControl>
);
}
}
@@ -0,0 +1,87 @@
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* Internal dependencies
*/
import './style.scss';
/**
* WordPress dependencies
*/
const {
Component,
RawHTML,
} = wp.element;
const {
Button,
Popover,
} = wp.components;
/**
* Component
*/
export default class ComponentImageSelector extends Component {
constructor() {
super(...arguments);
}
render() {
let {
className,
value,
} = this.props;
const {
items,
onChange,
} = this.props;
className = classnames(
'sight-component-image-selector',
className
);
const layouts = Object.keys(items).map((key) => {
return {
content: <RawHTML>{items[key].icon}</RawHTML>,
value: key,
label: items[key].name,
};
});
return (
<div className={className}>
{ layouts && layouts.length ? (
layouts.map((itemData, i) => {
const itemClassName = classnames(
'sight-component-image-selector-item',
{
'sight-component-image-selector-item-active': value === itemData.value,
}
);
return (
<div
key={`sight-component-image-selector-item-${itemData.value}`}
className={itemClassName}
>
<Button
onClick={() => {
onChange(itemData.value);
}}
>
{itemData.content}
</Button>
<span>{itemData.label}</span>
</div>
);
})
) : null }
</div>
);
}
}
@@ -0,0 +1,185 @@
/**
* External dependencies
*/
import ReactSelect from 'react-select';
import { debounce } from 'throttle-debounce';
/**
* WordPress dependencies
*/
const {
Component,
} = wp.element;
const {
withSelect,
} = wp.data;
const {
BaseControl,
} = wp.components;
const cachedPosts = {};
function maybeCache( postType, newPosts ) {
if ( ! newPosts || ! newPosts.length ) {
return;
}
if ( ! cachedPosts[ postType ] ) {
cachedPosts[ postType ] = {};
}
newPosts.forEach( ( postData ) => {
if ( ! cachedPosts[ postType ][ postData.id ] ) {
cachedPosts[ postType ][ postData.id ] = postData;
}
} );
}
/**
* Component
*/
class ComponentPostsSelectorControl extends Component {
constructor() {
super( ...arguments );
this.state = {
searchTerm: '',
};
this.updateSearchTerm = debounce( 300, this.updateSearchTerm.bind( this ) );
}
/**
* Update search term with debounce.
*
* @param {String} search - search term.
*/
updateSearchTerm( search ) {
this.setState( {
searchTerm: search,
} );
}
render() {
const {
value,
label,
help,
isMulti,
onChange,
allPosts,
findPosts,
} = this.props;
const {
searchTerm,
} = this.state;
const foundPosts = findPosts( searchTerm ) || [];
return (
<BaseControl
label={ label }
help={ help }
>
<ReactSelect
options={
foundPosts.map( ( postData ) => {
return {
value: postData.id,
label: postData.title.raw,
};
} )
}
value={ ( () => {
let result = value ? value.split(',') : [];
if ( result && result.length ) {
result = result.map( ( id ) => {
let thisData = {
value: id,
label: id,
};
// get label from categories list
if ( allPosts[ id ] ) {
thisData.label = allPosts[ id ].title.raw;
}
return thisData;
} );
return result;
}
return [];
} )() }
isMulti={ isMulti }
name="filter-by-categories"
className="basic-multi-select"
classNamePrefix="select"
components={ {
IndicatorSeparator: () => null,
ClearIndicator: () => null,
} }
onInputChange={ ( val ) => {
this.updateSearchTerm( val );
} }
onChange={ ( val ) => {
let result = '';
let slug = '';
if ( val ) {
val.forEach( ( catData ) => {
result += slug + catData.value;
slug = ',';
} );
}
onChange( result );
} }
/>
</BaseControl>
);
}
}
export default withSelect( ( select, props, a, b, c ) => {
const {
getEntityRecords,
} = select( 'core' );
const {
value,
postType = 'post',
} = props;
let ids = value ? value.split(',') : [];
// find non-cached posts and try to retrieve.
ids = ids.filter( ( id ) => {
return ! cachedPosts[ postType ] || ! cachedPosts[ postType ][ id ];
} );
if ( ids && ids.length ) {
const newPosts = getEntityRecords( 'postType', postType, {
include: ids,
per_page: 100,
} );
maybeCache( postType, newPosts );
}
return {
findPosts( search = '' ) {
const searchPosts = getEntityRecords( 'postType', postType, {
search,
per_page: 20,
} );
maybeCache( postType, searchPosts );
return searchPosts;
},
allPosts: cachedPosts[ postType ] || {},
};
})( ComponentPostsSelectorControl );
@@ -0,0 +1,77 @@
import ReactSelect from 'react-select';
const { __ } = wp.i18n;
const {
Component,
} = wp.element;
const {
BaseControl,
} = wp.components;
/**
* Component
*/
export default class ReactSelectControl extends Component {
constructor() {
super(...arguments);
}
render() {
const {
val,
label,
isMulti,
onChange,
options,
} = this.props;
return (
<BaseControl
label={ label || false }
>
<ReactSelect
label={ label }
isMulti={ isMulti }
options={ options }
value={ ( () => {
var list = val;
if ( ! Array.isArray( val ) ) {
list = [];
}
const result = list.map( ( val ) => {
const el = options.find(function(el){
if ( val === el['value'] ) {
return true;
}
})
if ( el ) {
return {
value: val,
label: el['label'],
};
}
} );
return result;
} )() }
onChange={ ( val ) => {
if ( val ) {
const result = val.map( ( opt ) => {
return opt.value;
} );
onChange( result );
} else {
onChange( [] );
}
} }
/>
</BaseControl>
);
}
}
@@ -0,0 +1,46 @@
/**
* WordPress dependencies
*/
const { useMemo } = wp.element;
const { withSelect } = wp.data;
/**
* Internal dependencies
*/
import ServerSideRender from './server-side-render';
/**
* Constants
*/
const EMPTY_OBJECT = {};
export default withSelect(
( select ) => {
const coreEditorSelect = select( 'core/editor' );
if ( coreEditorSelect ) {
const currentPostId = coreEditorSelect.getCurrentPostId();
if ( currentPostId ) {
return {
currentPostId,
};
}
}
return EMPTY_OBJECT;
}
)(
( { urlQueryArgs = EMPTY_OBJECT, currentPostId, ...props } ) => {
const newUrlQueryArgs = useMemo( () => {
if ( ! currentPostId ) {
return urlQueryArgs;
}
return {
post_id: currentPostId,
...urlQueryArgs,
};
}, [ currentPostId, urlQueryArgs ] );
return (
<ServerSideRender urlQueryArgs={ newUrlQueryArgs } { ...props } />
);
}
);
@@ -0,0 +1,210 @@
/*
* This is a copy of Gutenberg component https://github.com/WordPress/gutenberg/blob/master/packages/server-side-render/src/server-side-render.js
* With the changes in our component:
* - callbacks before and after new content render
* - slightly different rendering process - don't remove previously rendered content. So, we will not see page jumps after every attribute change.
*/
/**
* External dependencies
*/
import classnames from 'classnames';
const { isEqual, debounce } = window.lodash;
/**
* Internal dependencies
*/
import './style.scss';
/**
* WordPress dependencies
*/
const {
Component,
RawHTML,
} = wp.element;
const { __, sprintf } = wp.i18n;
const apiFetch = wp.apiFetch;
const { addQueryArgs } = wp.url;
const {
Placeholder,
Spinner,
} = wp.components;
const {
doAction,
} = wp.hooks;
export function rendererPath( block, attributes = null, urlQueryArgs = {} ) {
return addQueryArgs( `/wp/v2/sight-renderer/${ block }`, {
context: 'edit',
...( null !== attributes ? { attributes } : {} ),
...urlQueryArgs,
} );
}
export class ServerSideRender extends Component {
constructor( props ) {
super( props );
this.state = {
response: null,
prevResponse: null,
};
}
componentDidMount() {
this.isStillMounted = true;
this.fetch( this.props );
// Only debounce once the initial fetch occurs to ensure that the first
// renders show data as soon as possible.
this.fetch = debounce( this.fetch, 500 );
}
componentWillUnmount() {
this.isStillMounted = false;
}
componentDidUpdate( prevProps ) {
const prevAttributes = prevProps.attributes;
const curAttributes = this.props.attributes;
if ( ! isEqual( prevAttributes, curAttributes ) ) {
this.fetch( this.props );
}
}
fetch( props ) {
if ( ! this.isStillMounted ) {
return;
}
const {
block,
attributes = null,
urlQueryArgs = {},
onBeforeChange = () => {},
onChange = () => {},
} = props;
if ( null !== this.state.response ) {
this.setState( {
response: null,
prevResponse: this.state.response,
} );
}
const path = rendererPath( block );
// Store the latest fetch request so that when we process it, we can
// check if it is the current request, to avoid race conditions on slow networks.
const fetchRequest = this.currentFetchRequest = apiFetch( { method: 'POST', path, data: { attributes: attributes } } )
.then( ( response ) => {
if ( this.isStillMounted && fetchRequest === this.currentFetchRequest && response ) {
onBeforeChange();
doAction( 'sight.components.serverSideRender.onBeforeChange', this.props );
this.setState( {
response: response.rendered,
prevResponse: null,
}, () => {
onChange();
doAction( 'sight.components.serverSideRender.onChange', this.props );
} );
}
} )
.catch( ( error ) => {
if ( this.isStillMounted && fetchRequest === this.currentFetchRequest ) {
onBeforeChange();
doAction( 'sight.components.serverSideRender.onBeforeChange', this.props );
this.setState( {
response: {
error: true,
errorMsg: error.message,
},
prevResponse: null,
}, () => {
onChange();
doAction( 'sight.components.serverSideRender.onChange', this.props );
} );
}
} );
return fetchRequest;
}
render() {
const {
response,
prevResponse,
} = this.state;
let { className } = this.props;
className = classnames(
className,
'sight-component-server-side-render'
);
if ( response === '' ) {
return (
<Placeholder
className={ className }
>
{ __( 'Block rendered as empty.' ) }
</Placeholder>
);
} else if ( ! response && prevResponse ) {
className = classnames(
className,
'sight-component-server-side-render-loading'
);
return (
<div className={ className }>
<Spinner />
<RawHTML
key="html"
className="sight-component-server-side-render-content"
>
{ prevResponse }
</RawHTML>
</div>
);
} else if ( ! response ) {
return (
<Placeholder
className={ className }
>
<Spinner />
</Placeholder>
);
} else if ( response.error ) {
// translators: %s: error message describing the problem
const errorMessage = sprintf( __( 'Error loading block: %s' ), response.errorMsg );
return (
<Placeholder
className={ className }
>
{ errorMessage }
</Placeholder>
);
}
return (
<div className={ className }>
<RawHTML
key="html"
className="sight-component-server-side-render-content"
>
{ response }
</RawHTML>
</div>
);
}
}
export default ServerSideRender;