Skip to content

Commit

Permalink
Changed the relative link to wp:theme-file-uris
Browse files Browse the repository at this point in the history
Always adding path to the link object so that it can dynamically resolved.
  • Loading branch information
ramonjd committed May 13, 2024
1 parent de9cd47 commit 2eb8219
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 44 deletions.
8 changes: 6 additions & 2 deletions lib/class-wp-rest-global-styles-controller-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ public function prepare_item_for_response( $post, $request ) { // phpcs:ignore V
if ( $is_global_styles_user_theme_json ) {
$resolved_theme_uris = WP_Theme_JSON_Resolver_Gutenberg::get_resolved_theme_uris( $theme_json );
if ( ! empty( $resolved_theme_uris ) ) {
$links['theme_file_uris'] = $resolved_theme_uris;
$links['wp:theme-file-uris'] = $resolved_theme_uris;
}
}
$response->add_links( $links );
Expand Down Expand Up @@ -642,7 +642,11 @@ public function get_theme_item( $request ) {
);
$resolved_theme_uris = WP_Theme_JSON_Resolver_Gutenberg::get_resolved_theme_uris( $theme );
if ( ! empty( $resolved_theme_uris ) ) {
$links['theme_file_uris'] = $resolved_theme_uris;
/*
* @TODO this needs to be added to the WP REST API schema.
* E.g., $links['https://api.w.org/theme-file-uris'].
*/
$links['wp:theme-file-uris'] = $resolved_theme_uris;
}

$response->add_links( $links );
Expand Down
20 changes: 6 additions & 14 deletions lib/class-wp-theme-json-resolver-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ public static function get_style_variations() {
$variation['title'] = basename( $path, '.json' );
}
if ( ! empty( $resolved_theme_uris ) ) {
$variation['_links']['theme_file_uris'] = $resolved_theme_uris;
$variation['_links']['wp:theme-file-uris'] = $resolved_theme_uris;
}
$variations[] = $variation;
}
Expand All @@ -775,9 +775,8 @@ public static function get_style_variations() {
*
* @param WP_Theme_JSON_Gutenberg $theme_json A theme json instance.
* @return array An array of resolved paths.
* @return array Options.
*/
public static function get_resolved_theme_uris( $theme_json, $options = array() ) {
public static function get_resolved_theme_uris( $theme_json ) {
$resolved_theme_uris = array();

if ( ! $theme_json instanceof WP_Theme_JSON_Gutenberg || empty( $theme_json ) ) {
Expand All @@ -792,13 +791,11 @@ public static function get_resolved_theme_uris( $theme_json, $options = array()
is_string( $theme_json_data['styles']['background']['backgroundImage']['url'] ) &&
// Where a URL is not absolute (has no host fragment), it is assumed to be relative to the theme directory.
! isset( wp_parse_url( $theme_json_data['styles']['background']['backgroundImage']['url'] )['host'] ) ) {
$resolved_theme_uri = array(
'file' => $theme_json_data['styles']['background']['backgroundImage']['url'],
$resolved_theme_uri = array(
'name' => $theme_json_data['styles']['background']['backgroundImage']['url'],
'href' => esc_url( get_theme_file_uri( $theme_json_data['styles']['background']['backgroundImage']['url'] ) ),
'path' => array( 'styles', 'background', 'backgroundImage', 'url' ),
);
if ( ! empty( $options['include_paths'] ) ) {
$resolved_theme_uri['path'] = array( 'styles', 'background', 'backgroundImage', 'url' );
}
$resolved_theme_uris[] = $resolved_theme_uri;
}

Expand All @@ -815,12 +812,7 @@ public static function get_resolved_theme_uris( $theme_json, $options = array()
* @return WP_Theme_JSON_Gutenberg Theme merged with resolved paths, if any found.
*/
public static function resolve_theme_file_uris( $theme_json ) {
$resolved_urls = static::get_resolved_theme_uris(
$theme_json,
array(
'include_paths' => true,
)
);
$resolved_urls = static::get_resolved_theme_uris( $theme_json );
if ( empty( $resolved_urls ) ) {
return $theme_json;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ public function prepare_item_for_response( $post, $request ) {
$links = array();
$resolved_theme_uris = WP_Theme_JSON_Resolver_Gutenberg::get_resolved_theme_uris( $theme_json );
if ( ! empty( $resolved_theme_uris ) ) {
$links['theme_file_uris'] = $resolved_theme_uris;
/*
* @TODO this needs to be added to the WP REST API schema.
* E.g., $links['https://api.w.org/theme-file-uris'].
*/
$links['wp:theme-file-uris'] = $resolved_theme_uris;
}
$response->add_links( $links );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { TOOLSPANEL_DROPDOWNMENU_PROPS } from './utils';
import { setImmutably } from '../../utils/object';
import MediaReplaceFlow from '../media-replace-flow';
import { store as blockEditorStore } from '../../store';
import { getThemeFileURI } from './set-theme-file-uris';
import { getResolvedThemeFilePath } from './set-theme-file-uris';

const IMAGE_BACKGROUND_TYPE = 'image';
const DEFAULT_CONTROLS = {
Expand Down Expand Up @@ -303,7 +303,10 @@ function BackgroundImageToolsPanelItem( {
<InspectorImagePreview
label={ title }
filename={ title || __( 'Untitled' ) }
url={ getThemeFileURI( url, themeFileURIs ) }
url={ getResolvedThemeFilePath(
url,
themeFileURIs
) }
/>
}
variant="secondary"
Expand Down Expand Up @@ -471,7 +474,7 @@ function BackgroundSizeToolsPanelItem( {
<FocalPointPicker
__next40pxDefaultSize
label={ __( 'Position' ) }
url={ getThemeFileURI( imageValue, themeFileURIs ) }
url={ getResolvedThemeFilePath( imageValue, themeFileURIs ) }
value={ backgroundPositionToCoords( positionValue ) }
onChange={ updateBackgroundPosition }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
*/
import { isURL, isValidPath } from '@wordpress/url';

/**
* Internal dependencies
*/
import { getValueFromObjectPath } from '../../utils/object';

function isRelativePath( url ) {
return isValidPath( url ) && ! isURL( url );
}
Expand All @@ -14,41 +19,39 @@ function isRelativePath( url ) {
* @param {Array<Object>} themeFileURIs A collection of absolute theme file URIs and their corresponding file paths.
* @return {string?} A resolved theme file URI, if one is found in the themeFileURIs collection.
*/
export function getThemeFileURI( file, themeFileURIs = [] ) {
export function getResolvedThemeFilePath( file, themeFileURIs = [] ) {
if ( ! isRelativePath( file ) ) {
return file;
}

const uri = themeFileURIs.find(
( themeFileUri ) => themeFileUri.file === file
( themeFileUri ) => themeFileUri.name === file
);

return uri?.href;
}

/**
* Houses logic of where to look for unresolved theme file paths.
* Mutates an object by settings a value at the provided path.
*
* @param {Object} styles A styles object.
* @param {Array<Object>} themeFileURIs A collection of absolute theme file URIs and their corresponding file paths.
* @return {Object} Returns mutated styles object.
* @param {Object} object Object to set a value in.
* @param {number|string|Array} path Path in the object to modify.
* @param {*} value New value to set.
* @return {Object} Object with the new value set.
*/
function setUnresolvedThemeFilePaths( styles, themeFileURIs ) {
// Top level styles.
if (
!! styles?.background?.backgroundImage?.url &&
isRelativePath( styles?.background?.backgroundImage?.url )
) {
const backgroundImageUrl = getThemeFileURI(
styles?.background?.backgroundImage?.url,
themeFileURIs
);
if ( backgroundImageUrl ) {
styles.background.backgroundImage.url = backgroundImageUrl;
}
function setMutably( object, path, value ) {
path = Array.isArray( path ) ? [ ...path ] : [ path ];
const finalValueKey = path.pop();
let prev = object;

for ( const key of path ) {
const current = prev[ key ];
prev = current;
}

return styles;
prev[ finalValueKey ] = value;

return object;
}

/**
Expand All @@ -65,8 +68,19 @@ export default function setThemeFileUris( themeJson, themeFileURIs ) {
return themeJson;
}

// Mutating function.
setUnresolvedThemeFilePaths( themeJson.styles, themeFileURIs );
themeFileURIs.forEach( ( { name, href, path } ) => {
const value = getValueFromObjectPath( themeJson, path );
if ( value === name ) {
/*
* The object must not be updated immutably here because the
* themeJson is a reference to the global styles tree used as a dependency in the
* useGlobalStylesOutputWithConfig() hook. If we mutate the object,
* the hook will detect the change and re-render the component, resulting
* in a maximum depth exceeded error.
*/
themeJson = setMutably( themeJson, path, href );
}
} );

return themeJson;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ export function useGlobalStylesOutputWithConfig( mergedConfig = {} ) {
const [ blockGap ] = useGlobalSetting( 'spacing.blockGap' );
mergedConfig = setThemeFileUris(
mergedConfig,
mergedConfig?._links?.theme_file_uris
mergedConfig?._links?.[ 'wp:theme-file-uris' ]
);
const hasBlockGapSupport = blockGap !== null;
const hasFallbackGapSupport = ! hasBlockGapSupport; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback styles support.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function BackgroundPanel() {
headerLabel={ __( 'Image' ) }
defaultValues={ BACKGROUND_DEFAULT_VALUES }
defaultControls={ defaultControls }
themeFileURIs={ _links?.theme_file_uris }
themeFileURIs={ _links?.[ 'wp:theme-file-uris' ] }
/>
);
}

0 comments on commit 2eb8219

Please sign in to comment.