corvée(dépendances) ajoute Carbon Fields
This commit is contained in:
parent
135cc65eed
commit
62368587e5
459 changed files with 72750 additions and 26 deletions
177
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/container/index.js
vendored
Normal file
177
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/container/index.js
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import cx from 'classnames';
|
||||
import { Component } from '@wordpress/element';
|
||||
import {
|
||||
map,
|
||||
find,
|
||||
kebabCase,
|
||||
isPlainObject
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { getFieldType } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
import Field from '../field';
|
||||
|
||||
class Container extends Component {
|
||||
/**
|
||||
* Local state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
state = {
|
||||
currentTab: null
|
||||
};
|
||||
|
||||
/**
|
||||
* Lifecycle hook.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
componentDidMount() {
|
||||
const { container } = this.props;
|
||||
|
||||
if ( this.isTabbed( container ) ) {
|
||||
this.setState( {
|
||||
currentTab: Object.keys( container.settings.tabs )[ 0 ]
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the container uses tabs.
|
||||
*
|
||||
* @param {Object} container
|
||||
* @return {boolean}
|
||||
*/
|
||||
isTabbed( container ) {
|
||||
return isPlainObject( container.settings.tabs );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given field.
|
||||
*
|
||||
* @param {Object} field
|
||||
* @return {Object}
|
||||
*/
|
||||
renderField = ( field ) => {
|
||||
const FieldEdit = getFieldType( field.type, 'metabox' );
|
||||
|
||||
if ( ! FieldEdit ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Field key={ field.id } id={ field.id }>
|
||||
<FieldEdit id={ field.id } containerId={ this.props.id } />
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles click on the tabs.
|
||||
*
|
||||
* @param {string} tab
|
||||
* @return {void}
|
||||
*/
|
||||
handleTabClick = ( tab ) => {
|
||||
this.setState( {
|
||||
currentTab: tab
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the component.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
render() {
|
||||
const { currentTab } = this.state;
|
||||
const { container } = this.props;
|
||||
|
||||
const hasTabs = this.isTabbed( container );
|
||||
|
||||
const classes = cx( [
|
||||
'cf-container',
|
||||
`cf-container-${ container.id }`,
|
||||
`cf-container-${ kebabCase( container.type ) }`,
|
||||
...container.classes,
|
||||
{
|
||||
'cf-container--plain': ! hasTabs,
|
||||
[ `cf-container--tabbed cf-container--${ container.layout }` ]: hasTabs
|
||||
}
|
||||
] );
|
||||
|
||||
return (
|
||||
<div className={ classes }>
|
||||
<input
|
||||
type="hidden"
|
||||
name={ container.nonce.name }
|
||||
value={ container.nonce.value }
|
||||
/>
|
||||
|
||||
{ hasTabs && (
|
||||
<div className={ `cf-container__tabs cf-container__tabs--${ container.layout }` }>
|
||||
<ul className="cf-container__tabs-list">
|
||||
{ map( container.settings.tabs, ( fieldNames, tabName ) => {
|
||||
// eslint-disable-next-line no-shadow
|
||||
const classes = cx(
|
||||
'cf-container__tabs-item',
|
||||
{
|
||||
'cf-container__tabs-item--current': tabName === currentTab
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<li
|
||||
key={ tabName }
|
||||
className={ classes }
|
||||
tabIndex={ -1 }
|
||||
role="tab"
|
||||
aria-selected={ currentTab === tabName }
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={ () => this.handleTabClick( tabName ) }
|
||||
dangerouslySetInnerHTML={ { __html: tabName } }
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
} ) }
|
||||
</ul>
|
||||
</div>
|
||||
) }
|
||||
|
||||
{ hasTabs && (
|
||||
map( container.settings.tabs, ( fieldNames, tabName ) => {
|
||||
return (
|
||||
<div className="cf-container__fields" key={ tabName } hidden={ tabName !== currentTab }>
|
||||
{ map( fieldNames, ( fieldName ) => {
|
||||
const field = find( container.fields, [ 'name', fieldName ] );
|
||||
|
||||
return this.renderField( field );
|
||||
} ) }
|
||||
</div>
|
||||
);
|
||||
} )
|
||||
) }
|
||||
|
||||
{ ! hasTabs && (
|
||||
<div className="cf-container__fields">
|
||||
{ map( container.fields, this.renderField ) }
|
||||
</div>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Container;
|
||||
146
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/container/style.scss
vendored
Normal file
146
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/container/style.scss
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/* ==========================================================================
|
||||
Container
|
||||
========================================================================== */
|
||||
|
||||
.carbon-box {
|
||||
&.hide-if-js:not([hidden]) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
#poststuff .carbon-box .inside,
|
||||
.carbon-box .inside {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cf-container {
|
||||
&--plain {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&--tabbed {
|
||||
display: flex;
|
||||
|
||||
&-horizontal {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-vertical {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cf-container__fields {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
margin: 0 -1px 0 0;
|
||||
background-color: $color-white;
|
||||
|
||||
&[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.block-editor & {
|
||||
border-left: 1px solid $wp-color-gray-light-500;
|
||||
}
|
||||
|
||||
.cf-container-term-meta &,
|
||||
.cf-container-user-meta & {
|
||||
border-width: 0 0 1px 1px;
|
||||
border-style: solid;
|
||||
border-color: $wp-color-gray-light-500;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-container__tabs {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background-color: $wp-color-gray-light-100;
|
||||
|
||||
&-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 0 -1px;
|
||||
|
||||
.cf-container__tabs-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid $wp-color-gray-light-500;
|
||||
margin: 0 ($size-base * 2) 0 0;
|
||||
background-color: $wp-color-gray-light-100;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: background-color $transition-base, border-color $transition-base;
|
||||
|
||||
button {
|
||||
background: 0;
|
||||
border: 0;
|
||||
padding: ($size-base * 2.5) ($size-base * 3);
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-white;
|
||||
}
|
||||
|
||||
&--current {
|
||||
background-color: $color-white;
|
||||
border-bottom-color: $color-white;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&--tabbed-horizontal {
|
||||
padding: ($size-base * 3) ($size-base * 3) 0;
|
||||
border-bottom: 1px solid $wp-color-gray-light-500;
|
||||
|
||||
.cf-container__tabs-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
&--tabbed-vertical {
|
||||
width: 300px;
|
||||
border-right: 1px solid $wp-color-gray-light-500;
|
||||
|
||||
.cf-container__tabs-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.cf-container__tabs-item {
|
||||
margin: 0;
|
||||
justify-content: flex-start;
|
||||
border: 0;
|
||||
border-top: 1px solid $gb-light-gray-500;
|
||||
border-bottom: 1px solid $gb-light-gray-500;
|
||||
|
||||
&:first-of-type {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
text-align: left;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-container__tabs-item + .cf-container__tabs-item {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/field/index.js
vendored
Normal file
20
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/field/index.js
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { compose } from '@wordpress/compose';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { Field, withFilters } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
import withField from '../../hocs/with-field';
|
||||
|
||||
export default compose(
|
||||
withField,
|
||||
withFilters( 'carbon-fields.field-wrapper.metabox' )
|
||||
)( Field );
|
||||
45
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/field/style.scss
vendored
Normal file
45
web/vendor/htmlburger/carbon-fields/packages/metaboxes/components/field/style.scss
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* ==========================================================================
|
||||
Field
|
||||
========================================================================== */
|
||||
|
||||
.cf-field {
|
||||
.cf-container & {
|
||||
flex: 1 1 100%;
|
||||
padding: $size-base * 3;
|
||||
border-width: 0 1px 0 0;
|
||||
border-style: solid;
|
||||
border-color: $wp-color-gray-light-500;
|
||||
}
|
||||
|
||||
.cf-container & + & {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-field__head {
|
||||
.term-php .cf-container__fields > .cf-field:not(.cf-field--has-width) > &,
|
||||
.cf-container-user-meta .cf-container__fields > .cf-field > & {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-field__label {
|
||||
.cf-container & {
|
||||
padding-bottom: 6.5px;
|
||||
font-weight: 600;
|
||||
color: $wp-color-dark-gray;
|
||||
}
|
||||
|
||||
.cf-container-term-meta &,
|
||||
.cf-container-user-meta & {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-field__help {
|
||||
display: inline-block;
|
||||
color: #666;
|
||||
margin-top: 10px;
|
||||
}
|
||||
25
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/hooks.js
vendored
Normal file
25
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/hooks.js
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { withFilters } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import withContainer from '../hocs/with-container';
|
||||
|
||||
/**
|
||||
* Extends the containers with necessary hooks.
|
||||
*/
|
||||
addFilter( 'carbon-fields.register-container-type', 'carbon-fields/metaboxes', ( type, context, component ) => {
|
||||
return compose(
|
||||
withContainer,
|
||||
withFilters( `carbon-fields.${ type }.${ context }` )
|
||||
)( component );
|
||||
} );
|
||||
81
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/index.js
vendored
Normal file
81
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/index.js
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { render, createRoot } from '@wordpress/element';
|
||||
import { select } from '@wordpress/data';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { forEach } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './hooks';
|
||||
import './widget';
|
||||
import './term-meta';
|
||||
import './theme-options';
|
||||
import './user-meta';
|
||||
import Container from '../components/container';
|
||||
import { getContainerType, registerContainerType } from './registry';
|
||||
import { registerContainerRoot } from './root-registry';
|
||||
|
||||
/**
|
||||
* Registers the containers.
|
||||
*/
|
||||
[
|
||||
'post_meta',
|
||||
'term_meta',
|
||||
'user_meta',
|
||||
'comment_meta',
|
||||
'network',
|
||||
'theme_options',
|
||||
'nav_menu_item',
|
||||
'widget'
|
||||
].forEach( ( type ) => registerContainerType( type, Container ) );
|
||||
|
||||
/**
|
||||
* Renders the given container.
|
||||
*
|
||||
* @param {Object} container
|
||||
* @param {string} context
|
||||
* @return {void}
|
||||
*/
|
||||
export function renderContainer( container, context ) {
|
||||
const node = document.querySelector( `.container-${ container.id }` );
|
||||
const Component = getContainerType( container.type, context );
|
||||
|
||||
if ( node ) {
|
||||
const NodeComponent = <Component id={ container.id } />;
|
||||
|
||||
if ( createRoot ) {
|
||||
const nodeRoot = createRoot( node );
|
||||
nodeRoot.render( NodeComponent );
|
||||
|
||||
registerContainerRoot( container.id, nodeRoot );
|
||||
} else {
|
||||
render(
|
||||
NodeComponent,
|
||||
node,
|
||||
() => {
|
||||
node.dataset.mounted = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error( sprintf( __( 'Could not find DOM element for container "%1$s".', 'carbon-fields-ui' ), container.id ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the containers.
|
||||
*
|
||||
* @param {string} context
|
||||
* @return {void}
|
||||
*/
|
||||
export default function initializeContainers( context ) {
|
||||
const containers = select( 'carbon-fields/metaboxes' ).getContainers();
|
||||
|
||||
forEach( containers, ( container ) => {
|
||||
renderContainer( container, context );
|
||||
} );
|
||||
}
|
||||
13
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/registry.js
vendored
Normal file
13
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/registry.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { createRegistry } from '@carbon-fields/core';
|
||||
|
||||
export const {
|
||||
registerContainerType,
|
||||
getContainerType
|
||||
} = createRegistry( 'container', [
|
||||
'classic',
|
||||
'gutenberg'
|
||||
] );
|
||||
|
||||
28
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/root-registry.js
vendored
Normal file
28
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/root-registry.js
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
const rootRegistry = {};
|
||||
|
||||
export function registerContainerRoot( containerId, root ) {
|
||||
rootRegistry[ containerId ] = {
|
||||
createdAt: Math.floor(Date.now() / 1000),
|
||||
...root,
|
||||
unmount() {
|
||||
// Fix issues with race condition by delaying
|
||||
// the onLoad unmounting of containers
|
||||
// they would be unmounted later
|
||||
|
||||
if ( parseFloat( window.cf.config.wp_version ) >= 6.2 ) {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
if ( currentTime - rootRegistry[ containerId ].createdAt >= 3 ) {
|
||||
root.unmount();
|
||||
delete rootRegistry[ containerId ];
|
||||
}
|
||||
} else {
|
||||
root.unmount();
|
||||
delete rootRegistry[ containerId ];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getContainerRoot( containerId ) {
|
||||
return rootRegistry[ containerId ] || null;
|
||||
}
|
||||
68
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/term-meta/index.js
vendored
Normal file
68
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/term-meta/index.js
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import _ from 'lodash';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { dispatch } from '@wordpress/data';
|
||||
import { withEffects } from 'refract-callbag';
|
||||
import { pipe, filter } from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import fromEventPattern from '../../utils/from-event-pattern';
|
||||
import { normalizePreloadedState } from '../../store/helpers';
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function aperture() {
|
||||
return pipe(
|
||||
fromEventPattern(
|
||||
( handler ) => window.jQuery( document ).on( 'ajaxSuccess', handler ),
|
||||
( handler ) => window.jQuery( document ).off( 'ajaxSuccess', handler ),
|
||||
( e, xhr, options, data ) => ( {
|
||||
options,
|
||||
data
|
||||
} )
|
||||
),
|
||||
filter( ( { options, data } ) => {
|
||||
return options.data
|
||||
&& options.data.indexOf( 'carbon_fields_container' ) > -1
|
||||
&& options.data.indexOf( 'add-tag' ) > -1
|
||||
&& ! data.documentElement.querySelector( 'wp_error' );
|
||||
} )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @return {Function}
|
||||
*/
|
||||
function handler( props ) {
|
||||
return function() {
|
||||
// Collects identifiers of current fields so we can remove them later.
|
||||
const oldFieldIds = _.map( props.container.fields, 'id' );
|
||||
|
||||
// Get a fresh copy of the container and fields.
|
||||
const { containers, fields } = normalizePreloadedState( _.get( window.cf, 'preloaded.containers', [] ) );
|
||||
const container = _.find( containers, [ 'id', props.id ] );
|
||||
const containerFields = _.filter( fields, [ 'container_id', props.id ] );
|
||||
|
||||
// Replace the container and add the new fields.
|
||||
const { updateState, removeFields } = dispatch( 'carbon-fields/metaboxes' );
|
||||
|
||||
updateState(
|
||||
_.keyBy( [ container ], 'id' ),
|
||||
_.keyBy( containerFields, 'id' )
|
||||
);
|
||||
|
||||
removeFields( oldFieldIds );
|
||||
};
|
||||
}
|
||||
|
||||
addFilter( 'carbon-fields.term_meta.classic', 'carbon-fields/metaboxes', withEffects( aperture, { handler } ) );
|
||||
52
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/theme-options/index.js
vendored
Normal file
52
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/theme-options/index.js
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { withEffects } from 'refract-callbag';
|
||||
import { map, pipe } from 'callbag-basics';
|
||||
import fromEvent from 'callbag-from-event';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function aperture() {
|
||||
return pipe(
|
||||
fromEvent( window, 'scroll' ),
|
||||
map( () => window.jQuery( window ).scrollTop() )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @return {Function}
|
||||
*/
|
||||
function handler() {
|
||||
return function( windowTopOffset ) {
|
||||
const $container = window.jQuery( '.carbon-box:first' );
|
||||
const $panel = window.jQuery( '#postbox-container-1' );
|
||||
const $bar = window.jQuery( '#wpadminbar' );
|
||||
|
||||
const offset = $bar.height() + 10;
|
||||
const threshold = $container.offset().top - offset;
|
||||
|
||||
// In some situations the threshold is negative number because
|
||||
// the container element isn't rendered yet.
|
||||
if ( threshold > 0 ) {
|
||||
$panel
|
||||
.toggleClass( 'fixed', windowTopOffset >= threshold )
|
||||
.css( 'top', offset );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addFilter( 'carbon-fields.theme_options.classic', 'carbon-fields/metaboxes', withEffects( aperture, { handler } ) );
|
||||
|
||||
10
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/theme-options/style.scss
vendored
Normal file
10
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/theme-options/style.scss
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* ==========================================================================
|
||||
Theme Options
|
||||
========================================================================== */
|
||||
|
||||
#postbox-container-1.fixed {
|
||||
.carbon-theme-options #post-body.columns-2 &,
|
||||
.carbon-network #post-body.columns-2 & {
|
||||
position: fixed; right: 0; margin-right: 20px;
|
||||
}
|
||||
}
|
||||
4
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/user-meta/index.js
vendored
Normal file
4
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/user-meta/index.js
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
7
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/user-meta/style.scss
vendored
Normal file
7
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/user-meta/style.scss
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* ==========================================================================
|
||||
User Meta
|
||||
========================================================================== */
|
||||
|
||||
.cf-container-user-meta {
|
||||
max-width: 600px;
|
||||
}
|
||||
50
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/widget/index.js
vendored
Normal file
50
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/widget/index.js
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { select } from '@wordpress/data';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { withEffects } from 'refract-callbag';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function aperture() {
|
||||
return fromSelector( select( 'carbon-fields/metaboxes' ).isFieldUpdated );
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @return {Function}
|
||||
*/
|
||||
function handler( props ) {
|
||||
return function( { action } ) {
|
||||
if ( ! action ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { container } = props;
|
||||
const { payload } = action;
|
||||
|
||||
if ( container.fields.map( ( field ) => field.id ).indexOf( payload.fieldId ) >= 0 ) {
|
||||
const $carbonContainer = window.jQuery( `.container-${ container.id }` );
|
||||
|
||||
$carbonContainer.closest( '.widget-inside' ).trigger( 'change' );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addFilter( 'carbon-fields.widget.classic', 'carbon-fields/metaboxes', withEffects( aperture, { handler } ) );
|
||||
31
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/widget/style.scss
vendored
Normal file
31
web/vendor/htmlburger/carbon-fields/packages/metaboxes/containers/widget/style.scss
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* ==========================================================================
|
||||
Widget
|
||||
========================================================================== */
|
||||
|
||||
.cf-container-widget {
|
||||
margin-bottom: 13px;
|
||||
|
||||
.cf-field {
|
||||
margin: 1em 0 0;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cf-field + .cf-field {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.cf-complex__group-body {
|
||||
border-width: 1px 1px 1px 1px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.cf-complex__group-body .cf-field {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.cf-complex__group-body .cf-field + .cf-field {
|
||||
border-width: 1px 0 0 0;
|
||||
padding-top: 1em;
|
||||
}
|
||||
}
|
||||
88
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/association/index.js
vendored
Normal file
88
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/association/index.js
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { select } from '@wordpress/data';
|
||||
import { get, find } from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { withProps } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import stripCompactInputPrefix from '../../utils/strip-compact-input-prefix';
|
||||
|
||||
/**
|
||||
* Returns a field with the given name.
|
||||
*
|
||||
* @param {Object[]} fields
|
||||
* @param {string} name
|
||||
* @return {?Object}
|
||||
*/
|
||||
function findFieldByName( fields, name ) {
|
||||
return find( fields, ( field ) => {
|
||||
return field.name === name;
|
||||
} );
|
||||
}
|
||||
|
||||
addFilter( 'carbon-fields.association.metabox', 'carbon-fields/metaboxes', withProps( ( props ) => {
|
||||
return {
|
||||
hierarchyResolver() {
|
||||
// Get all fields.
|
||||
const container = select( 'carbon-fields/metaboxes' ).getContainerById( props.containerId );
|
||||
const fields = select( 'carbon-fields/metaboxes' ).getFieldsByContainerId( props.containerId );
|
||||
|
||||
// Get a clean version of field's name.
|
||||
const fieldName = stripCompactInputPrefix( props.name );
|
||||
|
||||
// Get the path.
|
||||
let path = fieldName.split( /\[|\]/g );
|
||||
|
||||
// Remove chunks that are empty.
|
||||
path = path.filter( ( chunk ) => chunk !== '' );
|
||||
|
||||
if ( container.type === 'widget' ) {
|
||||
return props.field.base_name;
|
||||
}
|
||||
|
||||
// Get the root field.
|
||||
const rootFieldName = path.shift();
|
||||
const rootField = findFieldByName( fields, rootFieldName );
|
||||
|
||||
// Get the hierarchy.
|
||||
let accessor = fields.indexOf( rootField );
|
||||
let hierarchy = rootField.base_name;
|
||||
|
||||
// Visit every branch in the tree so we can get the full hierarchy.
|
||||
while ( path.length > 0 ) {
|
||||
const chunk = path.shift();
|
||||
const isGroup = ! isNaN( chunk );
|
||||
const isSameField = chunk === props.field.base_name;
|
||||
const isNestedComplex = ! isGroup && ! isSameField;
|
||||
|
||||
if ( isGroup ) {
|
||||
accessor = `${ accessor }.value.${ chunk }.name`;
|
||||
hierarchy = `${ hierarchy }[${ chunk }]:${ get( fields, accessor ) }/`;
|
||||
}
|
||||
|
||||
if ( isNestedComplex ) {
|
||||
const fieldReferences = get( fields, accessor.replace( /\.name$/, '.fields' ) );
|
||||
const fieldReference = findFieldByName( fieldReferences, chunk );
|
||||
const field = find( fields, [ 'id', fieldReference.id ] );
|
||||
|
||||
accessor = fields.indexOf( field );
|
||||
hierarchy = `${ hierarchy }${ field.base_name }`;
|
||||
}
|
||||
|
||||
if ( isSameField ) {
|
||||
hierarchy = `${ hierarchy }${ chunk }`;
|
||||
}
|
||||
}
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
};
|
||||
} ) );
|
||||
295
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/complex/index.js
vendored
Normal file
295
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/complex/index.js
vendored
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import produce from 'immer';
|
||||
import { Component } from '@wordpress/element';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { withDispatch, withSelect } from '@wordpress/data';
|
||||
import {
|
||||
find,
|
||||
assign,
|
||||
without,
|
||||
cloneDeep
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { uniqueId } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
import Field from '../../components/field';
|
||||
import flattenField from '../../utils/flatten-field';
|
||||
|
||||
class ComplexField extends Component {
|
||||
/**
|
||||
* Handles adding of group.
|
||||
*
|
||||
* @param {Object} group
|
||||
* @param {Function} callback
|
||||
* @return {Object}
|
||||
*/
|
||||
handleAddGroup = ( group, callback ) => {
|
||||
const {
|
||||
id,
|
||||
field,
|
||||
value,
|
||||
addFields,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
// Create a copy of the group to prevent
|
||||
// incidentally modifications.
|
||||
group = cloneDeep( group );
|
||||
|
||||
// Get a flat list of all fields for this group.
|
||||
const fields = [];
|
||||
|
||||
group.id = uniqueId();
|
||||
group.container_id = field.container_id;
|
||||
group.fields = group.fields.map( ( groupField ) => flattenField( groupField, field.container_id, fields ) );
|
||||
|
||||
// Make sure that the group is expanded even
|
||||
// `set_collapsed(true)` is used.
|
||||
group.collapsed = false;
|
||||
|
||||
// Push the group to the field.
|
||||
addFields( fields );
|
||||
onChange( id, value.concat( group ) );
|
||||
|
||||
callback( group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles cloning of group.
|
||||
*
|
||||
* @param {Object} group
|
||||
* @param {Function} callback
|
||||
* @return {void}
|
||||
*/
|
||||
handleCloneGroup = ( group, callback ) => {
|
||||
const {
|
||||
id,
|
||||
value,
|
||||
cloneFields,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
const originFieldIds = group.fields.map( ( groupField ) => groupField.id );
|
||||
const cloneFieldIds = originFieldIds.map( () => uniqueId() );
|
||||
const clonedGroup = cloneDeep( group );
|
||||
|
||||
clonedGroup.id = uniqueId();
|
||||
clonedGroup.fields.forEach( ( groupField, index ) => {
|
||||
groupField.id = cloneFieldIds[ index ];
|
||||
} );
|
||||
|
||||
cloneFields( originFieldIds, cloneFieldIds );
|
||||
|
||||
onChange( id, produce( value, ( draft ) => {
|
||||
draft.splice( value.indexOf( group ) + 1, 0, clonedGroup );
|
||||
} ) );
|
||||
|
||||
callback( clonedGroup );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles removing of group.
|
||||
*
|
||||
* @param {Object} group
|
||||
* @return {void}
|
||||
*/
|
||||
handleRemoveGroup = ( group ) => {
|
||||
const {
|
||||
id,
|
||||
value,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
onChange(
|
||||
id,
|
||||
without( value, group ),
|
||||
group.fields.map( ( groupField ) => groupField.id )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles expanding/collapsing of group.
|
||||
*
|
||||
* @param {string} groupId
|
||||
* @return {void}
|
||||
*/
|
||||
handleToggleGroup = ( groupId ) => {
|
||||
const {
|
||||
field,
|
||||
value,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
onChange( field.id, produce( value, ( draft ) => {
|
||||
const group = find( draft, [ 'id', groupId ] );
|
||||
|
||||
group.collapsed = ! group.collapsed;
|
||||
} ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles expanding/collapsing of all groups.
|
||||
*
|
||||
* @param {boolean} collapsed
|
||||
* @return {void}
|
||||
*/
|
||||
handleToggleAllGroups = ( collapsed ) => {
|
||||
const {
|
||||
field,
|
||||
value,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
onChange( field.id, produce( value, ( draft ) => {
|
||||
draft.forEach( ( group ) => {
|
||||
group.collapsed = collapsed;
|
||||
} );
|
||||
} ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles setuping of group.
|
||||
*
|
||||
* @param {Object} group
|
||||
* @param {Object} props
|
||||
* @return {Object}
|
||||
*/
|
||||
handleGroupSetup = ( group, props ) => {
|
||||
return assign( {}, props, {
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
prefix: `${ this.props.name }[${ props.index }]`,
|
||||
fields: group.fields,
|
||||
collapsed: group.collapsed,
|
||||
context: 'metabox'
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles setuping of group's field.
|
||||
*
|
||||
* @param {Object} field
|
||||
* @param {Object} props
|
||||
* @param {Object} groupProps
|
||||
* @return {Array}
|
||||
*/
|
||||
handleGroupFieldSetup = ( field, props, groupProps ) => {
|
||||
return [ Field, assign( {}, props, {
|
||||
key: field.id,
|
||||
id: field.id,
|
||||
containerId: this.props.containerId,
|
||||
name: `${ groupProps.prefix }[${ field.name }]`
|
||||
} ) ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the component.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
render() {
|
||||
const {
|
||||
handleGroupSetup,
|
||||
handleGroupFieldSetup,
|
||||
handleAddGroup,
|
||||
handleCloneGroup,
|
||||
handleRemoveGroup,
|
||||
handleToggleGroup,
|
||||
handleToggleAllGroups
|
||||
} = this;
|
||||
|
||||
const { value, children } = this.props;
|
||||
|
||||
const allGroupsAreCollapsed = value.every( ( { collapsed } ) => collapsed );
|
||||
|
||||
return children( {
|
||||
allGroupsAreCollapsed,
|
||||
handleGroupSetup,
|
||||
handleGroupFieldSetup,
|
||||
handleAddGroup,
|
||||
handleCloneGroup,
|
||||
handleRemoveGroup,
|
||||
handleToggleGroup,
|
||||
handleToggleAllGroups
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
const applyWithSelect = withSelect( ( select, props ) => {
|
||||
const { getComplexGroupValues } = select( 'carbon-fields/metaboxes' );
|
||||
const groupValues = props.value.map( ( group ) => {
|
||||
const fieldIds = group.fields.map( ( field ) => field.id );
|
||||
|
||||
return [ group.name, getComplexGroupValues( fieldIds ) ];
|
||||
} );
|
||||
|
||||
return {
|
||||
groupValues
|
||||
};
|
||||
} );
|
||||
|
||||
const applyWithDispatch = withDispatch( ( dispatch ) => {
|
||||
const { addFields, cloneFields } = dispatch( 'carbon-fields/metaboxes' );
|
||||
|
||||
return {
|
||||
addFields,
|
||||
cloneFields
|
||||
};
|
||||
} );
|
||||
|
||||
addFilter( 'carbon-fields.complex.metabox', 'carbon-fields/metaboxes', ( OriginalComplexField ) => compose(
|
||||
applyWithSelect,
|
||||
applyWithDispatch
|
||||
)( ( props ) => {
|
||||
const {
|
||||
id,
|
||||
field,
|
||||
name,
|
||||
value,
|
||||
groupValues
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<ComplexField { ...props }>
|
||||
{ ( {
|
||||
allGroupsAreCollapsed,
|
||||
handleGroupSetup,
|
||||
handleGroupFieldSetup,
|
||||
handleAddGroup,
|
||||
handleCloneGroup,
|
||||
handleRemoveGroup,
|
||||
handleToggleGroup,
|
||||
handleToggleAllGroups
|
||||
} ) => (
|
||||
<OriginalComplexField
|
||||
groupIdKey="id"
|
||||
groupFilterKey="name"
|
||||
id={ id }
|
||||
field={ field }
|
||||
name={ name }
|
||||
value={ value }
|
||||
groupValues={ groupValues }
|
||||
allGroupsAreCollapsed={ allGroupsAreCollapsed }
|
||||
onGroupSetup={ handleGroupSetup }
|
||||
onGroupFieldSetup={ handleGroupFieldSetup }
|
||||
onAddGroup={ handleAddGroup }
|
||||
onCloneGroup={ handleCloneGroup }
|
||||
onRemoveGroup={ handleRemoveGroup }
|
||||
onToggleGroup={ handleToggleGroup }
|
||||
onToggleAllGroups={ handleToggleAllGroups }
|
||||
onChange={ props.onChange }
|
||||
/>
|
||||
) }
|
||||
</ComplexField>
|
||||
);
|
||||
} ) );
|
||||
54
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/complex/style.scss
vendored
Normal file
54
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/complex/style.scss
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* ==========================================================================
|
||||
Complex
|
||||
========================================================================== */
|
||||
|
||||
.cf-complex__inserter-menu {
|
||||
.postbox &,
|
||||
body[class*="taxonomy-"] & {
|
||||
margin: 0;
|
||||
border-radius: $wp-radius-round;
|
||||
background-color: $wp-color-ultra-dark-gray;
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 100%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-style: solid;
|
||||
border-color: transparent $wp-color-ultra-dark-gray;
|
||||
margin-top: -5px;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cf-complex__inserter-item {
|
||||
.postbox &,
|
||||
body[class*="taxonomy-"] & {
|
||||
font-weight: 600;
|
||||
color: $color-white;
|
||||
transition: color $transition-base;
|
||||
|
||||
&:hover {
|
||||
color: $wp-color-medium-blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cf-complex__inserter-button {
|
||||
.postbox .cf-complex__tabs &,
|
||||
body[class*="taxonomy-"] .cf-complex__tabs & {
|
||||
font-weight: 600;
|
||||
color: $wp-color-dark-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-complex__tabs-item {
|
||||
.postbox &,
|
||||
body[class*="taxonomy"] & {
|
||||
font-weight: 600;
|
||||
color: $wp-color-dark-gray;
|
||||
}
|
||||
}
|
||||
12
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/datetime/index.js
vendored
Normal file
12
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/datetime/index.js
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
addFilter( 'carbon-fields.date_time.metabox', 'carbon-fields/metaboxes', ( OriginalDatetimeField ) => ( props ) => (
|
||||
<OriginalDatetimeField
|
||||
buttonText={ __( 'Select Date', 'carbon-fields-ui' ) }
|
||||
{ ...props }
|
||||
/>
|
||||
) );
|
||||
16
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/file/index.js
vendored
Normal file
16
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/file/index.js
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
addFilter( 'carbon-fields.file.metabox', 'carbon-fields/metaboxes', ( OriginalFileField ) => ( props ) => {
|
||||
return (
|
||||
<OriginalFileField
|
||||
buttonLabel={ __( 'Select File', 'carbon-fields-ui' ) }
|
||||
mediaLibraryButtonLabel={ __( 'Use File', 'carbon-fields-ui' ) }
|
||||
mediaLibraryTitle={ __( 'Select File', 'carbon-fields-ui' ) }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
} );
|
||||
16
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/image/index.js
vendored
Normal file
16
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/image/index.js
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
addFilter( 'carbon-fields.image.metabox', 'carbon-fields/metaboxes', ( OriginalImageField ) => ( props ) => {
|
||||
return (
|
||||
<OriginalImageField
|
||||
buttonLabel={ __( 'Select Image', 'carbon-fields-ui' ) }
|
||||
mediaLibraryButtonLabel={ __( 'Use Image', 'carbon-fields-ui' ) }
|
||||
mediaLibraryTitle={ __( 'Select Image', 'carbon-fields-ui' ) }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
} );
|
||||
54
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/index.js
vendored
Normal file
54
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/index.js
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { withValidation } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import withField from '../hocs/with-field';
|
||||
import withConditionalLogic from '../hocs/with-conditional-logic';
|
||||
import isGutenberg from '../utils/is-gutenberg';
|
||||
|
||||
/**
|
||||
* Connects every field to the store.
|
||||
*/
|
||||
addFilter( 'carbon-fields.field-edit.metabox', 'carbon-fields/metaboxes', compose(
|
||||
withField,
|
||||
withConditionalLogic,
|
||||
withDispatch( ( dispatch ) => {
|
||||
if ( isGutenberg() ) {
|
||||
const { lockPostSaving, unlockPostSaving } = dispatch( 'core/editor' );
|
||||
|
||||
return {
|
||||
lockSaving: lockPostSaving,
|
||||
unlockSaving: unlockPostSaving
|
||||
};
|
||||
}
|
||||
|
||||
const { lockSaving, unlockSaving } = dispatch( 'carbon-fields/metaboxes' );
|
||||
|
||||
return {
|
||||
lockSaving,
|
||||
unlockSaving
|
||||
};
|
||||
} ),
|
||||
withValidation
|
||||
) );
|
||||
|
||||
import './association';
|
||||
import './complex';
|
||||
import './datetime';
|
||||
import './file';
|
||||
import './image';
|
||||
import './multiselect';
|
||||
import './media-gallery';
|
||||
import './radio';
|
||||
import './sidebar';
|
||||
21
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/media-gallery/index.js
vendored
Normal file
21
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/media-gallery/index.js
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
/**
|
||||
* The internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
addFilter( 'carbon-fields.media_gallery.metabox', 'carbon-fields/metaboxes', ( OriginalMediaGalleryField ) => ( props ) => {
|
||||
return (
|
||||
<OriginalMediaGalleryField
|
||||
buttonLabel={ __( 'Select Attachments', 'carbon-fields-ui' ) }
|
||||
mediaLibraryButtonLabel={ __( 'Use Attachments', 'carbon-fields-ui' ) }
|
||||
mediaLibraryTitle={ __( 'Select Attachments', 'carbon-fields-ui' ) }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
} );
|
||||
54
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/media-gallery/style.scss
vendored
Normal file
54
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/media-gallery/style.scss
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* ==========================================================================
|
||||
Media Gallery
|
||||
========================================================================== */
|
||||
|
||||
.cf-media-gallery__inner {
|
||||
.postbox & {
|
||||
border: 1px solid $wp-color-gray-light-500;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-media-gallery__actions {
|
||||
.postbox & {
|
||||
border-top: 1px solid $wp-color-gray-light-500;
|
||||
}
|
||||
|
||||
.cf-container-term-meta & {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-media-gallery__list {
|
||||
.cf-container-term-meta & {
|
||||
margin: 0 -8px;
|
||||
max-height: 285px;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-media-gallery__item {
|
||||
.cf-container-term-meta & {
|
||||
flex-basis: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-media-gallery__item-inner {
|
||||
.postbox &,
|
||||
.cf-container-term-meta & {
|
||||
border: 1px solid $wp-color-gray-light-500;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-media-gallery__item-preview {
|
||||
.postbox &,
|
||||
.cf-container-term-meta & {
|
||||
background-color: $wp-color-gray-light-200;
|
||||
}
|
||||
}
|
||||
|
||||
.cf-media-gallery__item-name {
|
||||
.postbox &,
|
||||
.cf-container-term-meta & {
|
||||
border-top: 1px solid $wp-color-gray-light-500;
|
||||
background-color: $wp-color-gray-light-200;
|
||||
}
|
||||
}
|
||||
4
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/multiselect/index.js
vendored
Normal file
4
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/multiselect/index.js
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
15
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/multiselect/style.scss
vendored
Normal file
15
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/multiselect/style.scss
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* ==========================================================================
|
||||
Multiselect
|
||||
========================================================================== */
|
||||
|
||||
.cf-multiselect__control {
|
||||
.postbox & {
|
||||
border-color: #ddd;
|
||||
box-shadow: 0 1px 2px transparentize($color-black, 0.93) inset;
|
||||
}
|
||||
|
||||
.postbox &--is-focused,
|
||||
.postbox &--is-focused:hover {
|
||||
box-shadow: 0 0 2px transparentize($wp-color-blue, 0.2);
|
||||
}
|
||||
}
|
||||
4
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/radio/index.js
vendored
Normal file
4
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/radio/index.js
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* The internal dependencies.
|
||||
*/
|
||||
import './style.scss';
|
||||
21
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/radio/style.scss
vendored
Normal file
21
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/radio/style.scss
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* ==========================================================================
|
||||
Radio
|
||||
========================================================================== */
|
||||
|
||||
.cf-radio__label {
|
||||
.inside .cf-radio-image .cf-radio__input:focus ~ & {
|
||||
box-shadow: 0 0 2px transparentize($wp-color-medium-blue, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.cf-radio-image__image {
|
||||
.inside & {
|
||||
border: 1px solid $wp-color-gray-light-800;
|
||||
}
|
||||
|
||||
.inside .cf-radio__input:focus ~ .cf-radio__label &,
|
||||
.inside .cf-radio__input:checked ~ .cf-radio__label & {
|
||||
outline: 4px solid $wp-color-medium-blue;
|
||||
}
|
||||
}
|
||||
|
||||
13
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/sidebar/index.js
vendored
Normal file
13
web/vendor/htmlburger/carbon-fields/packages/metaboxes/fields/sidebar/index.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
|
||||
addFilter( 'carbon-fields.sidebar.metabox', 'carbon-fields/metaboxes', withDispatch( ( dispatch ) => {
|
||||
const { receiveSidebar } = dispatch( 'carbon-fields/metaboxes' );
|
||||
|
||||
return {
|
||||
onAdded: receiveSidebar
|
||||
};
|
||||
} ) );
|
||||
175
web/vendor/htmlburger/carbon-fields/packages/metaboxes/hocs/with-conditional-logic/index.js
vendored
Normal file
175
web/vendor/htmlburger/carbon-fields/packages/metaboxes/hocs/with-conditional-logic/index.js
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import of from 'callbag-of';
|
||||
import takeUntil from 'callbag-take-until';
|
||||
import distinctUntilChanged from 'callbag-distinct-until-changed';
|
||||
import { pipe, merge } from 'callbag-basics';
|
||||
import { select } from '@wordpress/data';
|
||||
import {
|
||||
get,
|
||||
map,
|
||||
find,
|
||||
some,
|
||||
pick,
|
||||
keyBy,
|
||||
repeat,
|
||||
isEqual,
|
||||
fromPairs,
|
||||
difference,
|
||||
startsWith
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector, withConditionalLogic } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Returns all root fields from the given holder
|
||||
* while excluding some of them.
|
||||
*
|
||||
* @param {Object} fieldsHolder
|
||||
* @param {Object} allFields
|
||||
* @param {string[]} excludedIds
|
||||
* @return {Object[]}
|
||||
*/
|
||||
function getFieldsFromFieldsHolder( fieldsHolder, allFields, excludedIds = [] ) {
|
||||
if ( typeof fieldsHolder === 'undefined' ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return pick( allFields, difference( map( fieldsHolder.fields, 'id' ), excludedIds ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the `parent.` parent prefix to field's name.
|
||||
*
|
||||
* @param {Object[]} fields
|
||||
* @param {number} depth
|
||||
* @return {Array[]}
|
||||
*/
|
||||
function mapParentPrefix( fields, depth = 0 ) {
|
||||
return map( fields, ( field ) => ( [
|
||||
field.id,
|
||||
`${ repeat( 'parent.', depth ) }${ field.base_name }`
|
||||
] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* The function used to track dependencies required
|
||||
* by conditional logic.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {Object} component
|
||||
* @return {Object}
|
||||
*/
|
||||
function input( props, component ) {
|
||||
const { getFieldsByContainerId } = select( 'carbon-fields/metaboxes' );
|
||||
|
||||
return pipe(
|
||||
merge(
|
||||
of( getFieldsByContainerId( props.containerId ) ),
|
||||
|
||||
fromSelector( getFieldsByContainerId, props.containerId )
|
||||
),
|
||||
|
||||
takeUntil( component.unmount ),
|
||||
|
||||
distinctUntilChanged( isEqual )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that provides the data that needs to be
|
||||
* evaluated by conditional logic.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {Object} fields
|
||||
* @return {Object}
|
||||
*/
|
||||
function output( props, fields ) {
|
||||
fields = keyBy( fields, 'id' );
|
||||
|
||||
const container = select( 'carbon-fields/metaboxes' ).getContainerById( props.containerId );
|
||||
const isTopLevelField = some( container.fields, [ 'id', props.id ] );
|
||||
let siblingFields = [];
|
||||
|
||||
if ( isTopLevelField ) {
|
||||
siblingFields = getFieldsFromFieldsHolder( container, fields, [ props.id ] );
|
||||
siblingFields = mapParentPrefix( siblingFields );
|
||||
} else {
|
||||
const fieldName = props.name.replace( new RegExp( `^${ window.cf.config.compactInputKey }\\[(.+?)\\]` ), '$1' );
|
||||
|
||||
// Get the root field.
|
||||
const rootField = find( fields, ( field ) => {
|
||||
return field.container_id === props.containerId
|
||||
&& startsWith( fieldName, field.name );
|
||||
} );
|
||||
|
||||
// Get the hierarchy.
|
||||
let path = fieldName.split( /\[|\]/g );
|
||||
|
||||
// Remove the chunk with name of root field
|
||||
// because we already have it.
|
||||
path.shift();
|
||||
|
||||
// Remove any chunks that don't have a value.
|
||||
path = path.filter( ( chunk ) => chunk !== '' );
|
||||
|
||||
// Remove the chunk with name of field
|
||||
// because we don't needed it.
|
||||
path.pop();
|
||||
|
||||
// Keep reference to the depth
|
||||
// so we can add the `parent.` prefix.
|
||||
let depth = path.reduce( ( accumulator, chunk ) => {
|
||||
return isNaN( chunk )
|
||||
? accumulator + 1
|
||||
: accumulator;
|
||||
}, 0 );
|
||||
|
||||
// Collect fields that are siblings of root field.
|
||||
siblingFields = getFieldsFromFieldsHolder( container, fields, [ rootField.id ] );
|
||||
siblingFields = mapParentPrefix( siblingFields, depth + 1 );
|
||||
|
||||
// Keep reference to the full path of the field.
|
||||
let pathPrefix = `${ rootField.id }.value`;
|
||||
|
||||
while ( path.length > 0 ) {
|
||||
const chunk = path.shift();
|
||||
const isGroup = ! isNaN( chunk );
|
||||
const isNestedComplex = ! isGroup;
|
||||
|
||||
if ( isGroup ) {
|
||||
pathPrefix = `${ pathPrefix }[${ chunk }]`;
|
||||
|
||||
const group = get( fields, pathPrefix );
|
||||
const groupFields = getFieldsFromFieldsHolder( group, fields, [ props.id ] );
|
||||
|
||||
siblingFields = siblingFields.concat( mapParentPrefix( groupFields, depth ) );
|
||||
|
||||
pathPrefix = `${ pathPrefix }.fields`;
|
||||
}
|
||||
|
||||
if ( isNestedComplex ) {
|
||||
const groupField = find( get( fields, pathPrefix ), [ 'name', chunk ] );
|
||||
|
||||
if ( groupField ) {
|
||||
pathPrefix = `${ groupField.id }.value`;
|
||||
}
|
||||
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
siblingFields = siblingFields.map( ( [ id, name ] ) => ( [
|
||||
name,
|
||||
get( fields, `${ id }.value` )
|
||||
] ) );
|
||||
|
||||
return fromPairs( siblingFields );
|
||||
}
|
||||
|
||||
export default withConditionalLogic( input, output );
|
||||
24
web/vendor/htmlburger/carbon-fields/packages/metaboxes/hocs/with-container/index.js
vendored
Normal file
24
web/vendor/htmlburger/carbon-fields/packages/metaboxes/hocs/with-container/index.js
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { withSelect } from '@wordpress/data';
|
||||
import { createHigherOrderComponent } from '@wordpress/compose';
|
||||
|
||||
/**
|
||||
* Creates a high-order component which adds connection
|
||||
* to the store.
|
||||
*
|
||||
* @param {Function} Component
|
||||
* @return {Function}
|
||||
*/
|
||||
export default createHigherOrderComponent( ( Component ) => {
|
||||
const applyWithSelect = withSelect( ( select, { id } ) => {
|
||||
const container = select( 'carbon-fields/metaboxes' ).getContainerById( id );
|
||||
|
||||
return {
|
||||
container
|
||||
};
|
||||
} );
|
||||
|
||||
return applyWithSelect( Component );
|
||||
}, 'withContainer' );
|
||||
48
web/vendor/htmlburger/carbon-fields/packages/metaboxes/hocs/with-field/index.js
vendored
Normal file
48
web/vendor/htmlburger/carbon-fields/packages/metaboxes/hocs/with-field/index.js
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { withSelect, withDispatch } from '@wordpress/data';
|
||||
import { compose, createHigherOrderComponent } from '@wordpress/compose';
|
||||
|
||||
/**
|
||||
* Creates a high-order component which adds connection
|
||||
* to the store.
|
||||
*
|
||||
* @param {Function} Component
|
||||
* @return {Function}
|
||||
*/
|
||||
export default createHigherOrderComponent( ( Component ) => {
|
||||
const applyWithSelect = withSelect( ( select, props ) => {
|
||||
const { compactInput, compactInputKey } = window.cf.config;
|
||||
const field = select( 'carbon-fields/metaboxes' ).getFieldById( props.id );
|
||||
const value = field && field.value;
|
||||
|
||||
let name = props.name || field.name;
|
||||
|
||||
/**
|
||||
* Wrap top-level field names in compact input key.
|
||||
*
|
||||
* The fields in widgets don't need this prefix because
|
||||
* their input is already compacted by the `widget` namespace.
|
||||
*/
|
||||
if ( compactInput && ! props.name && name.indexOf( 'widget-carbon_fields' ) === -1 ) {
|
||||
name = `${ compactInputKey }[${ name }]`;
|
||||
}
|
||||
|
||||
return {
|
||||
field,
|
||||
name,
|
||||
value
|
||||
};
|
||||
} );
|
||||
|
||||
const applyWithDispatch = withDispatch( ( dispatch ) => {
|
||||
const { updateFieldValue } = dispatch( 'carbon-fields/metaboxes' );
|
||||
|
||||
return {
|
||||
onChange: updateFieldValue
|
||||
};
|
||||
} );
|
||||
|
||||
return compose( applyWithSelect, applyWithDispatch )( Component );
|
||||
}, 'withField' );
|
||||
39
web/vendor/htmlburger/carbon-fields/packages/metaboxes/index.js
vendored
Normal file
39
web/vendor/htmlburger/carbon-fields/packages/metaboxes/index.js
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { setLocaleData } from '@wordpress/i18n';
|
||||
import { addAction } from '@wordpress/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './store';
|
||||
import './fields';
|
||||
import initializeMonitors from './monitors';
|
||||
import initializeContainers from './containers';
|
||||
import isGutenberg from './utils/is-gutenberg';
|
||||
|
||||
/**
|
||||
* Public API.
|
||||
*/
|
||||
export { registerContainerType, getContainerType } from './containers/registry';
|
||||
|
||||
/**
|
||||
* Sets the locale data for the package type
|
||||
*/
|
||||
setLocaleData( window.cf.config.locale, 'carbon-fields-ui' );
|
||||
|
||||
/**
|
||||
* Determines the rendering context.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
const context = isGutenberg() ? 'gutenberg' : 'classic';
|
||||
|
||||
/**
|
||||
* Abracadabra! Poof! Containers everywhere ...
|
||||
*/
|
||||
addAction( 'carbon-fields.init', 'carbon-fields/metaboxes', () => {
|
||||
initializeContainers( context );
|
||||
initializeMonitors( context );
|
||||
} );
|
||||
5
web/vendor/htmlburger/carbon-fields/packages/metaboxes/lib/constants.js
vendored
Normal file
5
web/vendor/htmlburger/carbon-fields/packages/metaboxes/lib/constants.js
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export const PAGE_NOW_WIDGETS = 'widgets.php';
|
||||
export const PAGE_NOW_CUSTOMIZE = 'customize.php';
|
||||
|
||||
export const CARBON_FIELDS_CONTAINER_ID_PREFIX = 'carbon_fields_container_';
|
||||
export const CARBON_FIELDS_CONTAINER_WIDGET_ID_PREFIX = 'carbon_fields_';
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import produce from 'immer';
|
||||
import { applyFilters } from '@wordpress/hooks';
|
||||
import { assign } from 'lodash';
|
||||
import {
|
||||
pipe,
|
||||
merge,
|
||||
scan
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import './post-parent';
|
||||
import './post-format';
|
||||
import './post-template';
|
||||
import './post-term';
|
||||
import './term-parent';
|
||||
import './user-role';
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {string} props.context
|
||||
* @return {Object}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export default function aperture( component, { context } ) {
|
||||
const postParent$ = applyFilters( `carbon-fields.conditional-display-post-parent.${ context }` );
|
||||
const postFormat$ = applyFilters( `carbon-fields.conditional-display-post-format.${ context }` );
|
||||
const postTemplate$ = applyFilters( `carbon-fields.conditional-display-post-template.${ context }` );
|
||||
const postTerm$ = applyFilters( `carbon-fields.conditional-display-post-term.${ context }` );
|
||||
const termParent$ = applyFilters( `carbon-fields.conditional-display-term-parent.${ context }` );
|
||||
const userRole$ = applyFilters( `carbon-fields.conditional-display-user-role.${ context }` );
|
||||
|
||||
return pipe(
|
||||
merge(
|
||||
postParent$,
|
||||
postFormat$,
|
||||
postTemplate$,
|
||||
postTerm$,
|
||||
termParent$,
|
||||
userRole$
|
||||
),
|
||||
scan( ( previous, current ) => produce( previous, ( draft ) => {
|
||||
assign( draft, current );
|
||||
} ) )
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import of from 'callbag-of';
|
||||
import startWith from 'callbag-start-with';
|
||||
import fromDelegatedEvent from 'callbag-from-delegated-event';
|
||||
import distinctUntilChanged from 'callbag-distinct-until-changed';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { select } from '@wordpress/data';
|
||||
import {
|
||||
pipe,
|
||||
map,
|
||||
filter
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* The default state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
const INITIAL_STATE = {
|
||||
post_format: 'standard'
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts `post_format` from the input.
|
||||
*
|
||||
* @param {Object} input
|
||||
* @return {Object}
|
||||
*/
|
||||
function getPostFormatFromRadioInput( input ) {
|
||||
let value = input.value;
|
||||
|
||||
// Normalize the value of "Standard" input.
|
||||
if ( value === '0' ) {
|
||||
value = 'standard';
|
||||
}
|
||||
|
||||
return {
|
||||
post_format: value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the side effects for Classic Editor.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-format.classic', 'carbon-fields/metaboxes', () => {
|
||||
const node = document.querySelector( 'div#post-formats-select' );
|
||||
|
||||
if ( ! node ) {
|
||||
return of( INITIAL_STATE );
|
||||
}
|
||||
|
||||
return pipe(
|
||||
fromDelegatedEvent( node, 'input.post-format', 'change' ),
|
||||
map( ( { target } ) => getPostFormatFromRadioInput( target ) ),
|
||||
startWith( getPostFormatFromRadioInput( node.querySelector( 'input.post-format:checked' ) ) )
|
||||
);
|
||||
} );
|
||||
|
||||
/**
|
||||
* Defines the side effects for Gutenberg.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-format.gutenberg', 'carbon-fields/metaboxes', ( ) => {
|
||||
return pipe(
|
||||
fromSelector( select( 'core/editor' ).getEditedPostAttribute, 'format' ),
|
||||
distinctUntilChanged(),
|
||||
filter( Boolean ),
|
||||
map( ( postFormat ) => ( {
|
||||
post_format: postFormat
|
||||
} ) ),
|
||||
startWith( INITIAL_STATE )
|
||||
);
|
||||
} );
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import of from 'callbag-of';
|
||||
import startWith from 'callbag-start-with';
|
||||
import distinctUntilChanged from 'callbag-distinct-until-changed';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { select } from '@wordpress/data';
|
||||
import {
|
||||
get,
|
||||
find,
|
||||
isEqual
|
||||
} from 'lodash';
|
||||
import {
|
||||
pipe,
|
||||
map,
|
||||
combine,
|
||||
fromEvent
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import getParentIdFromOption from '../utils/get-parent-id-from-option';
|
||||
import getLevelFromOption from '../utils/get-level-from-option';
|
||||
import getAncestorsFromOption from '../utils/get-ancestors-from-option';
|
||||
|
||||
/**
|
||||
* The default state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
const INITIAL_STATE = {
|
||||
post_ancestors: [],
|
||||
post_parent_id: 0,
|
||||
post_level: 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts the `post_ancestors`, `post_parent_id` & `post_level` from the select.
|
||||
*
|
||||
* @param {Object} node
|
||||
* @return {Object}
|
||||
*/
|
||||
function getParentIdAncestorsAndLevelFromSelect( node ) {
|
||||
const option = node.options[ node.selectedIndex ];
|
||||
const ancestors = getAncestorsFromOption( option );
|
||||
const parentId = getParentIdFromOption( option );
|
||||
const level = getLevelFromOption( option ) + 1;
|
||||
|
||||
return {
|
||||
post_ancestors: ancestors,
|
||||
post_parent_id: parentId,
|
||||
post_level: level
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts `post_ancestors` from the list.
|
||||
*
|
||||
* @param {number} parentId
|
||||
* @param {Object[]} posts
|
||||
* @param {Array} ancestors
|
||||
* @return {number[]}
|
||||
*/
|
||||
function getAncestorsFromPostsList( parentId, posts, ancestors = [] ) {
|
||||
const parent = find( posts, [ 'id', parentId ] );
|
||||
|
||||
if ( ! parent ) {
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
ancestors.unshift( parent.id );
|
||||
|
||||
if ( parent.parent ) {
|
||||
return getAncestorsFromPostsList( parent.parent, posts, ancestors );
|
||||
}
|
||||
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the side effects for Classic Editor.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-parent.classic', 'carbon-fields/metaboxes', ( ) => {
|
||||
const node = document.querySelector( 'select#parent_id' );
|
||||
|
||||
if ( ! node ) {
|
||||
return of( INITIAL_STATE );
|
||||
}
|
||||
|
||||
return pipe(
|
||||
fromEvent.default( node, 'change' ),
|
||||
map( ( { target } ) => getParentIdAncestorsAndLevelFromSelect( target ) ),
|
||||
startWith( getParentIdAncestorsAndLevelFromSelect( node ) )
|
||||
);
|
||||
} );
|
||||
|
||||
/**
|
||||
* Defines the side effects for Gutenberg.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-parent.gutenberg', 'carbon-fields/metaboxes', ( ) => {
|
||||
const { getPostType, getEntityRecords } = select( 'core' );
|
||||
|
||||
return pipe(
|
||||
combine(
|
||||
fromSelector( select( 'core/editor' ).getCurrentPostId ),
|
||||
fromSelector( select( 'core/editor' ).getEditedPostAttribute, 'type' ),
|
||||
fromSelector( select( 'core/editor' ).getEditedPostAttribute, 'parent' )
|
||||
),
|
||||
distinctUntilChanged( isEqual ),
|
||||
map( ( [ postId, postTypeSlug, parentId ] ) => {
|
||||
parentId = parseInt( parentId, 10 );
|
||||
|
||||
if ( isNaN( parentId ) ) {
|
||||
return INITIAL_STATE;
|
||||
}
|
||||
|
||||
const postType = getPostType( postTypeSlug );
|
||||
const isHierarchical = get( postType, [ 'hierarchical' ], false );
|
||||
|
||||
if ( ! isHierarchical ) {
|
||||
return INITIAL_STATE;
|
||||
}
|
||||
|
||||
// Borrowed from https://github.com/WordPress/gutenberg/blob/master/packages/editor/src/components/page-attributes/parent.js
|
||||
const items = getEntityRecords( 'postType', postTypeSlug, {
|
||||
per_page: -1,
|
||||
exclude: postId,
|
||||
parent_exclude: postId,
|
||||
orderby: 'menu_order',
|
||||
order: 'asc'
|
||||
} ) || [];
|
||||
|
||||
const ancestors = getAncestorsFromPostsList( parentId, items );
|
||||
const level = ancestors.length + 1;
|
||||
|
||||
return {
|
||||
post_ancestors: ancestors,
|
||||
post_parent_id: parentId,
|
||||
post_level: level
|
||||
};
|
||||
} )
|
||||
);
|
||||
} );
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import of from 'callbag-of';
|
||||
import startWith from 'callbag-start-with';
|
||||
import distinctUntilChanged from 'callbag-distinct-until-changed';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { select } from '@wordpress/data';
|
||||
import { isString } from 'lodash';
|
||||
import {
|
||||
pipe,
|
||||
map,
|
||||
filter,
|
||||
fromEvent
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* The default state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
const INITIAL_STATE = {
|
||||
post_template: ''
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts `post_template` from the select.
|
||||
*
|
||||
* @param {Object} node
|
||||
* @return {Object}
|
||||
*/
|
||||
function getPostTemplateFromSelect( node ) {
|
||||
let { value } = node;
|
||||
|
||||
// In Gutenberg for the "Default" template is used an empty string.
|
||||
if ( value === 'default' ) {
|
||||
value = '';
|
||||
}
|
||||
|
||||
return {
|
||||
post_template: value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the side effects for Classic Editor.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-template.classic', 'carbon-fields/metaboxes', () => {
|
||||
const node = document.querySelector( 'select#page_template' );
|
||||
|
||||
if ( ! node ) {
|
||||
return of( INITIAL_STATE );
|
||||
}
|
||||
|
||||
return pipe(
|
||||
fromEvent.default( node, 'change' ),
|
||||
map( ( { target } ) => getPostTemplateFromSelect( target ) ),
|
||||
startWith( getPostTemplateFromSelect( node ) )
|
||||
);
|
||||
} );
|
||||
|
||||
/**
|
||||
* Defines the side effects for Gutenberg.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-template.gutenberg', 'carbon-fields/metaboxes', () => {
|
||||
return pipe(
|
||||
fromSelector( select( 'core/editor' ).getEditedPostAttribute, 'template' ),
|
||||
distinctUntilChanged(),
|
||||
filter( isString ),
|
||||
map( ( postTemplate ) => ( {
|
||||
post_template: postTemplate
|
||||
} ) ),
|
||||
startWith( INITIAL_STATE )
|
||||
);
|
||||
} );
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import produce from 'immer';
|
||||
import startWith from 'callbag-start-with';
|
||||
import fromDelegatedEvent from 'callbag-from-delegated-event';
|
||||
import {
|
||||
merge,
|
||||
pipe,
|
||||
scan,
|
||||
map,
|
||||
filter,
|
||||
fromEvent
|
||||
} from 'callbag-basics';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import { select } from '@wordpress/data';
|
||||
import { pull, fromPairs } from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
const TAGS_DELIMITER = ',';
|
||||
|
||||
/**
|
||||
* Applies a monkey patch to the specified method of `window.tagBox` API
|
||||
* so we can detect changes of the non-hierarchical taxonomies.
|
||||
*
|
||||
* @param {Object} tagBox
|
||||
* @param {string} method
|
||||
* @return {void}
|
||||
*/
|
||||
function patchWordPressTagBoxAPI( tagBox, method ) {
|
||||
tagBox[ `original_${ method }` ] = tagBox[ method ];
|
||||
|
||||
tagBox[ method ] = function( ...args ) {
|
||||
const event = new Event( 'change' );
|
||||
const textarea = window.jQuery( args[ 0 ] )
|
||||
.closest( '.postbox' )
|
||||
.find( 'textarea.the-tags' )
|
||||
.get( 0 );
|
||||
|
||||
const result = tagBox[ `original_${ method }` ]( ...args );
|
||||
|
||||
textarea.dispatchEvent( event );
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
if ( window.tagBox ) {
|
||||
patchWordPressTagBoxAPI( window.tagBox, 'parseTags' );
|
||||
patchWordPressTagBoxAPI( window.tagBox, 'flushTags' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the terms of a hierarchical taxonomy.
|
||||
*
|
||||
* @param {string} taxonomy
|
||||
* @return {Object}
|
||||
*/
|
||||
function getTermsFromChecklist( taxonomy ) {
|
||||
const inputs = document.querySelectorAll( `#${ taxonomy }checklist input[type="checkbox"]:checked` );
|
||||
|
||||
return [ ...inputs ].reduce( ( memo, input ) => {
|
||||
const value = parseInt( input.value, 10 );
|
||||
|
||||
memo[ taxonomy ].push( value );
|
||||
|
||||
return memo;
|
||||
}, {
|
||||
[ taxonomy ]: []
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the terms of a non-hierarchical taxonomy.
|
||||
*
|
||||
* @param {string} taxonomy
|
||||
* @return {Object}
|
||||
*/
|
||||
function getTermsFromText( taxonomy ) {
|
||||
const node = document.querySelector( `#tagsdiv-${ taxonomy } textarea.the-tags` );
|
||||
const terms = node.value
|
||||
? node.value.split( TAGS_DELIMITER )
|
||||
: [];
|
||||
|
||||
return {
|
||||
[ taxonomy ]: terms
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track of the hierarchical taxonomies like `categories`.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
function trackHierarchicalTaxonomies() {
|
||||
const nodes = document.querySelectorAll( 'div[id^="taxonomy-"]' );
|
||||
|
||||
return [ ...nodes ].map( ( node ) => {
|
||||
const taxonomy = node.id.replace( 'taxonomy-', '' );
|
||||
|
||||
return pipe(
|
||||
fromDelegatedEvent( node.querySelector( `#${ taxonomy }checklist` ), 'input[type="checkbox"]', 'change' ),
|
||||
scan( ( stack, { target } ) => {
|
||||
return produce( stack, ( draft ) => {
|
||||
const value = parseInt( target.value, 10 );
|
||||
|
||||
if ( target.checked ) {
|
||||
draft[ taxonomy ].push( value );
|
||||
} else {
|
||||
pull( draft[ taxonomy ], value );
|
||||
}
|
||||
} );
|
||||
}, {
|
||||
[ taxonomy ]: []
|
||||
} ),
|
||||
startWith( getTermsFromChecklist( taxonomy ) )
|
||||
);
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track of the non-hierarchical taxonomies like `tags`.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
function trackNonHierarchicalTaxonomies() {
|
||||
const nodes = document.querySelectorAll( 'div[id^="tagsdiv-"]' );
|
||||
|
||||
return [ ...nodes ].map( ( node ) => {
|
||||
const taxonomy = node.id.replace( 'tagsdiv-', '' );
|
||||
|
||||
return pipe(
|
||||
fromEvent.default( node.querySelector( 'textarea.the-tags' ), 'change' ),
|
||||
map( ( { target } ) => ( {
|
||||
[ taxonomy ]: target.value
|
||||
? target.value.split( TAGS_DELIMITER )
|
||||
: []
|
||||
} ) ),
|
||||
startWith( getTermsFromText( taxonomy ) )
|
||||
);
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the side effects for Classic Editor.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-term.classic', 'carbon-fields/metaboxes', () => {
|
||||
return pipe(
|
||||
merge(
|
||||
...trackHierarchicalTaxonomies(),
|
||||
...trackNonHierarchicalTaxonomies()
|
||||
),
|
||||
scan( ( previous, current ) => {
|
||||
return {
|
||||
post_term: {
|
||||
...previous.post_term,
|
||||
...current
|
||||
}
|
||||
};
|
||||
}, {
|
||||
post_term: {}
|
||||
} )
|
||||
);
|
||||
} );
|
||||
|
||||
/**
|
||||
* Defines the side effects for Gutenberg.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-post-term.gutenberg', 'carbon-fields/metaboxes', () => {
|
||||
const { getTaxonomies } = select( 'core' );
|
||||
const { getEditedPostAttribute } = select( 'core/editor' );
|
||||
|
||||
// Borrowed from https://github.com/WordPress/gutenberg/blob/master/packages/editor/src/components/post-taxonomies/index.js
|
||||
return pipe(
|
||||
fromSelector( getTaxonomies, { per_page: -1 } ),
|
||||
filter( Boolean ),
|
||||
map( ( taxonomies ) => {
|
||||
const pairs = taxonomies.map( ( taxonomy ) => ( [
|
||||
taxonomy.slug,
|
||||
getEditedPostAttribute( taxonomy.rest_base ) || []
|
||||
] ) );
|
||||
|
||||
return {
|
||||
post_term: fromPairs( pairs )
|
||||
};
|
||||
} )
|
||||
);
|
||||
} );
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import of from 'callbag-of';
|
||||
import startWith from 'callbag-start-with';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import {
|
||||
pipe,
|
||||
map,
|
||||
fromEvent
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import getParentIdFromOption from '../utils/get-parent-id-from-option';
|
||||
import getLevelFromOption from '../utils/get-level-from-option';
|
||||
import getAncestorsFromOption from '../utils/get-ancestors-from-option';
|
||||
|
||||
/**
|
||||
* The default state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
const INITIAL_STATE = {
|
||||
term_ancestors: [],
|
||||
term_parent: 0,
|
||||
term_level: 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts the `term_ancestors`, `term_parent` & `term_level` from the select.
|
||||
*
|
||||
* @param {Object} node
|
||||
* @return {Object}
|
||||
*/
|
||||
function getParentIdAncestorsAndLevelFromSelect( node ) {
|
||||
const option = node.options[ node.selectedIndex ];
|
||||
const ancestors = getAncestorsFromOption( option );
|
||||
const parentId = getParentIdFromOption( option );
|
||||
const level = getLevelFromOption( option ) + 1;
|
||||
|
||||
return {
|
||||
term_ancestors: ancestors,
|
||||
term_parent: parentId,
|
||||
term_level: level
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the side effects for Classic Editor.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-term-parent.classic', 'carbon-fields/metaboxes', ( ) => {
|
||||
const node = document.querySelector( 'select#parent' );
|
||||
|
||||
if ( ! node ) {
|
||||
return of( INITIAL_STATE );
|
||||
}
|
||||
|
||||
return pipe(
|
||||
fromEvent.default( node, 'change' ),
|
||||
map( ( { target } ) => getParentIdAncestorsAndLevelFromSelect( target ) ),
|
||||
startWith( getParentIdAncestorsAndLevelFromSelect( node ) )
|
||||
);
|
||||
} );
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import of from 'callbag-of';
|
||||
import startWith from 'callbag-start-with';
|
||||
import { addFilter } from '@wordpress/hooks';
|
||||
import {
|
||||
pipe,
|
||||
map,
|
||||
fromEvent
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* The default state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
const INITIAL_STATE = {
|
||||
user_role: ''
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts `user_role` from a select.
|
||||
*
|
||||
* @param {Object} node
|
||||
* @return {Object}
|
||||
*/
|
||||
function getRoleFromSelect( node ) {
|
||||
return {
|
||||
user_role: node.value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the side effects for Classic Editor.
|
||||
*/
|
||||
addFilter( 'carbon-fields.conditional-display-user-role.classic', 'carbon-fields/metaboxes', ( ) => {
|
||||
const node = document.querySelector( 'select#role' );
|
||||
|
||||
if ( ! node ) {
|
||||
const fieldset = document.querySelector( 'fieldset[data-profile-role]' );
|
||||
|
||||
// The selectbox doesn't exist on the "Profile" page.
|
||||
// So we need to read the role from the container in DOM.
|
||||
if ( fieldset ) {
|
||||
return of( {
|
||||
user_role: fieldset.dataset.profileRole
|
||||
} );
|
||||
}
|
||||
|
||||
return of( INITIAL_STATE );
|
||||
}
|
||||
|
||||
return pipe(
|
||||
fromEvent.default( node, 'change' ),
|
||||
map( ( { target } ) => getRoleFromSelect( target ) ),
|
||||
startWith( getRoleFromSelect( node ) )
|
||||
);
|
||||
} );
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { intersection } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
operators: [ 'IN', 'NOT IN' ],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
evaluate( a, operator, b ) {
|
||||
switch ( operator ) {
|
||||
case 'IN':
|
||||
return intersection( a, b ).length > 0;
|
||||
case 'NOT IN':
|
||||
return intersection( a, b ).length === 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { includes } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
operators: [ '=', '!=' ],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
evaluate( a, operator, b ) {
|
||||
switch ( operator ) {
|
||||
case '=':
|
||||
return includes( a, b );
|
||||
case '!=':
|
||||
return ! includes( a, b );
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
export default {
|
||||
/**
|
||||
* The supported operators.
|
||||
*
|
||||
* @type {string[]}
|
||||
*/
|
||||
operators: [],
|
||||
|
||||
/**
|
||||
* Checks if the operator is supported.
|
||||
*
|
||||
* @param {string} operator
|
||||
* @return {boolean}
|
||||
*/
|
||||
isOperatorSupported( operator ) {
|
||||
return this.operators.indexOf( operator ) > -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs the comparison.
|
||||
*
|
||||
* @param {mixed} a
|
||||
* @param {string} operator
|
||||
* @param {mixed} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
evaluate() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
operators: [ 'IN', 'NOT IN' ],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
evaluate( a, operator, b ) {
|
||||
switch ( operator ) {
|
||||
case 'IN':
|
||||
return b.indexOf( a ) > -1;
|
||||
case 'NOT IN':
|
||||
return b.indexOf( a ) === -1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* eslint eqeqeq: "off" */
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
operators: [ '=', '!=' ],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
evaluate( a, operator, b ) {
|
||||
switch ( operator ) {
|
||||
case '=':
|
||||
return a == b;
|
||||
case '!=':
|
||||
return a != b;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
operators: [ '>', '>=', '<', '<=' ],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
evaluate( a, operator, b ) {
|
||||
switch ( operator ) {
|
||||
case '>':
|
||||
return a > b;
|
||||
case '>=':
|
||||
return a >= b;
|
||||
case '<':
|
||||
return a < b;
|
||||
case '<=':
|
||||
return a <= b;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { find } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import equality from '../comparers/equality';
|
||||
import contain from '../comparers/contain';
|
||||
import scalar from '../comparers/scalar';
|
||||
|
||||
export default {
|
||||
/**
|
||||
* The supported comparers.
|
||||
*
|
||||
* @type {Function[]}
|
||||
*/
|
||||
comparers: [
|
||||
equality,
|
||||
contain,
|
||||
scalar
|
||||
],
|
||||
|
||||
/**
|
||||
* Checks if the condition is fulfiled.
|
||||
*
|
||||
* @param {Object} definition
|
||||
* @param {Object} values
|
||||
* @return {boolean}
|
||||
*/
|
||||
isFulfiled( definition, values ) {
|
||||
const { compare, value } = definition;
|
||||
|
||||
return this.firstComparerIsCorrect( this.getEnvironmentValue( definition, values ), compare, value );
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if any comparer is correct for `a` and `b`.
|
||||
*
|
||||
* @param {mixed} a
|
||||
* @param {string} operator
|
||||
* @param {mixed} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
firstComparerIsCorrect( a, operator, b ) {
|
||||
const comparer = find( this.comparers, ( item ) => item.isOperatorSupported( operator ) );
|
||||
|
||||
if ( ! comparer ) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error( sprintf( __( 'Unsupported container condition comparison operator used - "%1$s".', 'carbon-fields-ui' ), operator ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return comparer.evaluate( a, operator, b );
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the value from the environment.
|
||||
*
|
||||
* @param {Object} definition
|
||||
* @param {Object} values
|
||||
* @return {Object}
|
||||
*/
|
||||
getEnvironmentValue( definition, values ) {
|
||||
return values[ definition.type ];
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getEnvironmentValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { get } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import anyEquality from '../comparers/any-equality';
|
||||
import anyContain from '../comparers/any-contain';
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
comparers: [
|
||||
anyEquality,
|
||||
anyContain
|
||||
],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getEnvironmentValue( definition, values ) {
|
||||
return get( values, 'post_ancestors', [] );
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { isArray } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
isFulfiled( definition, values ) {
|
||||
definition = { ...definition };
|
||||
|
||||
// In Gutenberg for the "Default" template is used an empty string.
|
||||
if ( definition.value === 'default' ) {
|
||||
definition.value = '';
|
||||
} else if ( isArray( definition.value ) ) {
|
||||
const defaultIndex = definition.value.indexOf( 'default' );
|
||||
|
||||
if ( defaultIndex !== -1 ) {
|
||||
definition.value[ defaultIndex ] = '';
|
||||
}
|
||||
}
|
||||
|
||||
return base.isFulfiled( definition, values );
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { get, isArray } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import anyEquality from '../comparers/any-equality';
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
comparers: [
|
||||
anyEquality
|
||||
],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
isFulfiled( definition, values ) {
|
||||
let { compare, value } = definition;
|
||||
|
||||
if ( isArray( value ) ) {
|
||||
let method;
|
||||
|
||||
switch ( compare ) {
|
||||
case 'IN':
|
||||
compare = '=';
|
||||
method = 'some';
|
||||
break;
|
||||
|
||||
case 'NOT IN':
|
||||
compare = '!=';
|
||||
method = 'every';
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
const results = value.map( ( descriptor ) => {
|
||||
return this.isFulfiled( {
|
||||
...definition,
|
||||
compare,
|
||||
value: descriptor
|
||||
}, values );
|
||||
} );
|
||||
|
||||
return results[ method ]( Boolean );
|
||||
}
|
||||
|
||||
// TODO: Improve value resolution in context of Gutenberg
|
||||
value = value.taxonomy_object.hierarchical
|
||||
? value.term_object.term_id
|
||||
: value.term_object.name;
|
||||
|
||||
return this.firstComparerIsCorrect( this.getEnvironmentValue( definition, values ), compare, value );
|
||||
},
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getEnvironmentValue( definition, values ) {
|
||||
return get( values, `post_term.${ definition.value.taxonomy }`, [] );
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import {
|
||||
get,
|
||||
isArray,
|
||||
isPlainObject
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import anyEquality from '../comparers/any-equality';
|
||||
import anyContain from '../comparers/any-contain';
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
comparers: [
|
||||
anyEquality,
|
||||
anyContain
|
||||
],
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
isFulfiled( definition, values ) {
|
||||
const { compare } = definition;
|
||||
let { value } = definition;
|
||||
|
||||
if ( isArray( value ) ) {
|
||||
value = value.map( ( item ) => item.term_object.term_id );
|
||||
} else if ( isPlainObject( value ) ) {
|
||||
value = value.term_object.term_id;
|
||||
}
|
||||
|
||||
return this.firstComparerIsCorrect( this.getEnvironmentValue( definition, values ), compare, value );
|
||||
},
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
getEnvironmentValue( definition, values ) {
|
||||
return get( values, 'term_ancestors', [] );
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { isArray, isPlainObject } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import base from './base';
|
||||
|
||||
export default {
|
||||
...base,
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
isFulfiled( definition, values ) {
|
||||
const { compare } = definition;
|
||||
let { value } = definition;
|
||||
|
||||
if ( isArray( value ) ) {
|
||||
value = value.map( ( item ) => item.term_object.term_id );
|
||||
} else if ( isPlainObject( value ) ) {
|
||||
value = value.term_object.term_id;
|
||||
}
|
||||
|
||||
return this.firstComparerIsCorrect( this.getEnvironmentValue( definition, values ), compare, value );
|
||||
}
|
||||
};
|
||||
136
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/conditional-display/handler/index.js
vendored
Normal file
136
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/conditional-display/handler/index.js
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { get, map } from 'lodash';
|
||||
import { createRoot } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import { renderContainer } from '../../../containers';
|
||||
import base from '../conditions/base';
|
||||
import boolean from '../conditions/boolean';
|
||||
import postTerm from '../conditions/post-term';
|
||||
import postTemplate from '../conditions/post-template';
|
||||
import postAncestorId from '../conditions/post-ancestor-id';
|
||||
import termParentId from '../conditions/term-parent-id';
|
||||
import termAncestorId from '../conditions/term-ancestor-id';
|
||||
import { getContainerRoot } from '../../../containers/root-registry';
|
||||
|
||||
/**
|
||||
* Keeps track of supported conditions.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
const conditions = {
|
||||
boolean,
|
||||
post_term: postTerm,
|
||||
post_ancestor_id: postAncestorId,
|
||||
post_parent_id: base,
|
||||
post_level: base,
|
||||
post_format: base,
|
||||
post_template: postTemplate,
|
||||
term_level: base,
|
||||
term_parent: termParentId,
|
||||
term_ancestor: termAncestorId,
|
||||
user_role: base
|
||||
};
|
||||
|
||||
/**
|
||||
* Walks through the definitions and evaluates the conditions.
|
||||
*
|
||||
* @param {Object[]} definitions
|
||||
* @param {Object} values
|
||||
* @param {string} relation
|
||||
* @return {boolean}
|
||||
*/
|
||||
function evaluate( definitions, values, relation ) {
|
||||
const results = definitions.map( ( definition ) => {
|
||||
if ( ! definition.relation ) {
|
||||
const condition = get( conditions, definition.type );
|
||||
|
||||
if ( condition ) {
|
||||
return condition.isFulfiled( definition, values );
|
||||
} else { // eslint-disable-line no-else-return
|
||||
// eslint-disable-next-line no-console
|
||||
console.error( sprintf( __( 'Unsupported container condition - "%1$s".', 'carbon-fields-ui' ), definition.type ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
} else { // eslint-disable-line no-else-return
|
||||
return evaluate( definition.conditions, values, definition.relation );
|
||||
}
|
||||
} );
|
||||
|
||||
switch ( relation ) {
|
||||
case 'AND':
|
||||
return results.every( Boolean );
|
||||
|
||||
case 'OR':
|
||||
return results.some( Boolean );
|
||||
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error( sprintf( __( 'Unsupported container condition relation used - "%1$s".', 'carbon-fields-ui' ), relation ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {Object} props.containers
|
||||
* @param {string} props.context
|
||||
* @return {Function}
|
||||
*/
|
||||
export default function handler( { containers, context } ) {
|
||||
return function( effect ) {
|
||||
const results = map( containers, ( container, id ) => {
|
||||
return [
|
||||
id,
|
||||
evaluate( container.conditions.conditions, effect, container.conditions.relation )
|
||||
];
|
||||
} );
|
||||
|
||||
results.forEach( ( [ id, result ] ) => {
|
||||
const postboxNode = document.getElementById( id );
|
||||
const containerNode = document.querySelector( `.container-${ id }` );
|
||||
const isMounted = !! containerNode?.dataset?.mounted;
|
||||
|
||||
if ( postboxNode ) {
|
||||
postboxNode.hidden = ! result;
|
||||
}
|
||||
|
||||
if ( containerNode ) {
|
||||
if ( createRoot ) {
|
||||
const containerRoot = getContainerRoot( id );
|
||||
|
||||
if ( result && ! containerRoot ) {
|
||||
renderContainer( containers[ id ], context );
|
||||
}
|
||||
|
||||
if ( ! result && containerRoot ) {
|
||||
containerRoot.unmount();
|
||||
}
|
||||
} else {
|
||||
if ( result && ! isMounted ) {
|
||||
renderContainer( containers[ id ], context );
|
||||
}
|
||||
|
||||
if ( ! result && isMounted ) {
|
||||
delete containerNode?.dataset?.mounted;
|
||||
|
||||
// Rely on React's internals instead of `unmountComponentAtNode`
|
||||
// due to https://github.com/facebook/react/issues/13690.
|
||||
// TODO: Conditionally render the fields in the container, this way
|
||||
// we can move away from mount/unmount cycles.
|
||||
containerNode?._reactRootContainer?.unmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
};
|
||||
}
|
||||
36
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/conditional-display/index.js
vendored
Normal file
36
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/conditional-display/index.js
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { withSelect } from '@wordpress/data';
|
||||
import { withEffects } from 'refract-callbag';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import aperture from './aperture';
|
||||
import handler from './handler';
|
||||
|
||||
/**
|
||||
* Performs the evaluation of conditions.
|
||||
*
|
||||
* @return {null}
|
||||
*/
|
||||
function ConditionalDisplay() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const applyWithSelect = withSelect( ( select ) => {
|
||||
const containers = select( 'carbon-fields/metaboxes' ).getContainers();
|
||||
|
||||
return {
|
||||
containers
|
||||
};
|
||||
} );
|
||||
|
||||
const applyWithEffects = withEffects( aperture, { handler } );
|
||||
|
||||
export default compose(
|
||||
applyWithSelect,
|
||||
applyWithEffects
|
||||
)( ConditionalDisplay );
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import getLevelFromOption from './get-level-from-option';
|
||||
|
||||
/**
|
||||
* Extracts the ancestors of the post/term from an option.
|
||||
*
|
||||
* @param {Object} option
|
||||
* @return {number[]}
|
||||
*/
|
||||
export default function getAncestorsFromOption( option ) {
|
||||
const ancestors = [];
|
||||
|
||||
let previousOption = option;
|
||||
let level = getLevelFromOption( option );
|
||||
|
||||
while ( level > 0 && previousOption ) {
|
||||
if ( getLevelFromOption( previousOption ) !== level ) {
|
||||
previousOption = previousOption.previousSibling;
|
||||
|
||||
// Skip this iteration because the option isn't an ancestor.
|
||||
continue;
|
||||
}
|
||||
|
||||
const id = parseInt( previousOption.value, 10 );
|
||||
|
||||
if ( id > 0 ) {
|
||||
ancestors.unshift( id );
|
||||
}
|
||||
|
||||
previousOption = previousOption.previousSibling;
|
||||
|
||||
level--;
|
||||
}
|
||||
|
||||
return ancestors;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Extracts the level from an option.
|
||||
*
|
||||
* @param {Object} option
|
||||
* @return {number}
|
||||
*/
|
||||
export default function getLevelFromOption( option ) {
|
||||
let level = 0;
|
||||
|
||||
if ( option.className ) {
|
||||
const matches = option.className.match( /^level-(\d+)/ );
|
||||
|
||||
if ( matches ) {
|
||||
level = parseInt( matches[ 1 ], 10 ) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Extracts the id of the post/term parent from an option.
|
||||
*
|
||||
* @param {Object} option
|
||||
* @return {number}
|
||||
*/
|
||||
export default function getParentIdFromOption( option ) {
|
||||
const value = parseInt( option.value, 10 );
|
||||
|
||||
return ( ! isNaN( value ) && value >= 0 ) ? value : 0;
|
||||
}
|
||||
61
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/index.js
vendored
Normal file
61
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/index.js
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { Fragment, render, createRoot } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import SaveLock from './save-lock';
|
||||
import ConditionalDisplay from './conditional-display';
|
||||
import WidgetHandler from './widget-handler';
|
||||
import RevisionsFlag from './revisions-flag';
|
||||
import isGutenberg from '../utils/is-gutenberg';
|
||||
import { PAGE_NOW_WIDGETS, PAGE_NOW_CUSTOMIZE } from '../lib/constants';
|
||||
|
||||
/**
|
||||
* Initializes the monitors.
|
||||
*
|
||||
* @param {string} context
|
||||
* @return {void}
|
||||
*/
|
||||
export default function initializeMonitors( context ) {
|
||||
const { pagenow } = window.cf.config;
|
||||
|
||||
const MonitorElement = document.createElement( 'div' );
|
||||
const MonitorComponent = <Fragment>
|
||||
{ ! isGutenberg() && (
|
||||
<SaveLock />
|
||||
) }
|
||||
|
||||
{ ( pagenow === PAGE_NOW_WIDGETS || pagenow === PAGE_NOW_CUSTOMIZE ) && (
|
||||
<WidgetHandler />
|
||||
) }
|
||||
|
||||
<ConditionalDisplay context={ context } />
|
||||
</Fragment>;
|
||||
|
||||
if ( createRoot ) {
|
||||
createRoot( MonitorElement ).render( MonitorComponent );
|
||||
} else {
|
||||
render(
|
||||
MonitorComponent,
|
||||
MonitorElement,
|
||||
);
|
||||
}
|
||||
|
||||
const postStuffNode = document.querySelector( '#poststuff' );
|
||||
|
||||
if ( postStuffNode ) {
|
||||
const postStuffElement = document.createElement( 'div' );
|
||||
const postStuffComponenet = <RevisionsFlag />;
|
||||
|
||||
const postStuffChildElement = postStuffNode.appendChild( postStuffElement );
|
||||
|
||||
if ( createRoot ) {
|
||||
createRoot( postStuffChildElement ).render( postStuffComponenet );
|
||||
} else {
|
||||
render( postStuffComponenet, postStuffChildElement );
|
||||
}
|
||||
}
|
||||
}
|
||||
26
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/revisions-flag/index.js
vendored
Normal file
26
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/revisions-flag/index.js
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { withSelect } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Renders the input used to notify the backend about the changes.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {boolean} props.isDirty
|
||||
* @return {mixed}
|
||||
*/
|
||||
function RevisionsFlag( props ) {
|
||||
return (
|
||||
<input
|
||||
type="hidden"
|
||||
name={ window.cf.config.revisionsInputKey }
|
||||
disabled={ ! props.isDirty }
|
||||
value="1"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default withSelect( ( select ) => ( {
|
||||
isDirty: select( 'carbon-fields/metaboxes' ).isDirty()
|
||||
} ) )( RevisionsFlag );
|
||||
51
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/save-lock/index.js
vendored
Normal file
51
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/save-lock/index.js
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { withEffects } from 'refract-callbag';
|
||||
import { select } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Toggles the ability to save the page.
|
||||
*
|
||||
* @return {null}
|
||||
*/
|
||||
function SaveLock() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function aperture() {
|
||||
return fromSelector( select( 'carbon-fields/metaboxes' ).isSavingLocked );
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
function handler() {
|
||||
return function( isLocked ) {
|
||||
const nodes = document.querySelectorAll( `
|
||||
#publishing-action input#publish,
|
||||
#publishing-action input#save,
|
||||
#addtag input#submit,
|
||||
#edittag input[type="submit"],
|
||||
#your-profile input#submit
|
||||
` );
|
||||
|
||||
nodes.forEach( ( node ) => {
|
||||
node.disabled = isLocked;
|
||||
} );
|
||||
};
|
||||
}
|
||||
|
||||
export default withEffects( aperture, { handler } )( SaveLock );
|
||||
47
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/unsaved-changes/index.js
vendored
Normal file
47
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/unsaved-changes/index.js
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { select } from '@wordpress/data';
|
||||
import { withEffects } from 'refract-callbag';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { fromSelector } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Toggles the alert if the page has not been saved before reload.
|
||||
*
|
||||
* @return {null}
|
||||
*/
|
||||
function UnsavedChanges() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function aperture() {
|
||||
return fromSelector( select( 'carbon-fields/metaboxes' ).isDirty );
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
function handler() {
|
||||
return function( isDirty ) {
|
||||
if ( ! isDirty ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Support for custom message has been removed
|
||||
// Ref : https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload#Browser_compatibility
|
||||
window.onbeforeunload = ( e ) => e;
|
||||
};
|
||||
}
|
||||
|
||||
export default withEffects( aperture, { handler } )( UnsavedChanges );
|
||||
183
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/widget-handler/index.js
vendored
Normal file
183
web/vendor/htmlburger/carbon-fields/packages/metaboxes/monitors/widget-handler/index.js
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { dispatch, select } from '@wordpress/data';
|
||||
import { unmountComponentAtNode } from '@wordpress/element';
|
||||
import { startsWith, flow } from 'lodash';
|
||||
import { withEffects } from 'refract-callbag';
|
||||
import {
|
||||
map,
|
||||
merge,
|
||||
pipe,
|
||||
filter
|
||||
} from 'callbag-basics';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import urldecode from '../../utils/urldecode';
|
||||
import flattenField from '../../utils/flatten-field';
|
||||
import fromEventPattern from '../../utils/from-event-pattern';
|
||||
import { renderContainer } from '../../containers';
|
||||
import {
|
||||
CARBON_FIELDS_CONTAINER_ID_PREFIX,
|
||||
CARBON_FIELDS_CONTAINER_WIDGET_ID_PREFIX,
|
||||
PAGE_NOW_CUSTOMIZE
|
||||
} from '../../lib/constants';
|
||||
|
||||
/**
|
||||
* Performs the re-initialization of widgets.
|
||||
*
|
||||
* @return {null}
|
||||
*/
|
||||
function WidgetHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the widget is created by Carbon Fields.
|
||||
*
|
||||
* @param {string} identifier
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isCarbonFieldsWidget( identifier ) {
|
||||
return identifier.indexOf( CARBON_FIELDS_CONTAINER_WIDGET_ID_PREFIX ) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that controls the stream of side effects.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function aperture() {
|
||||
return merge(
|
||||
pipe(
|
||||
fromEventPattern(
|
||||
( handler ) => window.jQuery( document ).on( 'widget-added widget-updated', handler ),
|
||||
( handler ) => window.jQuery( document ).off( 'widget-added widget-updated', handler ),
|
||||
( event, $widget ) => ( {
|
||||
event,
|
||||
$widget
|
||||
} )
|
||||
),
|
||||
filter( ( { $widget } ) => {
|
||||
return isCarbonFieldsWidget( $widget[ 0 ].id );
|
||||
} ),
|
||||
map( ( payload ) => ( {
|
||||
type: 'WIDGET_CREATED_OR_UPDATED',
|
||||
payload
|
||||
} ) )
|
||||
),
|
||||
|
||||
pipe(
|
||||
fromEventPattern(
|
||||
( handler ) => window.jQuery( document ).on( 'ajaxSend', handler ),
|
||||
( handler ) => window.jQuery( document ).off( 'ajaxSend', handler ),
|
||||
( event, xhr, options, data ) => ( {
|
||||
event,
|
||||
xhr,
|
||||
options,
|
||||
data
|
||||
} )
|
||||
),
|
||||
filter( ( { options } ) => {
|
||||
return startsWith( options.data, CARBON_FIELDS_CONTAINER_ID_PREFIX );
|
||||
} ),
|
||||
map( ( payload ) => ( {
|
||||
type: 'WIDGET_BEIGN_UPDATED_OR_DELETED',
|
||||
payload
|
||||
} ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that causes the side effects.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
function handler() {
|
||||
return function( effect ) {
|
||||
const { getContainerById } = select( 'carbon-fields/metaboxes' );
|
||||
const {
|
||||
addContainer,
|
||||
removeContainer,
|
||||
addFields,
|
||||
removeFields
|
||||
} = dispatch( 'carbon-fields/metaboxes' );
|
||||
|
||||
switch ( effect.type ) {
|
||||
case 'WIDGET_CREATED_OR_UPDATED': {
|
||||
const { event, $widget } = effect.payload;
|
||||
|
||||
const container = flow(
|
||||
urldecode,
|
||||
JSON.parse
|
||||
)(
|
||||
$widget
|
||||
.find( '[data-json]' )
|
||||
.data( 'json' )
|
||||
);
|
||||
|
||||
const fields = [];
|
||||
|
||||
container.fields = container.fields.map( ( field ) => flattenField( field, container, fields ) );
|
||||
|
||||
addFields( fields );
|
||||
addContainer( container );
|
||||
|
||||
renderContainer( container, 'classic' );
|
||||
|
||||
// WARNING: This piece of code manipulates the core behavior of WordPress Widgets.
|
||||
// Some day this code will stop to work and we'll need to find another workaround.
|
||||
//
|
||||
// * Disable the submit { handler } since it breaks our validation logic.
|
||||
// * Disable live preview mode because we can't detect when the widget is updated/synced.
|
||||
// * Show the "Apply" button because it's hidden by the live mode.
|
||||
if ( window.cf.config.pagenow === PAGE_NOW_CUSTOMIZE && event.type === 'widget-added' ) {
|
||||
const widgetId = $widget
|
||||
.find( '[name="widget-id"]' )
|
||||
.val();
|
||||
|
||||
$widget
|
||||
.find( '[name="savewidget"]' )
|
||||
.show()
|
||||
.end()
|
||||
.find( '.widget-content:first' )
|
||||
.off( 'keydown', 'input' )
|
||||
.off( 'change input propertychange', ':input' );
|
||||
|
||||
const instance = wp.customize.Widgets.getWidgetFormControlForWidget( widgetId );
|
||||
|
||||
// Change the flag for 'live mode' so we can receive proper `widget-updated` events.
|
||||
instance.liveUpdateMode = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'WIDGET_BEIGN_UPDATED_OR_DELETED': {
|
||||
const [ , widgetId ] = effect.payload.options.data.match( /widget-id=(.+?)&/ );
|
||||
|
||||
const containerId = `${ CARBON_FIELDS_CONTAINER_ID_PREFIX }${ widgetId }`;
|
||||
|
||||
// Get the container from the store.
|
||||
const container = getContainerById( containerId );
|
||||
|
||||
// Remove the current instance from DOM.
|
||||
unmountComponentAtNode( document.querySelector( `.container-${ containerId }` ) );
|
||||
|
||||
// Get the fields that belongs to the container.
|
||||
const fieldsIds = _.map( container.fields, 'id' );
|
||||
|
||||
// Remove everything from the store.
|
||||
removeContainer( containerId );
|
||||
removeFields( fieldsIds );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default withEffects( aperture, { handler } )( WidgetHandler );
|
||||
169
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/actions.js
vendored
Normal file
169
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/actions.js
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/**
|
||||
* Returns an action object used to setup the state when first opening an editor.
|
||||
*
|
||||
* @param {Object[]} containers
|
||||
* @param {Object} fields
|
||||
* @return {Object}
|
||||
*/
|
||||
export function setupState( containers, fields ) {
|
||||
return {
|
||||
type: 'SETUP_STATE',
|
||||
payload: {
|
||||
containers,
|
||||
fields
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to update the state.
|
||||
*
|
||||
* @param {Object[]} containers
|
||||
* @param {Object} fields
|
||||
* @return {Object}
|
||||
*/
|
||||
export function updateState( containers, fields ) {
|
||||
return {
|
||||
type: 'UPDATE_STATE',
|
||||
payload: {
|
||||
containers,
|
||||
fields
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to update the field's value.
|
||||
*
|
||||
* @param {string} fieldId
|
||||
* @param {mixed} value
|
||||
* @param {string[]} fieldsToRemove It's used by the complex fields to remove the nested
|
||||
* fields within a single action.
|
||||
* @return {Object}
|
||||
*/
|
||||
export function updateFieldValue( fieldId, value, fieldsToRemove = [] ) {
|
||||
return {
|
||||
type: 'UPDATE_FIELD_VALUE',
|
||||
payload: {
|
||||
fieldId,
|
||||
value,
|
||||
fieldsToRemove
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to add the fields.
|
||||
*
|
||||
* @param {Object[]} fields
|
||||
* @return {Object}
|
||||
*/
|
||||
export function addFields( fields ) {
|
||||
return {
|
||||
type: 'ADD_FIELDS',
|
||||
payload: {
|
||||
fields
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to clone the fields.
|
||||
*
|
||||
* @param {string[]} originFieldIds
|
||||
* @param {string[]} cloneFieldIds
|
||||
* @return {Object}
|
||||
*/
|
||||
export function cloneFields( originFieldIds, cloneFieldIds ) {
|
||||
return {
|
||||
type: 'CLONE_FIELDS',
|
||||
payload: {
|
||||
originFieldIds,
|
||||
cloneFieldIds
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to remove the fields.
|
||||
*
|
||||
* @param {string[]} fieldIds
|
||||
* @return {Object}
|
||||
*/
|
||||
export function removeFields( fieldIds ) {
|
||||
return {
|
||||
type: 'REMOVE_FIELDS',
|
||||
payload: {
|
||||
fieldIds
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to add a container to all containers.
|
||||
*
|
||||
* @param {Object} container
|
||||
* @return {Object}
|
||||
*/
|
||||
export function addContainer( container ) {
|
||||
return {
|
||||
type: 'ADD_CONTAINER',
|
||||
payload: container
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to remove a container from all containers.
|
||||
*
|
||||
* @param {Object} container
|
||||
* @return {Object}
|
||||
*/
|
||||
export function removeContainer( container ) {
|
||||
return {
|
||||
type: 'REMOVE_CONTAINER',
|
||||
payload: container
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to add the created sidebar to all fields.
|
||||
*
|
||||
* @param {Object} sidebar
|
||||
* @return {Object}
|
||||
*/
|
||||
export function receiveSidebar( sidebar ) {
|
||||
return {
|
||||
type: 'RECEIVE_SIDEBAR',
|
||||
payload: sidebar
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to signal that saving is locked.
|
||||
*
|
||||
* @param {string} lockName
|
||||
* @return {Object}
|
||||
*/
|
||||
export function lockSaving( lockName ) {
|
||||
return {
|
||||
type: 'LOCK_SAVING',
|
||||
payload: {
|
||||
lockName
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action object used to signal that saving is unlocked.
|
||||
*
|
||||
* @param {string} lockName
|
||||
* @return {Object}
|
||||
*/
|
||||
export function unlockSaving( lockName ) {
|
||||
return {
|
||||
type: 'UNLOCK_SAVING',
|
||||
payload: {
|
||||
lockName
|
||||
}
|
||||
};
|
||||
}
|
||||
28
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/helpers.js
vendored
Normal file
28
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/helpers.js
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { assign, endsWith } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import flattenField from '../utils/flatten-field';
|
||||
|
||||
/**
|
||||
* Transform the shape of the given state to be more Redux friendly.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @return {Object}
|
||||
*/
|
||||
export function normalizePreloadedState( state ) {
|
||||
const fields = [];
|
||||
const containers = state
|
||||
.filter( ( { id } ) => ! endsWith( id, '__i__' ) )
|
||||
.map( ( container ) => {
|
||||
return assign( {}, container, {
|
||||
fields: container.fields.map( ( field ) => flattenField( field, container.id, fields ) )
|
||||
} );
|
||||
} );
|
||||
|
||||
return { containers, fields };
|
||||
}
|
||||
35
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/index.js
vendored
Normal file
35
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/index.js
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { registerStore, dispatch } from '@wordpress/data';
|
||||
import {
|
||||
get,
|
||||
keyBy
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies.
|
||||
*/
|
||||
import reducer from './reducer';
|
||||
import * as actions from './actions';
|
||||
import * as selectors from './selectors';
|
||||
import { normalizePreloadedState } from './helpers';
|
||||
|
||||
/**
|
||||
* Register the store.
|
||||
*/
|
||||
registerStore( 'carbon-fields/metaboxes', {
|
||||
reducer,
|
||||
actions,
|
||||
selectors
|
||||
} );
|
||||
|
||||
/**
|
||||
* Hydrate the store's state.
|
||||
*/
|
||||
const { containers, fields } = normalizePreloadedState( get( window.cf, 'preloaded.containers', [] ) );
|
||||
|
||||
dispatch( 'carbon-fields/metaboxes' ).setupState(
|
||||
keyBy( containers, 'id' ),
|
||||
keyBy( fields, 'id' )
|
||||
);
|
||||
247
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/reducer.js
vendored
Normal file
247
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/reducer.js
vendored
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import produce from 'immer';
|
||||
import { combineReducers } from '@wordpress/data';
|
||||
import {
|
||||
omit,
|
||||
keyBy,
|
||||
assign,
|
||||
forEach,
|
||||
cloneDeep,
|
||||
values,
|
||||
unset
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { uniqueId } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* The reducer that keeps track of the containers.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {Object} action
|
||||
* @return {Object}
|
||||
*/
|
||||
export function containers( state = {}, action ) {
|
||||
switch ( action.type ) {
|
||||
case 'SETUP_STATE':
|
||||
return action.payload.containers;
|
||||
|
||||
case 'UPDATE_STATE':
|
||||
return produce( state, ( draft ) => {
|
||||
values( action.payload.containers ).forEach( ( container ) => {
|
||||
draft[ container.id ] = container;
|
||||
} );
|
||||
} );
|
||||
|
||||
case 'ADD_CONTAINER':
|
||||
return produce( state, ( draft ) => {
|
||||
draft[ action.payload.id ] = action.payload;
|
||||
} );
|
||||
|
||||
case 'REMOVE_CONTAINER':
|
||||
return omit( state, action.payload );
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones a field.
|
||||
*
|
||||
* @param {string} originId
|
||||
* @param {string} cloneId
|
||||
* @param {Object} fields
|
||||
* @param {Object[]} accumulator
|
||||
* @return {Object[]}
|
||||
*/
|
||||
function cloneField( originId, cloneId, fields, accumulator ) {
|
||||
const field = cloneDeep( fields[ originId ] );
|
||||
|
||||
field.id = cloneId;
|
||||
|
||||
if ( field.type === 'complex' ) {
|
||||
field.value.forEach( ( group ) => {
|
||||
group.id = uniqueId();
|
||||
|
||||
accumulator = group.fields.reduce( ( groupAccumulator, groupField ) => {
|
||||
const originGroupFieldId = groupField.id;
|
||||
const cloneGroupFieldId = uniqueId();
|
||||
|
||||
groupField.id = cloneGroupFieldId;
|
||||
|
||||
return cloneField( originGroupFieldId, cloneGroupFieldId, fields, groupAccumulator );
|
||||
}, accumulator );
|
||||
} );
|
||||
}
|
||||
|
||||
return accumulator.concat( field );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of field ids by a given root id.
|
||||
*
|
||||
* @param {string} fieldId
|
||||
* @param {Object} fields
|
||||
* @param {string[]} accumulator
|
||||
* @return {string[]}
|
||||
*/
|
||||
function getFieldIdsByRootId( fieldId, fields, accumulator ) {
|
||||
const field = fields[ fieldId ];
|
||||
|
||||
if ( field.type === 'complex' ) {
|
||||
field.value.forEach( ( group ) => {
|
||||
accumulator = group.fields.reduce( ( groupAccumulator, groupField ) => {
|
||||
return getFieldIdsByRootId( groupField.id, fields, groupAccumulator );
|
||||
}, accumulator );
|
||||
} );
|
||||
}
|
||||
|
||||
return accumulator.concat( fieldId );
|
||||
}
|
||||
|
||||
/**
|
||||
* The reducer that keeps track of the fields.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {Object} action
|
||||
* @return {Object}
|
||||
*/
|
||||
export function fields( state = {}, action ) {
|
||||
switch ( action.type ) {
|
||||
case 'SETUP_STATE':
|
||||
return action.payload.fields;
|
||||
|
||||
case 'UPDATE_STATE':
|
||||
return produce( state, ( draft ) => {
|
||||
values( action.payload.fields ).forEach( ( field ) => {
|
||||
draft[ field.id ] = field;
|
||||
} );
|
||||
} );
|
||||
|
||||
case 'UPDATE_FIELD_VALUE':
|
||||
return produce( state, ( draft ) => {
|
||||
const {
|
||||
fieldId,
|
||||
value,
|
||||
fieldsToRemove
|
||||
} = action.payload;
|
||||
|
||||
draft[ fieldId ].value = value;
|
||||
|
||||
const fieldIdsToRemove = fieldsToRemove.reduce( ( accumulator, fieldIdToRemove ) => {
|
||||
return getFieldIdsByRootId( fieldIdToRemove, state, accumulator );
|
||||
}, [] );
|
||||
|
||||
fieldIdsToRemove.forEach( ( fieldIdToRemove ) => {
|
||||
unset( draft, fieldIdToRemove );
|
||||
} );
|
||||
} );
|
||||
|
||||
case 'ADD_FIELDS':
|
||||
return produce( state, ( draft ) => {
|
||||
action.payload.fields.forEach( ( field ) => {
|
||||
draft[ field.id ] = field;
|
||||
} );
|
||||
} );
|
||||
|
||||
case 'CLONE_FIELDS':
|
||||
return produce( state, ( draft ) => {
|
||||
const { originFieldIds, cloneFieldIds } = action.payload;
|
||||
|
||||
const clonedFields = originFieldIds.reduce( ( accumulator, originFieldId, index ) => {
|
||||
return cloneField( originFieldId, cloneFieldIds[ index ], draft, accumulator );
|
||||
}, [] );
|
||||
|
||||
assign( draft, keyBy( clonedFields, 'id' ) );
|
||||
} );
|
||||
|
||||
case 'REMOVE_FIELDS':
|
||||
const fieldIds = action.payload.fieldIds.reduce( ( accumulator, fieldId ) => {
|
||||
return getFieldIdsByRootId( fieldId, state, accumulator );
|
||||
}, [] );
|
||||
|
||||
return omit( state, fieldIds );
|
||||
|
||||
case 'RECEIVE_SIDEBAR':
|
||||
return produce( state, ( draft ) => {
|
||||
forEach( draft, ( field ) => {
|
||||
if ( field.type === 'sidebar' ) {
|
||||
field.options.unshift( action.payload );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The reducer that keeps track of the save locks.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {Object} action
|
||||
* @return {Object}
|
||||
*/
|
||||
export function savingLock( state = {}, action ) {
|
||||
switch ( action.type ) {
|
||||
case 'LOCK_SAVING':
|
||||
return {
|
||||
...state,
|
||||
[ action.payload.lockName ]: true
|
||||
};
|
||||
|
||||
case 'UNLOCK_SAVING':
|
||||
return omit( state, [ action.payload.lockName ] );
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The reducer that keeps track if there is dirty fields.
|
||||
*
|
||||
* @param {boolean} state
|
||||
* @param {Object} action
|
||||
* @return {Object}
|
||||
*/
|
||||
export function isDirty( state = false, action ) {
|
||||
switch ( action.type ) {
|
||||
case 'UPDATE_FIELD_VALUE':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The reducer that keeps track if an update is being made.
|
||||
*
|
||||
* @param {boolean} state
|
||||
* @param {Object} action
|
||||
* @return {Object}
|
||||
*/
|
||||
export function isFieldUpdated( state, action ) {
|
||||
switch ( action.type ) {
|
||||
case 'UPDATE_FIELD_VALUE':
|
||||
return { action };
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default combineReducers( {
|
||||
containers,
|
||||
fields,
|
||||
savingLock,
|
||||
isDirty,
|
||||
isFieldUpdated
|
||||
} );
|
||||
108
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/selectors.js
vendored
Normal file
108
web/vendor/htmlburger/carbon-fields/packages/metaboxes/store/selectors.js
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import {
|
||||
filter,
|
||||
pick,
|
||||
mapValues,
|
||||
mapKeys
|
||||
} from 'lodash';
|
||||
|
||||
/**
|
||||
* Returns the containers.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @return {Object[]}
|
||||
*/
|
||||
export function getContainers( state ) {
|
||||
return state.containers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a container by an id.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {string} containerId
|
||||
* @return {?Object}
|
||||
*/
|
||||
export function getContainerById( state, containerId ) {
|
||||
return state.containers[ containerId ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @return {Object}
|
||||
*/
|
||||
export function getFields( state ) {
|
||||
return state.fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields that belong to the specified container.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {string} containerId
|
||||
* @return {Object[]}
|
||||
*/
|
||||
export function getFieldsByContainerId( state, containerId ) {
|
||||
return filter( state.fields, [ 'container_id', containerId ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a field by an id.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {string} fieldId
|
||||
* @return {?Object}
|
||||
*/
|
||||
export function getFieldById( state, fieldId ) {
|
||||
return state.fields[ fieldId ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether saving is locked.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isSavingLocked( state ) {
|
||||
return Object.keys( state.savingLock ).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the metaboxes fields contain unsaved changed.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isDirty( state ) {
|
||||
return state.isDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the metaboxes fields contain unsaved changed.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isFieldUpdated( state ) {
|
||||
return state.isFieldUpdated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of field values for a given group.
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {string[]} fieldIds
|
||||
* @return {Object}
|
||||
*/
|
||||
export function getComplexGroupValues( state, fieldIds ) {
|
||||
let fields = pick( getFields( state ), fieldIds );
|
||||
|
||||
fields = mapKeys( fields, ( field ) => field.base_name.replace( /\-/g, '_' ) );
|
||||
fields = mapValues( fields, ( field ) => field.value );
|
||||
|
||||
return fields;
|
||||
}
|
||||
46
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/flatten-field.js
vendored
Normal file
46
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/flatten-field.js
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { pick, cloneDeep } from 'lodash';
|
||||
|
||||
/**
|
||||
* Carbon Fields dependencies.
|
||||
*/
|
||||
import { uniqueId } from '@carbon-fields/core';
|
||||
|
||||
/**
|
||||
* Flattens a field.
|
||||
*
|
||||
* @param {Object} field
|
||||
* @param {string} containerId
|
||||
* @param {Object[]} accumulator
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function flattenField( field, containerId, accumulator ) {
|
||||
field = cloneDeep( field );
|
||||
|
||||
// Replace the id of the field.
|
||||
field.id = uniqueId();
|
||||
|
||||
// Keep reference to the container.
|
||||
field.container_id = containerId;
|
||||
|
||||
// The complex fields represent a nested structure of fields.
|
||||
// So we need to flat them as well.
|
||||
if ( field.type === 'complex' ) {
|
||||
field.value.forEach( ( group ) => {
|
||||
group.id = uniqueId();
|
||||
group.container_id = containerId;
|
||||
group.fields = group.fields.map( ( groupField ) => flattenField( groupField, containerId, accumulator ) );
|
||||
} );
|
||||
}
|
||||
|
||||
accumulator.push( field );
|
||||
|
||||
return pick( field, [
|
||||
'id',
|
||||
'type',
|
||||
'name',
|
||||
'base_name'
|
||||
] );
|
||||
}
|
||||
23
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/from-event-pattern.js
vendored
Normal file
23
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/from-event-pattern.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import create from 'callbag-create';
|
||||
|
||||
/**
|
||||
* Callbag source factory from `addHandler` and `removeHandler` pair.
|
||||
*
|
||||
* @see https://github.com/Andarist/callbag-from-event-pattern
|
||||
* @param {Function} addHandler
|
||||
* @param {Function} removeHandler
|
||||
* @param {Function} argsTransformer
|
||||
* @return {Function}
|
||||
*/
|
||||
export default function fromEventPattern( addHandler, removeHandler, argsTransformer = ( ...args ) => args ) {
|
||||
return create( ( sink ) => {
|
||||
const handler = ( ...args ) => sink( 1, argsTransformer( ...args ) );
|
||||
|
||||
addHandler( handler );
|
||||
|
||||
return () => removeHandler( handler );
|
||||
} );
|
||||
}
|
||||
13
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/is-gutenberg.js
vendored
Normal file
13
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/is-gutenberg.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { isUndefined } from 'lodash';
|
||||
|
||||
/**
|
||||
* Returns true if Gutenberg is presented.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
export default function isGutenberg() {
|
||||
return ! isUndefined( window._wpLoadBlockEditor );
|
||||
}
|
||||
15
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/strip-compact-input-prefix.js
vendored
Normal file
15
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/strip-compact-input-prefix.js
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Removes the prefix used to compact the input of Carbon Fields.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {string}
|
||||
*/
|
||||
export default function stripCompactInputPrefix( str ) {
|
||||
const { compactInput, compactInputKey } = window.cf.config;
|
||||
|
||||
if ( ! compactInput || str.indexOf( compactInputKey ) !== 0 ) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return str.replace( new RegExp( `^${ compactInputKey }\\[(.+?)\\]` ), '$1' );
|
||||
}
|
||||
16
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/urldecode.js
vendored
Normal file
16
web/vendor/htmlburger/carbon-fields/packages/metaboxes/utils/urldecode.js
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Source: https://github.com/kvz/locutus/blob/master/src/php/url/urldecode.js
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {string}
|
||||
*/
|
||||
export default function urldecode( str ) {
|
||||
return decodeURIComponent( ( str + '' )
|
||||
.replace( /%(?![\da-f]{2})/gi, function() {
|
||||
// PHP tolerates poorly formed escape sequences
|
||||
return '%25';
|
||||
} )
|
||||
|
||||
.replace( /\+/g, '%20' )
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue