Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple blocks on the same page #175

Merged
merged 11 commits into from
Feb 2, 2023
44 changes: 27 additions & 17 deletions frontend/block/view.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { BlockProps, renderBlock } from "../app";

declare global {
interface Window {
ChatrixBlockConfig: {
attributes: object,
};
}
}

window.addEventListener('DOMContentLoaded', () => {
renderAllBlocks().catch(error => {
console.error(error);
Expand All @@ -18,24 +10,42 @@ async function renderAllBlocks() {
// See https://github.com/Automattic/chatrix/issues/161 for why we introduce a delay here.
await introduceDelayInMilliseconds(1);

const config = window.ChatrixBlockConfig;
if (!config) {
throw "ChatrixBlockConfig is not defined";
}

const props: BlockProps = {
attributes: config.attributes,
};

const containers = <HTMLCollectionOf<HTMLElement>>document.getElementsByClassName('wp-block-automattic-chatrix');
for (const container of containers) {
const config = getConfigFromDataElement(container);
const props: BlockProps = {
attributes: config.attributes,
};

renderBlock(container, props);

// TODO: Support multiple blocks on the same page.
break;
}
}

/**
* The container element has a single <span> child that contains the config as a data-attribute.
* This function parses that data-attribute into an object.
*/
function getConfigFromDataElement(container: HTMLElement): BlockConfig {
const dataElement = container.getElementsByTagName('span').item(0);
if (!dataElement) {
throw "Data element for chatrix block was not found";
}

const dataString = decodeURIComponent(dataElement.dataset?.chatrixBlockConfig ?? '');
if (dataString === '') {
throw "Data attribute for chatrix block was not found, or is empty";
}

return JSON.parse(dataString);
}

interface BlockConfig {
attributes: object,
}

async function introduceDelayInMilliseconds(delay: number) {
return new Promise(resolve => setTimeout(resolve, delay));
}
9 changes: 2 additions & 7 deletions src/Block/block.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,22 @@ function () use ( $block_json_path ) {
}

function render( array $attributes ): string {
$handle = 'chatrix-block-config';
$json_data = wp_json_encode(
array(
'attributes' => $attributes,
)
);

wp_register_script( $handle, '', array(), automattic_chatrix_version(), true );
wp_add_inline_script( $handle, "window.ChatrixBlockConfig = $json_data;", 'before' );
wp_enqueue_script( $handle );

ob_start();
?>
<div <?php echo wp_kses_data( get_block_wrapper_attributes() ); ?>>
<?php // Iframe will be rendered here. ?>
<?php // The following element will be replaced by the <Block> component. ?>
<span style="display: none;" data-chatrix-block-config="<?php echo rawurlencode( $json_data ); ?>"></span>
psrpinto marked this conversation as resolved.
Show resolved Hide resolved
</div>
<?php
return ob_get_clean();
}


function parse_block_json( string $block_json_path ): array {
// phpcs discourages file_get_contents for remote URLs, and recommends using wp_remote_get().
// However, here we're dealing with a path to a file on disk, so we ignore phpcs's warning.
Expand Down