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

Fix Faust.js WordPress Plugin Preview #1568

Merged
merged 4 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/soft-cooks-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@faustwp/wordpress-plugin': patch
---

Fixed a bug in the block editor screen where the preview link was missing the `p` and `previewPathName` query arguments after saving a draft.
11 changes: 9 additions & 2 deletions plugins/faustwp/includes/replacement/callbacks.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,15 @@ function term_link( $term_link ) {
* XXX: Please remove this once this issue is resolved: https://github.com/WordPress/gutenberg/issues/13998
*/
function enqueue_preview_scripts() {
wp_enqueue_script( 'faustwp-gutenberg-filters', plugins_url( '/previewlinks.js', __FILE__ ), array( 'jquery' ), plugin_version(), true );
wp_localize_script( 'faustwp-gutenberg-filters', '_faustwp_preview_link', array( '_preview_link' => get_preview_post_link() ) );
wp_enqueue_script( 'faustwp-gutenberg-filters', plugins_url( '/previewlinks.js', __FILE__ ), array(), plugin_version(), true );
wp_localize_script(
'faustwp-gutenberg-filters',
'_faustwp_preview_data',
array(
'_preview_link' => get_preview_post_link(),
'_wp_version' => get_bloginfo( 'version' ),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the WordPress version to better handle any breaking changes until WordPress/gutenberg#13998 is resolved.

)
);
}

add_filter( 'wp_sitemaps_posts_entry', __NAMESPACE__ . '\\sitemaps_posts_entry' );
Expand Down
105 changes: 57 additions & 48 deletions plugins/faustwp/includes/replacement/previewlinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,63 @@
* XXX: Please remove this once this issue is resolved: https://github.com/WordPress/gutenberg/issues/13998
*/

window.addEventListener('DOMContentLoaded', function () {
jQuery(document).ready(function () {
// Get the correct preview link via wp_localize_script
const previewLink = window._faustwp_preview_link
? window._faustwp_preview_link._preview_link
: undefined;

/**
* Check to make sure there is a preview link before continuing, as there may not be a preview link
* for every instance the block editor is enqueued (e.g. /wp-admin/widgets.php)
*/
if (!previewLink) {
return;
document.addEventListener('DOMContentLoaded', function() {
// Get the preview data via wp_localize_script
const faustPreviewData = window._faustwp_preview_data;

/**
* Check to make sure there is a preview link before continuing, as there may not be a preview link
* for every instance the block editor is enqueued (e.g. /wp-admin/widgets.php)
*/
if (!faustPreviewData) {
return;
}

const wpVersion = faustPreviewData._wp_version;
const faustPreviewLink = faustPreviewData._preview_link;

function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}

// Handle potential breaking changes from WordPress.
function getPreviewLinksByVersion(version) {
switch (version) {
default:
return {
headerLink: document.querySelector('.edit-post-header-preview__grouping-external a'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query selector can only be used once since we replace the node in line 49 thus making it problematic. If we attempt to read this from a deleted node we may find issues.

snackbarLink: document.querySelector('.components-snackbar__content a'),
};
}
}

function updateUIElements() {
const { headerLink, snackbarLink } = getPreviewLinksByVersion(wpVersion);

// Clone & replace the original link in order to clear pre-existing events.
if (headerLink && headerLink.getAttribute('href') !== faustPreviewLink) {
const clonedHeaderLink = headerLink.cloneNode(true);
headerLink.parentNode.replaceChild(clonedHeaderLink, headerLink);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cannot work unfortunately. The whole preview box is controlled by React and any attempts to modify the DOM under its nose will result in fatal errors. For example here is the result when I call wp.data.dispatch('core/editor').autosave(); after that:

Screenshot 2023-11-13 at 13 32 12 Screenshot 2023-11-13 at 13 32 08

if (clonedHeaderLink) clonedHeaderLink.setAttribute('href', faustPreviewLink);
}

const intervalId = setInterval(function () {
const previewButton = jQuery(
'button[class~="block-editor-post-preview__button-toggle"]',
);

if (!previewButton.length) {
return;
}

clearInterval(intervalId);
previewButton.first().one('click', function () {
setTimeout(function () {
const links = jQuery('a[target*="wp-preview"]');

if (!links.length) {
return;
}

links.each((i, link) => {
link.href = previewLink;

var copy = link.cloneNode(true);
copy.addEventListener('click', function () {
previewButton[0].click();

wp.data.dispatch('core/editor').autosave();
});

link.parentElement.insertBefore(copy, link);
link.style.display = 'none';
});
}, 100);
});
}, 100);
});
if (snackbarLink && snackbarLink.getAttribute('href') !== faustPreviewLink) {
snackbarLink.setAttribute('href', faustPreviewLink);
}
}

// Run the update function on initial page load.
const debouncedUpdateUIElements = debounce(updateUIElements, 300);

// Observe DOM changes to update UI elements accordingly.
const observer = new MutationObserver(debouncedUpdateUIElements);
observer.observe(document.body, { childList: true, subtree: true });
});
Loading