Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1 @@
.wp-block-rank-math-toc-block nav li,.wp-block-rank-math-toc-block nav div{position:relative;min-height:28px;margin-bottom:0}.wp-block-rank-math-toc-block nav li.disabled,.wp-block-rank-math-toc-block nav div.disabled{display:block !important;opacity:0.5}.wp-block-rank-math-toc-block nav li .components-base-control,.wp-block-rank-math-toc-block nav div .components-base-control{position:absolute;top:2px;left:-4px;right:-3px}.wp-block-rank-math-toc-block nav li .rank-math-block-actions,.wp-block-rank-math-toc-block nav div .rank-math-block-actions{position:absolute;top:1px;right:0;display:none;line-height:1}.wp-block-rank-math-toc-block nav li .rank-math-block-actions button.components-button,.wp-block-rank-math-toc-block nav div .rank-math-block-actions button.components-button{min-width:24px;width:24px;height:24px;line-height:34px}.wp-block-rank-math-toc-block nav li:hover .rank-math-block-actions,.wp-block-rank-math-toc-block nav li:focus .rank-math-block-actions,.wp-block-rank-math-toc-block nav li .components-base-control+.rank-math-block-actions .rank-math-block-actions,.wp-block-rank-math-toc-block nav div:hover .rank-math-block-actions,.wp-block-rank-math-toc-block nav div:focus .rank-math-block-actions,.wp-block-rank-math-toc-block nav div .components-base-control+.rank-math-block-actions .rank-math-block-actions{display:block}.rank-math-toc-exclude-headings{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.rank-math-toc-exclude-headings>div{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;margin-bottom:10px !important}

View File

@@ -0,0 +1 @@
.wp-block-rank-math-toc-block nav ol{counter-reset:item}.wp-block-rank-math-toc-block nav ol li{display:block}.wp-block-rank-math-toc-block nav ol li:before{content:counters(item, ".") ". ";counter-increment:item}

View File

@@ -0,0 +1,25 @@
<?php
/**
* Block script dependencies.
*
* @package RankMath
* @subpackage RankMath\Schema
* @author Rank Math <support@rankmath.com>
*/
return [
'dependencies' => [
'wp-blocks',
'wp-element',
'wp-components',
'wp-block-editor',
'wp-data',
'wp-dom',
'wp-url',
'wp-i18n',
'lodash',
'wp-primitives',
'wp-reusable-blocks',
],
'version' => rank_math()->version,
];

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,52 @@
.wp-block-rank-math-toc-block {
nav {
li, div {
position: relative;
min-height: 28px;
margin-bottom: 0;
&.disabled {
display: block !important;
opacity: 0.5;
}
.components-base-control {
position: absolute;
top: 2px;
left: -4px;
right: -3px;
}
.rank-math-block-actions {
position: absolute;
top: 1px;
right: 0;
display: none;
line-height: 1;
button.components-button {
min-width: 24px;
width: 24px;
height: 24px;
line-height: 34px;
}
}
&:hover, &:focus, .components-base-control + .rank-math-block-actions {
.rank-math-block-actions {
display: block;
}
}
}
}
}
.rank-math-toc-exclude-headings {
display: flex;
flex-wrap: wrap;
> div {
flex: 0 0 50%;
margin-bottom: 10px!important;
}
}

View File

@@ -0,0 +1,17 @@
.wp-block-rank-math-toc-block {
nav {
ol {
counter-reset: item;
li {
display: block;
}
li:before {
content: counters(item, ".") ". ";
counter-increment: item;
}
}
}
}

View File

@@ -0,0 +1,55 @@
import { linearToNestedHeadingList } from './utils'
import { useBlockProps } from '@wordpress/block-editor'
import List from './list'
const attributes = {
title: {
type: 'text',
},
headings: {
type: 'array',
items: {
type: 'object',
},
},
listStyle: {
type: 'text',
},
titleWrapper: {
type: 'text',
default: 'h2',
},
excludeHeadings: {
type: 'array',
},
}
const v1 = {
attributes,
save( { attributes } ) {
if ( attributes.headings.length === 0 ) {
return null
}
const TitleWrapper = attributes.titleWrapper
const headings = linearToNestedHeadingList( attributes.headings )
const ListStyle = attributes.listStyle
return (
<div { ...useBlockProps.save() }>
{ attributes.title && <TitleWrapper dangerouslySetInnerHTML={ { __html: attributes.title } }></TitleWrapper> }
<nav>
<ListStyle>
<List
headings={ headings }
ListStyle={ ListStyle }
isSave={ true }
/>
</ListStyle>
</nav>
</div>
)
},
}
export default [ v1 ]

View File

@@ -0,0 +1,138 @@
/**
* External dependencies
*/
import { isUndefined, map, includes, remove } from 'lodash'
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n'
import {
useBlockProps,
RichText,
store as blockEditorStore,
} from '@wordpress/block-editor'
import { useDispatch } from '@wordpress/data'
import { Placeholder } from '@wordpress/components'
import { useEffect, useState } from '@wordpress/element'
/**
* Internal dependencies
*/
import { GetLatestHeadings, linearToNestedHeadingList } from './utils'
import List from './list'
import InspectControls from './inspectControls'
import Toolbar from './toolbar'
export default ( {
attributes,
setAttributes,
} ) => {
const blockProps = useBlockProps()
// State to monitor edit heading links.
const [ edit, toggleEdit ] = useState( false )
const [ excludeHeading, toggleExcludeHeading ] = useState( {} )
if ( ! attributes.listStyle ) {
setAttributes( { listStyle: rankMath.listStyle } )
}
const ListStyle = attributes.listStyle
const tocTitle = attributes.title ?? rankMath.tocTitle
const excludeHeadings = ! isUndefined( attributes.excludeHeadings ) ? attributes.excludeHeadings : rankMath.tocExcludeHeadings
// Function to hide certain heading.
const hideHeading = ( value, key ) => {
const headings = map( attributes.headings, ( heading ) => {
if ( heading.key === key ) {
heading.disable = value
}
return heading
} )
setAttributes( { headings } )
}
// Function to update Heading link.
const onHeadingUpdate = ( value, key, isContent = false ) => {
const headings = map( attributes.headings, ( heading ) => {
if ( heading.key === key ) {
if ( isContent ) {
heading.content = value
heading.isUpdated = true
} else {
heading.isGeneratedLink = false
heading.link = value
}
}
return heading
} )
setAttributes( { headings } )
}
const setExcludeHeadings = ( headingLevel ) => {
if ( includes( excludeHeadings, headingLevel ) ) {
remove( excludeHeadings, ( heading ) => {
return heading === headingLevel
} )
} else {
excludeHeadings.push( headingLevel )
}
setAttributes( { excludeHeadings } )
toggleExcludeHeading( ! excludeHeading )
}
const { __unstableMarkNextChangeAsNotPersistent } = useDispatch( blockEditorStore )
// Get Latest headings from the content.
const latestHeadings = GetLatestHeadings( attributes.headings, excludeHeadings )
useEffect( () => {
if ( latestHeadings !== null ) {
__unstableMarkNextChangeAsNotPersistent();
setAttributes( { headings: latestHeadings } )
}
}, [ latestHeadings ] )
const headingTree = linearToNestedHeadingList( attributes.headings )
if ( isUndefined( attributes.headings ) || attributes.headings.length === 0 ) {
return (
<div { ...blockProps }>
<Placeholder
label={ __( 'Table of Contents', 'rank-math' ) }
instructions={ __( 'Add Heading blocks to this page to generate the Table of Contents.', 'rank-math' ) }
/>
<InspectControls attributes={ attributes } setAttributes={ setAttributes } excludeHeadings={ excludeHeadings } setExcludeHeadings={ setExcludeHeadings } />
</div>
)
}
return (
<div { ...blockProps }>
<RichText
tagName={ attributes.titleWrapper }
value={ tocTitle }
onChange={ ( newTitle ) => {
setAttributes( { title: newTitle } )
} }
placeholder={ __( 'Enter a title', 'rank-math' ) }
/>
<nav>
<ListStyle>
<List
headings={ headingTree }
onHeadingUpdate={ onHeadingUpdate }
edit={ edit }
toggleEdit={ toggleEdit }
hideHeading={ hideHeading }
ListStyle={ ListStyle }
/>
</ListStyle>
</nav>
<Toolbar setAttributes={ setAttributes } />
<InspectControls attributes={ attributes } setAttributes={ setAttributes } excludeHeadings={ excludeHeadings } setExcludeHeadings={ setExcludeHeadings } />
</div>
)
}

View File

@@ -0,0 +1,23 @@
/**
* WordPress dependencies
*/
import { registerBlockType } from '@wordpress/blocks'
/**
* Internal dependencies
*/
import edit from './edit'
import save from './save'
import deprecated from './deprecated'
/**
* Register TOC block
*/
registerBlockType(
'rank-math/toc-block',
{
edit,
save,
deprecated,
}
)

View File

@@ -0,0 +1,58 @@
/**
* External dependencies
*/
import { map, includes, toUpper } from 'lodash'
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n'
import { InspectorControls } from '@wordpress/block-editor'
import {
PanelBody,
SelectControl,
CheckboxControl,
} from '@wordpress/components'
export default ( { attributes, setAttributes, excludeHeadings, setExcludeHeadings } ) => {
return (
<InspectorControls>
<PanelBody title={ __( 'Settings', 'rank-math' ) }>
<SelectControl
label={ __( 'Title Wrapper', 'rank-math' ) }
value={ attributes.titleWrapper }
options={ [
{ value: 'h2', label: __( 'H2', 'rank-math' ) },
{ value: 'h3', label: __( 'H3', 'rank-math' ) },
{ value: 'h4', label: __( 'H4', 'rank-math' ) },
{ value: 'h5', label: __( 'H5', 'rank-math' ) },
{ value: 'h6', label: __( 'H6', 'rank-math' ) },
{ value: 'p', label: __( 'P', 'rank-math' ) },
{ value: 'div', label: __( 'DIV', 'rank-math' ) },
] }
onChange={ ( titleWrapper ) => {
setAttributes( { titleWrapper } )
} }
/>
<br />
<h3>{ __( 'Exclude Headings', 'rank-math' ) }</h3>
<div className="rank-math-toc-exclude-headings">
{
map( [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ], ( value ) => {
return (
<CheckboxControl
key={ value }
label={ __( 'Heading ', 'rank-math' ) + toUpper( value ) }
checked={ includes( excludeHeadings, value ) }
onChange={ ( newVlaue ) => setExcludeHeadings( value, newVlaue ) }
/>
)
} )
}
</div>
</PanelBody>
</InspectorControls>
)
}

View File

@@ -0,0 +1,90 @@
/**
* External dependencies
*/
import { isEmpty } from 'lodash'
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n'
import { Button, TextControl } from '@wordpress/components'
import { RichText } from '@wordpress/block-editor'
export default function List( { headings = {}, onHeadingUpdate = {}, edit = {}, toggleEdit = {}, hideHeading = {}, ListStyle = 'ul', isSave = false } ) {
if ( isEmpty( headings ) ) {
return null
}
return (
<>
{ headings.map( ( heading ) => {
if ( isSave && heading.heading.disable ) {
return false
}
const { content, link, disable, key } = heading.heading
const TagName = 'div' === ListStyle ? 'div' : 'li'
return (
<TagName key={ key } className={ disable ? 'disabled' : '' }>
{
isSave &&
<a href={ link }>
{ content }
</a>
}
{
! isSave &&
<RichText
tagName="a"
value={ content }
allowedFormats={ [] }
onChange={ ( newContent ) => onHeadingUpdate( newContent, key, true ) }
placeholder={ __( 'Heading text', 'rank-math' ) }
/>
}
{
heading.children &&
<ListStyle>
<List
headings={ heading.children }
onHeadingUpdate={ onHeadingUpdate }
edit={ edit }
toggleEdit={ toggleEdit }
hideHeading={ hideHeading }
ListStyle={ ListStyle }
isSave={ isSave }
/>
</ListStyle>
}
{
key === edit &&
<TextControl
placeholder={ __( 'Heading Link', 'rank-math' ) }
value={ link }
onChange={ ( newLink ) => onHeadingUpdate( newLink, key ) }
/>
}
{
! isSave &&
<span className="rank-math-block-actions">
<Button
icon={ edit === key ? 'saved' : 'admin-links' }
className="rank-math-item-visbility"
onClick={ () => toggleEdit( edit === key ? false : key ) }
title={ __( 'Edit Link', 'rank-math' ) }
/>
<Button
className="rank-math-item-delete"
icon={ ! disable ? 'visibility' : 'hidden' }
onClick={ () => hideHeading( ! disable, key ) }
title={ __( 'Hide', 'rank-math' ) }
/>
</span>
}
</TagName>
)
} ) }
</>
)
}

View File

@@ -0,0 +1,40 @@
/**
* External dependencies
*/
import { isUndefined } from 'lodash'
/**
* WordPress dependencies
*/
import { useBlockProps } from '@wordpress/block-editor'
/**
* Internal dependencies
*/
import { linearToNestedHeadingList } from './utils'
import List from './list'
export default function save( { attributes } ) {
if ( isUndefined( attributes.headings ) || attributes.headings.length === 0 ) {
return null
}
const TitleWrapper = attributes.titleWrapper
const headings = linearToNestedHeadingList( attributes.headings )
const ListStyle = attributes.listStyle
return (
<div { ...useBlockProps.save() } id="rank-math-toc">
{ attributes.title && <TitleWrapper dangerouslySetInnerHTML={ { __html: attributes.title } }></TitleWrapper> }
<nav>
<ListStyle>
<List
headings={ headings }
ListStyle={ ListStyle }
isSave={ true }
/>
</ListStyle>
</nav>
</div>
)
}

View File

@@ -0,0 +1,34 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n'
import { BlockControls } from '@wordpress/block-editor'
import {
Toolbar,
ToolbarButton,
} from '@wordpress/components'
import { formatListBullets, formatListNumbered, alignLeft } from '@wordpress/icons'
export default ( { setAttributes } ) => {
return (
<BlockControls>
<Toolbar label={ __( 'Table of Content Options', 'rank-math' ) }>
<ToolbarButton
icon={ formatListBullets }
label={ __( 'Unordered List', 'rank-math' ) }
onClick={ () => setAttributes( { listStyle: 'ul' } ) }
/>
<ToolbarButton
icon={ formatListNumbered }
label={ __( 'Ordered List', 'rank-math' ) }
onClick={ () => setAttributes( { listStyle: 'ol' } ) }
/>
<ToolbarButton
icon={ alignLeft }
label={ __( 'None', 'rank-math' ) }
onClick={ () => setAttributes( { listStyle: 'div' } ) }
/>
</Toolbar>
</BlockControls>
)
}

View File

@@ -0,0 +1,196 @@
/**
* External dependencies
*/
import { isEmpty, isUndefined, isString, kebabCase, includes, forEach, isEqual, map, isNull } from 'lodash'
/**
* WordPress dependencies
*/
import { store as blockEditorStore } from '@wordpress/block-editor'
import { __unstableStripHTML as stripHTML } from '@wordpress/dom'
import { useSelect, useDispatch } from '@wordpress/data'
/**
* Get the headings from the content.
*
* @param {Array} headings Array of headings data
* @param {Array} excludeHeadings Heading levels to exclude
*/
export function GetLatestHeadings( headings, excludeHeadings ) {
return useSelect(
( select ) => {
const {
getBlockAttributes,
getBlockName,
getClientIdsWithDescendants,
} = select( blockEditorStore )
const { __experimentalConvertBlockToStatic: convertBlockToStatic } = useDispatch( 'core/reusable-blocks' )
// Get the client ids of all blocks in the editor.
const allBlockClientIds = getClientIdsWithDescendants()
const _latestHeadings = []
let i = 0
const anchors = []
for ( const blockClientId of allBlockClientIds ) {
const blockName = getBlockName( blockClientId )
if ( blockName === 'core/block' ) {
const attrs = getBlockAttributes( blockClientId )
if ( ! isNull( attrs.ref ) ) {
const reusableBlock = wp.data.select( 'core' ).getEditedEntityRecord( 'postType', 'wp_block', attrs.ref )
const blocks = map( reusableBlock.blocks, ( block ) => {
return block.name
} )
if ( includes( blocks, 'rank-math/toc-block' ) && ! isNull( getBlockAttributes( blockClientId ) ) ) {
convertBlockToStatic( blockClientId )
}
}
continue
}
if ( ! includes( [ 'rank-math/faq-block', 'rank-math/howto-block', 'core/heading' ], blockName ) ) {
continue
}
const headingAttributes = getBlockAttributes( blockClientId )
if ( blockName === 'rank-math/faq-block' || blockName === 'rank-math/howto-block' ) {
const titleWrapper = headingAttributes.titleWrapper
if (
includes( excludeHeadings, titleWrapper ) ||
includes( [ 'div', 'p' ], titleWrapper )
) {
continue
}
const data = blockName === 'rank-math/howto-block' ? headingAttributes.steps : headingAttributes.questions
if ( isEmpty( data ) ) {
continue
}
forEach( data, ( value ) => {
const currentHeading = ! isUndefined( headings ) && ! isEmpty( headings[ _latestHeadings.length ] ) ? headings[ _latestHeadings.length ] : {
content: '',
level: '',
disable: false,
isUpdated: false,
isGeneratedLink: true,
}
const isGeneratedLink = ! isUndefined( currentHeading.isGeneratedLink ) && currentHeading.isGeneratedLink
const content = ! isUndefined( currentHeading.isUpdated ) && currentHeading.isUpdated ? currentHeading.content : value.title
_latestHeadings.push( {
key: value.id,
content: stripHTML( content ),
level: parseInt( headingAttributes.titleWrapper.replace( 'h', '' ) ),
link: ! isGeneratedLink ? currentHeading.link : `#${ value.id }`,
disable: currentHeading.disable ? currentHeading.disable : false,
isUpdated: ! isUndefined( currentHeading.isUpdated ) ? currentHeading.isUpdated : false,
isGeneratedLink,
} )
} )
continue
}
if ( blockName === 'core/heading' ) {
if ( includes( excludeHeadings, 'h' + headingAttributes.level ) ) {
continue
}
const currentHeading = ! isUndefined( headings ) && ! isEmpty( headings[ _latestHeadings.length ] ) ? headings[ _latestHeadings.length ] : {
content: '',
level: '',
disable: false,
isUpdated: false,
isGeneratedLink: true,
}
const isGeneratedLink = ! isUndefined( currentHeading.isGeneratedLink ) && currentHeading.isGeneratedLink
let anchor = headingAttributes.anchor
const headingText = ! isEmpty( headingAttributes.content.text ) ? headingAttributes.content.text : headingAttributes.content
if ( isEmpty( headingAttributes.anchor ) || isGeneratedLink ) {
anchor = kebabCase( stripHTML( headingText ) )
}
if ( includes( anchors, anchor ) ) {
i += 1
anchor = anchor + '-' + i
}
anchors.push( anchor )
headingAttributes.anchor = anchor
const headingContent = isString( headingText ) ? stripHTML(
headingText.replace(
/(<br *\/?>)+/g,
' '
)
) : ''
const content = ! isUndefined( currentHeading.isUpdated ) && currentHeading.isUpdated ? currentHeading.content : headingContent
_latestHeadings.push( {
key: blockClientId,
content: stripHTML( content ),
level: headingAttributes.level,
link: ! isGeneratedLink ? currentHeading.link : `#${ headingAttributes.anchor }`,
disable: currentHeading.disable ? currentHeading.disable : false,
isUpdated: ! isUndefined( currentHeading.isUpdated ) ? currentHeading.isUpdated : false,
isGeneratedLink,
} )
}
}
if ( isEqual( headings, _latestHeadings ) ) {
return null
}
return _latestHeadings
}
)
}
/**
* Nest heading based on the Heading level.
*
* @param {Array} headingList The flat list of headings to nest.
*
* @return {Array} The nested list of headings.
*/
export function linearToNestedHeadingList( headingList = [] ) {
const nestedHeadingList = []
forEach( headingList, ( heading, key ) => {
if ( isEmpty( heading.content ) ) {
return
}
// Make sure we are only working with the same level as the first iteration in our set.
if ( heading.level === headingList[ 0 ].level ) {
if ( headingList[ key + 1 ]?.level > heading.level ) {
let endOfSlice = headingList.length
for ( let i = key + 1; i < headingList.length; i++ ) {
if ( headingList[ i ].level === heading.level ) {
endOfSlice = i
break
}
}
nestedHeadingList.push( {
heading,
children: linearToNestedHeadingList(
headingList.slice( key + 1, endOfSlice )
),
} )
} else {
nestedHeadingList.push( {
heading,
children: null,
} )
}
}
} )
return nestedHeadingList
}