Refactor AJAX user authentication
This commit is contained in:
parent
d145067b89
commit
b1e6ffc700
@ -246,8 +246,8 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| `template_redirect` | `fictioneer_disable_date_archives`, `fictioneer_generate_epub`, `fictioneer_handle_oauth`, `fictioneer_logout`, `fictioneer_disable_attachment_pages`, `fictioneer_gate_unpublished_content`
|
||||
| `trashed_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_transients`, `fictioneer_flush_object_cache`
|
||||
| `untrash_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_transients`, `fictioneer_flush_object_cache`
|
||||
| `wp_ajax_*` | `fictioneer_ajax_clear_my_checkmarks`, `fictioneer_ajax_clear_my_comments`, `fictioneer_ajax_clear_my_comment_subscriptions`, `fictioneer_ajax_clear_my_follows`, `fictioneer_ajax_clear_my_reminders`, `fictioneer_ajax_delete_epub`, `fictioneer_ajax_delete_my_account`, `fictioneer_ajax_delete_my_comment`, `fictioneer_ajax_edit_comment`, `fictioneer_ajax_get_avatar`, `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_finished_checkmarks_list`, `fictioneer_ajax_get_follows_list`, `fictioneer_ajax_get_follows_notifications`, `fictioneer_ajax_get_nonce`, `fictioneer_ajax_get_reminders_list`, `fictioneer_ajax_is_user_logged_in`, `fictioneer_ajax_mark_follows_read`, `fictioneer_ajax_moderate_comment`, `fictioneer_ajax_purge_schema`, `fictioneer_ajax_report_comment`, `fictioneer_ajax_save_bookmarks`, `fictioneer_ajax_set_checkmark`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_toggle_follow`, `fictioneer_ajax_toggle_reminder`, `fictioneer_ajax_unset_my_oauth`, `fictioneer_ajax_get_user_data`
|
||||
| `wp_ajax_nopriv_*` | `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_nonce`, `fictioneer_ajax_is_user_logged_in`, `fictioneer_ajax_submit_comment`
|
||||
| `wp_ajax_*` | `fictioneer_ajax_clear_my_checkmarks`, `fictioneer_ajax_clear_my_comments`, `fictioneer_ajax_clear_my_comment_subscriptions`, `fictioneer_ajax_clear_my_follows`, `fictioneer_ajax_clear_my_reminders`, `fictioneer_ajax_delete_epub`, `fictioneer_ajax_delete_my_account`, `fictioneer_ajax_delete_my_comment`, `fictioneer_ajax_edit_comment`, `fictioneer_ajax_get_avatar`, `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_finished_checkmarks_list`, `fictioneer_ajax_get_follows_list`, `fictioneer_ajax_get_follows_notifications`, `fictioneer_ajax_get_reminders_list`, `fictioneer_ajax_mark_follows_read`, `fictioneer_ajax_moderate_comment`, `fictioneer_ajax_purge_schema`, `fictioneer_ajax_report_comment`, `fictioneer_ajax_save_bookmarks`, `fictioneer_ajax_set_checkmark`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_toggle_follow`, `fictioneer_ajax_toggle_reminder`, `fictioneer_ajax_unset_my_oauth`, `fictioneer_ajax_get_user_data`, `fictioneer_ajax_get_auth`
|
||||
| `wp_ajax_nopriv_*` | `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_get_auth`
|
||||
| `wp_before_admin_bar_render` | `fictioneer_remove_admin_bar_links`, `fictioneer_remove_dashboard_from_admin_bar`
|
||||
| `wp_dashboard_setup` | `fictioneer_remove_dashboard_widgets`
|
||||
| `wp_default_scripts` | `fictioneer_remove_jquery_migrate`
|
||||
|
@ -314,7 +314,7 @@ The [plugin ecosystem](https://wordpress.org/plugins/) of WordPress is vast and
|
||||
<h4>[Fictioneer: General] Compatibility:</h4>
|
||||
<ul>
|
||||
<li>- [x] Enable cache compatibility mode</li>
|
||||
<li>- [x] Enable AJAX nonce deferment</li>
|
||||
<li>- [x] Enable AJAX user authentication</li>
|
||||
<li>- [x] Enable AJAX comment form (best performance) ... or ... comment section (best compatibility)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
@ -450,7 +450,6 @@ Technically just another plugin, but one that will make your site significantly
|
||||
<h4>[General] Compatibility:</h4>
|
||||
<ul>
|
||||
<li>- [x] Enable public cache compatibility mode</li>
|
||||
<li>- [x] Enable AJAX nonce deferment</li>
|
||||
<li>- [x] Enable AJAX user authentication</li>
|
||||
<li>- [x] Enable AJAX comment form (best performance) ... or ... comment section (best compatibility)</li>
|
||||
</ul>
|
||||
@ -582,10 +581,10 @@ Most of the theme’s configuration is found here, the options being largely sel
|
||||
* **Contact Form Receivers:** Submitted contact forms are sent to those email addresses. One per line.
|
||||
* **Add consent wrappers to embedded content:** Required to be GDPR compliant if you use embeds.
|
||||
* **Page Assignments:** Only set what you actually need. Used for breadcrumbs and menu items.
|
||||
* **Enable Storygraph API:** Allow external services to index and search your site to reach a larger audience. Recommended.
|
||||
* **Enable OAuth 2.0 authentication:** Allow visitors to register with social media accounts, but be aware of the implications!
|
||||
* **Enable Storygraph API:** Allows external services to index and search your site to reach a larger audience. Recommended.
|
||||
* **Enable OAuth 2.0 authentication:** Allows visitors to register with social media accounts, but be aware of the implications!
|
||||
* **Enable AJAX comment form/section:** If you have trouble with caching. Try the form first to save resources.
|
||||
* **Enable AJAX nonce deferment:** [Nonces](https://developer.wordpress.org/apis/security/nonces/) can conflict with caching. Use this as *last resort* to bypass the cache.
|
||||
* **Enable AJAX user authentication:** If you have trouble with [Nonces](https://developer.wordpress.org/apis/security/nonces/) and/or users not being properly logged-in. Use this as *last resort* to bypass the cache.
|
||||
* **Disable theme comment {…}:** If you want to use different comments. Disables most of the other comment options as well.
|
||||
|
||||
<br>
|
||||
|
@ -8,9 +8,6 @@ if ( ! defined( 'FICTIONEER_FAST_AJAX_FUNCTIONS' ) ) {
|
||||
define(
|
||||
'FICTIONEER_FAST_AJAX_FUNCTIONS',
|
||||
array(
|
||||
// System
|
||||
'fictioneer_ajax_is_user_logged_in',
|
||||
'fictioneer_ajax_get_nonce',
|
||||
// Bookmarks
|
||||
'fictioneer_ajax_save_bookmarks',
|
||||
// Follows
|
||||
@ -28,6 +25,7 @@ if ( ! defined( 'FICTIONEER_FAST_AJAX_FUNCTIONS' ) ) {
|
||||
'fictioneer_ajax_clear_my_checkmarks',
|
||||
'fictioneer_ajax_get_finished_checkmarks_list',
|
||||
// User
|
||||
'fictioneer_ajax_get_auth',
|
||||
'fictioneer_ajax_get_user_data',
|
||||
'fictioneer_ajax_get_avatar'
|
||||
)
|
||||
|
@ -1075,7 +1075,7 @@ if ( ! current_user_can( 'manage_options' ) ) {
|
||||
echo '<style type="text/css">.user-url-wrap, .user-description-wrap, .user-first-name-wrap, .user-last-name-wrap, .user-language-wrap, .user-admin-bar-front-wrap, .user-pass1-wrap, .user-pass2-wrap, .pw-weak, .user-generate-reset-link-wrap, #contextual-help-link-wrap, #your-profile > h2:first-of-type { display: none; }</style>';
|
||||
|
||||
// Add JS to remove blocks...
|
||||
echo '<script>document.addEventListener("DOMContentLoaded", () =>{document.querySelectorAll(".user-pass1-wrap, .user-pass2-wrap, .pw-weak, .user-generate-reset-link-wrap").forEach(element => {console.log(element); element.remove();});});</script>';
|
||||
echo '<script>document.addEventListener("DOMContentLoaded", () => {document.querySelectorAll(".user-pass1-wrap, .user-pass2-wrap, .pw-weak, .user-generate-reset-link-wrap").forEach(element => {element.remove();});});</script>';
|
||||
}
|
||||
|
||||
if ( current_user_can( 'fcn_reduced_profile' ) ) {
|
||||
|
@ -13,10 +13,10 @@
|
||||
function fictioneer_bring_out_legacy_trash() {
|
||||
// Setup
|
||||
$options = wp_cache_get( 'alloptions', 'options' );
|
||||
$obsolete = ['fictioneer_disable_html_in_comments', 'fictioneer_block_subscribers_from_admin', 'fictioneer_admin_restrict_menus', 'fictioneer_admin_restrict_private_data', 'fictioneer_admin_reduce_subscriber_profile', 'fictioneer_enable_subscriber_self_delete', 'fictioneer_strip_shortcodes_for_non_administrators', 'fictioneer_restrict_media_access', 'fictioneer_subscription_enabled', 'fictioneer_patreon_badge_map', 'fictioneer_patreon_tier_as_badge', 'fictioneer_patreon_campaign_ids', 'fictioneer_patreon_campaign_id', 'fictioneer_mount_wpdiscuz_theme_styles', 'fictioneer_base_site_width', 'fictioneer_comment_form_selector', 'fictioneer_featherlight_enabled', 'fictioneer_tts_enabled', 'fictioneer_log'];
|
||||
$obsolete = ['fictioneer_disable_html_in_comments', 'fictioneer_block_subscribers_from_admin', 'fictioneer_admin_restrict_menus', 'fictioneer_admin_restrict_private_data', 'fictioneer_admin_reduce_subscriber_profile', 'fictioneer_enable_subscriber_self_delete', 'fictioneer_strip_shortcodes_for_non_administrators', 'fictioneer_restrict_media_access', 'fictioneer_subscription_enabled', 'fictioneer_patreon_badge_map', 'fictioneer_patreon_tier_as_badge', 'fictioneer_patreon_campaign_ids', 'fictioneer_patreon_campaign_id', 'fictioneer_mount_wpdiscuz_theme_styles', 'fictioneer_base_site_width', 'fictioneer_comment_form_selector', 'fictioneer_featherlight_enabled', 'fictioneer_tts_enabled', 'fictioneer_log', 'fictioneer_enable_ajax_nonce'];
|
||||
|
||||
// Check for most recent obsolete option...
|
||||
if ( isset( $options['fictioneer_disable_html_in_comments'] ) ) {
|
||||
if ( isset( $options['fictioneer_enable_ajax_nonce'] ) ) {
|
||||
// Looping everything is not great but it only happens once!
|
||||
foreach ( $obsolete as $trash ) {
|
||||
delete_option( $trash );
|
||||
@ -249,7 +249,6 @@ function fictioneer_root_attributes() {
|
||||
$conditions = array(
|
||||
'data-ajax-submit' => get_option( 'fictioneer_enable_ajax_comment_submit', false ),
|
||||
'data-force-child-theme' => ! FICTIONEER_THEME_SWITCH,
|
||||
'data-ajax-nonce' => get_option( 'fictioneer_enable_ajax_nonce', false ),
|
||||
'data-public-caching' => get_option( 'fictioneer_enable_public_cache_compatibility', false ),
|
||||
'data-ajax-auth' => get_option( 'fictioneer_enable_ajax_authentication', false ),
|
||||
'data-edit-time' => get_option( 'fictioneer_enable_user_comment_editing', false ) ?
|
||||
|
@ -960,17 +960,16 @@ function fictioneer_show_auth_content() {
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GET LOGIN STATUS VIA AJAX
|
||||
// AJAX AUTHENTICATION
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Sends login status via AJAX
|
||||
* Send user authentication status via AJAX
|
||||
*
|
||||
* @since 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
* @since 5.7.0
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_is_user_logged_in() {
|
||||
function fictioneer_ajax_get_auth() {
|
||||
// Enabled?
|
||||
if ( ! get_option( 'fictioneer_enable_ajax_authentication' ) ) {
|
||||
wp_send_json_error(
|
||||
@ -979,60 +978,27 @@ function fictioneer_ajax_is_user_logged_in() {
|
||||
);
|
||||
}
|
||||
|
||||
// Nonce
|
||||
check_ajax_referer( 'fictioneer_nonce', 'nonce' );
|
||||
|
||||
// Setup
|
||||
$user = wp_get_current_user();
|
||||
$nonce = wp_create_nonce( 'fictioneer_nonce' );
|
||||
$nonce_html = '<input id="fictioneer-ajax-nonce" name="fictioneer-ajax-nonce" type="hidden" value="' . $nonce . '">';
|
||||
|
||||
// Send login status
|
||||
// Response
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'loggedIn' => is_user_logged_in(),
|
||||
'isAdmin' => fictioneer_is_admin( $user->ID ),
|
||||
'isModerator' => fictioneer_is_moderator( $user->ID ),
|
||||
'isAuthor' => fictioneer_is_author( $user->ID ),
|
||||
'isEditor' => fictioneer_is_editor( $user->ID )
|
||||
'isEditor' => fictioneer_is_editor( $user->ID ),
|
||||
'nonce' => $nonce,
|
||||
'nonceHtml' => $nonce_html
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_ajax_authentication' ) ) {
|
||||
add_action( 'wp_ajax_fictioneer_ajax_is_user_logged_in', 'fictioneer_ajax_is_user_logged_in' );
|
||||
add_action( 'wp_ajax_nopriv_fictioneer_ajax_is_user_logged_in', 'fictioneer_ajax_is_user_logged_in' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// GET NONCE VIA AJAX
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Sends valid nonce via AJAX
|
||||
*
|
||||
* @since 5.0
|
||||
* @link https://developer.wordpress.org/reference/functions/wp_send_json_success/
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_get_nonce() {
|
||||
// Enabled?
|
||||
if ( ! get_option( 'fictioneer_enable_ajax_nonce' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'error' => __( 'Not allowed.', 'fictioneer' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare nonce field
|
||||
$nonce = wp_create_nonce( 'fictioneer_nonce' );
|
||||
$nonce_html = '<input id="fictioneer-ajax-nonce" name="fictioneer-ajax-nonce" type="hidden" value="' . $nonce . '">';
|
||||
|
||||
// Send nonce field
|
||||
wp_send_json_success( array( 'nonce' => $nonce, 'nonceHtml' => $nonce_html ) );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_ajax_nonce' ) ) {
|
||||
add_action( 'wp_ajax_fictioneer_ajax_get_nonce', 'fictioneer_ajax_get_nonce' );
|
||||
add_action( 'wp_ajax_nopriv_fictioneer_ajax_get_nonce', 'fictioneer_ajax_get_nonce' );
|
||||
add_action( 'wp_ajax_fictioneer_ajax_get_auth', 'fictioneer_ajax_get_auth' );
|
||||
add_action( 'wp_ajax_nopriv_fictioneer_ajax_get_auth', 'fictioneer_ajax_get_auth' );
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
@ -502,13 +502,6 @@ define( 'FICTIONEER_OPTIONS', array(
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Enable all Gutenberg block styles', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_enable_ajax_nonce' => array(
|
||||
'name' => 'fictioneer_enable_ajax_nonce',
|
||||
'group' => 'fictioneer-settings-general-group',
|
||||
'sanitize_callback' => 'fictioneer_sanitize_checkbox',
|
||||
'label' => __( 'Enable AJAX nonce deferment', 'fictioneer' ),
|
||||
'default' => false
|
||||
),
|
||||
'fictioneer_enable_ajax_authentication' => array(
|
||||
'name' => 'fictioneer_enable_ajax_authentication',
|
||||
|
@ -931,14 +931,6 @@
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_enable_ajax_nonce" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_enable_ajax_nonce" type="checkbox" id="fictioneer_enable_ajax_nonce" <?php echo checked( 1, get_option( 'fictioneer_enable_ajax_nonce' ), false ); ?> value="1">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans']['fictioneer_enable_ajax_nonce']['label']; ?></span>
|
||||
<p class="sub-label"><?php _e( 'Fetch the nonce via AJAX after the page has been loaded to get around aggressive caching strategies.', 'fictioneer' ) ?></p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="fictioneer_enable_ajax_authentication" class="label-wrapped-checkbox row">
|
||||
<input name="fictioneer_enable_ajax_authentication" type="checkbox" id="fictioneer_enable_ajax_authentication" <?php echo checked( 1, get_option( 'fictioneer_enable_ajax_authentication' ), false ); ?> value="1">
|
||||
<div>
|
||||
|
@ -15,11 +15,8 @@ function fictioneer_after_logout_cleanup() {
|
||||
<script>
|
||||
localStorage.removeItem('fcnProfileAvatar');
|
||||
localStorage.removeItem('fcnUserData');
|
||||
localStorage.removeItem('fcnLoginState');
|
||||
localStorage.removeItem('fcnNonce');
|
||||
localStorage.removeItem('fcnAuth');
|
||||
localStorage.removeItem('fcnBookshelfContent');
|
||||
|
||||
// Deliberate logout means clear bookmarks!
|
||||
localStorage.removeItem('fcnChapterBookmarks');
|
||||
</script>
|
||||
<?php // <--- End HTML
|
||||
|
2
js/admin.min.js
vendored
2
js/admin.min.js
vendored
@ -1 +1 @@
|
||||
function fcn_purgeSchema(e){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_purge_schema",nonce:document.getElementById("fictioneer_admin_nonce").value,id:e},dataType:"json",success:function(t){if(t.success){const t=_$$$(`schema-${e}`);t.querySelector(".text-blob").innerHTML=t.querySelector("summary").innerHTML,t.querySelector(".delete").remove(),t.querySelector(".no-schema-note").classList.remove("hidden")}}})}function fcn_delete_epub(e,t){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_delete_epub",nonce:document.getElementById("fictioneer_admin_nonce").value,name:e},dataType:"json",success:function(e){e.success&&document.getElementById(`epub-id-${t}`).remove()}})}function fcn_ogMediaUpload(e){e.preventDefault();var t=wp.media({multiple:!1,library:{type:"image"}}).open().on("select",(function(){const e=t.state().get("selection").first().toJSON();_$$$("fictioneer-seo-og-image").value=e.id,_$$$("fictioneer-seo-og-display").setAttribute("src",e.url),_$$$("fictioneer-button-seo-og-image-remove").classList.remove("hidden"),_$(".og-source").classList.add("hidden")}))}function fcn_update_seo_title_chars(){const e=_$$$("fictioneer-seo-title");"{{title}} – {{site}}"!=e.value?_$$$("fictioneer-seo-title-chars").innerHTML=`(${e.value.length}/70)`:_$$$("fictioneer-seo-title-chars").innerHTML=""}function fcn_remove_seo_og_image(e){e.preventDefault();const t=_$$$("fictioneer-seo-og-display").dataset.placeholder;_$$$("fictioneer-seo-og-image").value="",_$$$("fictioneer-seo-og-display").setAttribute("src",t),_$$$("fictioneer-button-seo-og-image-remove").classList.add("hidden")}function fcn_confirmIt(e){const t=e.currentTarget.dataset.dialogMessage,o=e.currentTarget.dataset.dialogConfirm;if(!t||!o)return;const a=prompt(t);a?a.toLowerCase()!=o.toLowerCase()&&e.preventDefault():e.preventDefault()}_$$(".button-purge-schema").forEach((e=>{e.addEventListener("click",(e=>{fcn_purgeSchema(e.currentTarget.dataset.id)}))})),_$$(".button-delete-epub").forEach((e=>{e.addEventListener("click",(e=>{fcn_delete_epub(e.target.dataset.filename,e.target.dataset.id)}))})),(button=_$$$("fictioneer-button-og-upload"))&&button.addEventListener("click",fcn_ogMediaUpload),(button=_$$$("fictioneer-seo-title"))&&(fcn_update_seo_title_chars(),button.addEventListener("keyup",fcn_update_seo_title_chars)),(button=_$$$("fictioneer-button-seo-og-image-remove"))&&button.addEventListener("click",fcn_remove_seo_og_image),_$$(".confirm-dialog").forEach((e=>{e.addEventListener("click",(e=>{fcn_confirmIt(e)}))})),_$("#wp-admin-bar-logout a")?.addEventListener("click",(()=>{localStorage.removeItem("fcnProfileAvatar"),localStorage.removeItem("fcnUserData"),localStorage.removeItem("fcnLoginState"),localStorage.removeItem("fcnNonce"),localStorage.removeItem("fcnBookshelfContent"),localStorage.removeItem("fcnChapterBookmarks")})),_$(".fictioneer-settings")?.addEventListener("click",(e=>{const t=e.target.closest("[data-click]"),o=t?.dataset.click;if(o)switch(o){case"purge-all-epubs":case"purge-all-schemas":case"purge-all-meta":case"reset-post-relationship-registry":confirm(t.dataset.prompt)||e.preventDefault()}})),_$$("button[data-dialog-target]").forEach((e=>{e.addEventListener("click",(e=>{_$$$(e.currentTarget.dataset.dialogTarget)?.showModal()}))})),_$$('button[formmethod="dialog"][value="cancel"]').forEach((e=>{e.addEventListener("click",(e=>{e.preventDefault(),e.currentTarget.closest("dialog").close()}))}));
|
||||
function fcn_purgeSchema(e){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_purge_schema",nonce:document.getElementById("fictioneer_admin_nonce").value,id:e},dataType:"json",success:function(t){if(t.success){const t=_$$$(`schema-${e}`);t.querySelector(".text-blob").innerHTML=t.querySelector("summary").innerHTML,t.querySelector(".delete").remove(),t.querySelector(".no-schema-note").classList.remove("hidden")}}})}function fcn_delete_epub(e,t){jQuery.ajax({url:fictioneer_ajax.ajax_url,type:"post",data:{action:"fictioneer_ajax_delete_epub",nonce:document.getElementById("fictioneer_admin_nonce").value,name:e},dataType:"json",success:function(e){e.success&&document.getElementById(`epub-id-${t}`).remove()}})}function fcn_ogMediaUpload(e){e.preventDefault();var t=wp.media({multiple:!1,library:{type:"image"}}).open().on("select",(function(){const e=t.state().get("selection").first().toJSON();_$$$("fictioneer-seo-og-image").value=e.id,_$$$("fictioneer-seo-og-display").setAttribute("src",e.url),_$$$("fictioneer-button-seo-og-image-remove").classList.remove("hidden"),_$(".og-source").classList.add("hidden")}))}function fcn_update_seo_title_chars(){const e=_$$$("fictioneer-seo-title");"{{title}} – {{site}}"!=e.value?_$$$("fictioneer-seo-title-chars").innerHTML=`(${e.value.length}/70)`:_$$$("fictioneer-seo-title-chars").innerHTML=""}function fcn_remove_seo_og_image(e){e.preventDefault();const t=_$$$("fictioneer-seo-og-display").dataset.placeholder;_$$$("fictioneer-seo-og-image").value="",_$$$("fictioneer-seo-og-display").setAttribute("src",t),_$$$("fictioneer-button-seo-og-image-remove").classList.add("hidden")}function fcn_confirmIt(e){const t=e.currentTarget.dataset.dialogMessage,o=e.currentTarget.dataset.dialogConfirm;if(!t||!o)return;const a=prompt(t);a?a.toLowerCase()!=o.toLowerCase()&&e.preventDefault():e.preventDefault()}_$$(".button-purge-schema").forEach((e=>{e.addEventListener("click",(e=>{fcn_purgeSchema(e.currentTarget.dataset.id)}))})),_$$(".button-delete-epub").forEach((e=>{e.addEventListener("click",(e=>{fcn_delete_epub(e.target.dataset.filename,e.target.dataset.id)}))})),(button=_$$$("fictioneer-button-og-upload"))&&button.addEventListener("click",fcn_ogMediaUpload),(button=_$$$("fictioneer-seo-title"))&&(fcn_update_seo_title_chars(),button.addEventListener("keyup",fcn_update_seo_title_chars)),(button=_$$$("fictioneer-button-seo-og-image-remove"))&&button.addEventListener("click",fcn_remove_seo_og_image),_$$(".confirm-dialog").forEach((e=>{e.addEventListener("click",(e=>{fcn_confirmIt(e)}))})),_$("#wp-admin-bar-logout a")?.addEventListener("click",(()=>{localStorage.removeItem("fcnProfileAvatar"),localStorage.removeItem("fcnUserData"),localStorage.removeItem("fcnAuth"),localStorage.removeItem("fcnBookshelfContent"),localStorage.removeItem("fcnChapterBookmarks")})),_$(".fictioneer-settings")?.addEventListener("click",(e=>{const t=e.target.closest("[data-click]"),o=t?.dataset.click;if(o)switch(o){case"purge-all-epubs":case"purge-all-schemas":case"purge-all-meta":case"reset-post-relationship-registry":confirm(t.dataset.prompt)||e.preventDefault()}})),_$$("button[data-dialog-target]").forEach((e=>{e.addEventListener("click",(e=>{_$$$(e.currentTarget.dataset.dialogTarget)?.showModal()}))})),_$$('button[formmethod="dialog"][value="cancel"]').forEach((e=>{e.addEventListener("click",(e=>{e.preventDefault(),e.currentTarget.closest("dialog").close()}))}));
|
2
js/ajax-bookshelf.min.js
vendored
2
js/ajax-bookshelf.min.js
vendored
@ -1 +1 @@
|
||||
const fcn_bookshelfTarget=_$$$("ajax-bookshelf-target");function fcn_getBookshelfContent(){const e=localStorage.getItem("fcnBookshelfContent");return e&&fcn_isValidJSONString(e)?JSON.parse(e):{html:{},count:{}}}function fcn_updateBookshelfView(e=null,t=null,o=null,n=!1){let a=fcn_getBookshelfContent();const s=(e=e??fcn_bookshelfTarget.dataset.action)+(t=t??fcn_bookshelfTarget.dataset.page)+(o=o??fcn_bookshelfTarget.dataset.order);if(!a.hasOwnProperty("timestamp")||a.timestamp+6e4<Date.now())return localStorage.removeItem("fcnBookshelfContent"),a={html:{},count:{}},void fcn_fetchBookshelfPart(e,t,o,n);a.hasOwnProperty("html")&&a.html.hasOwnProperty(s)?(fcn_bookshelfTarget.innerHTML=a.html[s],fcn_bookshelfTarget.classList.remove("ajax-in-progress"),fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${a.count[e]})`,n&&_$$$("main").scrollIntoView({behavior:"smooth"})):fcn_fetchBookshelfPart(e,t,o,n)}function fcn_browseBookshelfPage(e){fcn_bookshelfTarget.classList.add("ajax-in-progress"),fcn_updateBookshelfView(null,e,null,!0),history.pushState({},"",fcn_buildUrl({tab:fcn_bookshelfTarget.dataset.tab,pg:e,order:fcn_bookshelfTarget.dataset.order}).href)}function fcn_fetchBookshelfPart(e,t,o,n=!1){const a=e+t+o,s=fcn_getBookshelfContent();fcn_ajaxGet({action:e,fcn_fast_ajax:1,page:t,order:o}).then((o=>{o.success?(s.timestamp=Date.now(),s.html[a]=o.data.html,s.count[e]=o.data.count,localStorage.setItem("fcnBookshelfContent",JSON.stringify(s)),fcn_bookshelfTarget.innerHTML=o.data.html,fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${o.data.count})`):(fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(o.data.error)))})).catch((e=>{_$(".item-number").innerHTML="",fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(`${e.status}: ${e.statusText}`))})).then((()=>{fcn_bookshelfTarget.classList.remove("ajax-in-progress"),n&&_$$$("main").scrollIntoView({behavior:"smooth"})}))}fcn_theRoot.dataset.ajaxNonce&&!_$$$("fictioneer-ajax-nonce")?fcn_theRoot.addEventListener("nonceReady",(()=>{fcn_updateBookshelfView()})):fcn_updateBookshelfView(),_$(".bookshelf__list")?.addEventListener("click",(e=>{const t=e.target.closest(".page-numbers[data-page]");t&&fcn_browseBookshelfPage(t.dataset.page)}));
|
||||
const fcn_bookshelfTarget=_$$$("ajax-bookshelf-target");function fcn_getBookshelfContent(){return fcn_parseJSON(localStorage.getItem("fcnBookshelfContent"))??{html:{},count:{}}}function fcn_updateBookshelfView(e=null,t=null,o=null,n=!1){let a=fcn_getBookshelfContent();const s=(e=e??fcn_bookshelfTarget.dataset.action)+(t=t??fcn_bookshelfTarget.dataset.page)+(o=o??fcn_bookshelfTarget.dataset.order);if(!a.hasOwnProperty("timestamp")||a.timestamp+6e4<Date.now())return localStorage.removeItem("fcnBookshelfContent"),a={html:{},count:{}},void fcn_fetchBookshelfPart(e,t,o,n);a.hasOwnProperty("html")&&a.html.hasOwnProperty(s)?(fcn_bookshelfTarget.innerHTML=a.html[s],fcn_bookshelfTarget.classList.remove("ajax-in-progress"),fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${a.count[e]})`,n&&_$$$("main").scrollIntoView({behavior:"smooth"})):fcn_fetchBookshelfPart(e,t,o,n)}function fcn_browseBookshelfPage(e){fcn_bookshelfTarget.classList.add("ajax-in-progress"),fcn_updateBookshelfView(null,e,null,!0),history.pushState({},"",fcn_buildUrl({tab:fcn_bookshelfTarget.dataset.tab,pg:e,order:fcn_bookshelfTarget.dataset.order}).href)}function fcn_fetchBookshelfPart(e,t,o,n=!1){const a=e+t+o,s=fcn_getBookshelfContent();fcn_ajaxGet({action:e,fcn_fast_ajax:1,page:t,order:o}).then((o=>{o.success?(s.timestamp=Date.now(),s.html[a]=o.data.html,s.count[e]=o.data.count,localStorage.setItem("fcnBookshelfContent",JSON.stringify(s)),fcn_bookshelfTarget.innerHTML=o.data.html,fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${o.data.count})`):(fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(o.data.error)))})).catch((e=>{_$(".item-number").innerHTML="",fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(`${e.status}: ${e.statusText}`))})).then((()=>{fcn_bookshelfTarget.classList.remove("ajax-in-progress"),n&&_$$$("main").scrollIntoView({behavior:"smooth"})}))}fcn_theRoot.dataset.ajaxNonce?document.addEventListener("fcnAuthReady",(()=>{fcn_updateBookshelfView()})):fcn_updateBookshelfView(),_$(".bookshelf__list")?.addEventListener("click",(e=>{const t=e.target.closest(".page-numbers[data-page]");t&&fcn_browseBookshelfPage(t.dataset.page)}));
|
2
js/ajax-comments.min.js
vendored
2
js/ajax-comments.min.js
vendored
@ -1 +1 @@
|
||||
const fcn_ajaxCommentsSection=_$$$("comments");var fct_commentsObserver,fcn_commentStack=[];function fcn_getCommentSection(e=null,n=null,t=!1){if(!fcn_ajaxCommentsSection)return;const o=_$$$("comments");let c,a="",m=_$$$("comment");if(m&&(a=m.value),fcn_ajaxCommentsSection.classList.contains("ajax-in-progress"))return;if(fcn_ajaxCommentsSection.classList.add("ajax-in-progress"),n||(n=fcn_urlParams.pg??1),!fcn_ajaxCommentsSection)return;const r={action:"fictioneer_ajax_get_comment_section",post_id:e??fcn_ajaxCommentsSection.dataset.postId,page:parseInt(n)};fcn_urlParams.commentcode&&(r.commentcode=fcn_urlParams.commentcode),fcn_ajaxGet(r).then((e=>{if(e.success){n=e.data.page;const c=document.createElement("div");if(c.innerHTML=e.data.html,c.querySelector("#comment_post_ID")){c.querySelector("#comment_post_ID").value=e.data.postId,c.querySelector("#cancel-comment-reply-link").href="#respond";const n=c.querySelector(".logout-link");n&&(n.href=_$$$("comments").dataset.logoutUrl)}o.innerHTML=c.innerHTML,c.remove(),m=_$$$("comment"),m&&(m.value=a,fcn_commentStack.forEach((e=>{m.value+=e}))),fcn_commentStack=[],m&&fcn_textareaAdjust(m),fcn_addModerationEvents(),fcn_addCommentMouseleaveEvents(),fcn_addTextareaEvents(),fcn_addCommentFormEvents(),fcn_addPrivateToggleEvents(),fcn_bindAJAXCommentSubmit(),fcn_addJSTrap(),fcn_revealEditButton(),fcn_revealDeleteButton();const r=location.hash.includes("#comment")?location.hash:".respond",s=document.querySelector(r)??_$$$("respond");t&&s.scrollIntoView({behavior:"smooth"});const i=window.location.protocol+"//"+window.location.host+window.location.pathname;let _="";fcn_urlParams.commentcode&&(_+=`?commentcode=${fcn_urlParams.commentcode}`),n>1&&(_+=_.length>1?`&pg=${n}`:`?pg=${n}`),window.history.pushState({path:i},"",i+_+location.hash)}else c=fcn_buildErrorNotice(e.data.error)})).catch((e=>{c=fcn_buildErrorNotice(e)})).then((()=>{fcn_ajaxCommentsSection.classList.remove("ajax-in-progress"),c&&(o.innerHTML="",o.appendChild(c))}))}function fcn_reloadCommentsPage(e=null){fcn_getCommentSection(null,e,!0)}function fcn_jumpToCommentPage(){const e=parseInt(window.prompt(_x("Enter page number:","Pagination jump prompt.","fictioneer")));e>0&&fcn_reloadCommentsPage(e)}function fcn_setupCommentObserver(){fct_commentsObserver=new IntersectionObserver((([e])=>{e.isIntersecting&&(fcn_getCommentSection(),fct_commentsObserver.disconnect())}),{rootMargin:"400px",threshold:1}),fcn_ajaxCommentsSection&&fct_commentsObserver.observe(fcn_ajaxCommentsSection)}function fcn_loadCommentEarly(){_$$$("comments")&&location.hash.includes("#comment")&&(_$$$("comment")||(fct_commentsObserver.disconnect(),fcn_reloadCommentsPage()))}fcn_theRoot.dataset.ajaxNonce&&!_$$$("fictioneer-ajax-nonce")?fcn_theRoot.addEventListener("nonceReady",(()=>{fcn_setupCommentObserver()})):fcn_setupCommentObserver(),fcn_theRoot.dataset.ajaxNonce&&!_$$$("fictioneer-ajax-nonce")?fcn_theRoot.addEventListener("nonceReady",(()=>{fcn_loadCommentEarly()})):fcn_loadCommentEarly(),_$(".fictioneer-comments")?.addEventListener("click",(e=>{if(e.target.closest("[data-page-jump]"))return void fcn_jumpToCommentPage();const n=e.target.closest("[data-page]");n&&fcn_reloadCommentsPage(n.dataset.page)}));
|
||||
const fcn_ajaxCommentsSection=_$$$("comments");var fct_commentsObserver,fcn_commentStack=[];function fcn_getCommentSection(e=null,n=null,t=!1){if(!fcn_ajaxCommentsSection)return;const o=_$$$("comments");let c,a="",m=_$$$("comment");if(m&&(a=m.value),fcn_ajaxCommentsSection.classList.contains("ajax-in-progress"))return;if(fcn_ajaxCommentsSection.classList.add("ajax-in-progress"),n||(n=fcn_urlParams.pg??1),!fcn_ajaxCommentsSection)return;const s={action:"fictioneer_ajax_get_comment_section",post_id:e??fcn_ajaxCommentsSection.dataset.postId,page:parseInt(n)};fcn_urlParams.commentcode&&(s.commentcode=fcn_urlParams.commentcode),fcn_ajaxGet(s).then((e=>{if(e.success){n=e.data.page;const c=document.createElement("div");if(c.innerHTML=e.data.html,c.querySelector("#comment_post_ID")){c.querySelector("#comment_post_ID").value=e.data.postId,c.querySelector("#cancel-comment-reply-link").href="#respond";const n=c.querySelector(".logout-link");n&&(n.href=_$$$("comments").dataset.logoutUrl)}o.innerHTML=c.innerHTML,c.remove(),m=_$$$("comment"),m&&(m.value=a,fcn_commentStack.forEach((e=>{m.value+=e}))),fcn_commentStack=[],m&&fcn_textareaAdjust(m),fcn_addModerationEvents(),fcn_addCommentMouseleaveEvents(),fcn_addTextareaEvents(),fcn_addCommentFormEvents(),fcn_addPrivateToggleEvents(),fcn_bindAJAXCommentSubmit(),fcn_addJSTrap(),fcn_revealEditButton(),fcn_revealDeleteButton();const s=location.hash.includes("#comment")?location.hash:".respond",r=document.querySelector(s)??_$$$("respond");t&&r.scrollIntoView({behavior:"smooth"});const i=window.location.protocol+"//"+window.location.host+window.location.pathname;let d="";fcn_urlParams.commentcode&&(d+=`?commentcode=${fcn_urlParams.commentcode}`),n>1&&(d+=d.length>1?`&pg=${n}`:`?pg=${n}`),window.history.pushState({path:i},"",i+d+location.hash)}else c=fcn_buildErrorNotice(e.data.error)})).catch((e=>{c=fcn_buildErrorNotice(e)})).then((()=>{fcn_ajaxCommentsSection.classList.remove("ajax-in-progress"),c&&(o.innerHTML="",o.appendChild(c))}))}function fcn_reloadCommentsPage(e=null){fcn_getCommentSection(null,e,!0)}function fcn_jumpToCommentPage(){const e=parseInt(window.prompt(_x("Enter page number:","Pagination jump prompt.","fictioneer")));e>0&&fcn_reloadCommentsPage(e)}function fcn_setupCommentObserver(){fct_commentsObserver=new IntersectionObserver((([e])=>{e.isIntersecting&&(fcn_getCommentSection(),fct_commentsObserver.disconnect())}),{rootMargin:"400px",threshold:1}),fcn_ajaxCommentsSection&&fct_commentsObserver.observe(fcn_ajaxCommentsSection)}function fcn_loadCommentEarly(){_$$$("comments")&&location.hash.includes("#comment")&&(_$$$("comment")||(fct_commentsObserver.disconnect(),fcn_reloadCommentsPage()))}fcn_theRoot.dataset.ajaxNonce?document.addEventListener("fcnAuthReady",(()=>{fcn_setupCommentObserver()})):fcn_setupCommentObserver(),fcn_theRoot.dataset.ajaxNonce?document.addEventListener("fcnAuthReady",(()=>{fcn_loadCommentEarly()})):fcn_loadCommentEarly(),_$(".fictioneer-comments")?.addEventListener("click",(e=>{if(e.target.closest("[data-page-jump]"))return void fcn_jumpToCommentPage();const n=e.target.closest("[data-page]");n&&fcn_reloadCommentsPage(n.dataset.page)}));
|
2
js/application.min.js
vendored
2
js/application.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/comments.min.js
vendored
2
js/comments.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/follows.min.js
vendored
2
js/follows.min.js
vendored
@ -1 +1 @@
|
||||
const fcn_desktopFollowList=_$$$("follow-menu-scroll"),fcn_mobileFollowList=_$$$("mobile-menu-follows-list"),fcn_followsMenuItem=_$$$("follow-menu-button");var fcn_userFollowsTimeout,fcn_follows;function fcn_initializeFollows(o){const t=o.detail.data.follows;!1!==t&&(fcn_follows=t,fcn_updateFollowsView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleFollow(o){const t=fcn_getUserData();if(fcn_follows&&t.follows){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_follows.data[o])!==JSON.stringify(t.follows.data[o]))return fcn_follows=t.follows,fcn_showNotification(__("Follows re-synchronized.","fictioneer")),void fcn_updateFollowsView();fcn_follows.data.hasOwnProperty(o)?delete fcn_follows.data[o]:fcn_follows.data[o]={story_id:parseInt(o),timestamp:Date.now()},t.follows.data[o]=fcn_follows.data[o],t.lastLoaded=0,fcn_setUserData(t),fcn_updateFollowsView(),clearTimeout(fcn_userFollowsTimeout),fcn_userFollowsTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_follow",fcn_fast_ajax:1,story_id:o,set:fcn_follows.data.hasOwnProperty(o)}).then((o=>{o.data.error&&fcn_showNotification(o.data.error,5,"warning")})).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateFollowsView(){if(!fcn_getUserData().follows)return;_$$(".button-follow-story").forEach((o=>{o.classList.toggle("_followed",fcn_follows?.data.hasOwnProperty(o.dataset.storyId))})),_$$(".card").forEach((o=>{o.classList.toggle("has-follow",fcn_follows?.data.hasOwnProperty(o.dataset.storyId))}));const o=parseInt(fcn_follows.new)>0;_$$(".mark-follows-read, .follows-alert-number, .mobile-menu-button").forEach((t=>{t.classList.toggle("_new",o),o>0&&(t.dataset.newCount=fcn_follows.new)}))}function fcn_setupFollowsHTML(){fcn_followsMenuItem.classList.contains("_loaded")||fcn_ajaxGet({action:"fictioneer_ajax_get_follows_notifications",fcn_fast_ajax:1}).then((o=>{o.data.html&&(fcn_desktopFollowList.innerHTML=o.data.html,fcn_mobileFollowList.innerHTML=o.data.html)})).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning"),fcn_desktopFollowList.remove(),fcn_mobileFollowList.remove()})).then((()=>{fcn_followsMenuItem.classList.add("_loaded")}))}function fcn_markFollowsRead(){if(!fcn_followsMenuItem.classList.contains("_new")||!fcn_followsMenuItem.classList.contains("_loaded"))return;_$$(".mark-follows-read, .follows-alert-number, .follow-item, .mobile-menu-button").forEach((o=>{o.classList.remove("_new")}));const o=fcn_getUserData();o.new=0,o.lastLoaded=0,fcn_setUserData(o),fcn_ajaxPost({action:"fictioneer_ajax_mark_follows_read",fcn_fast_ajax:1}).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}document.addEventListener("fcnUserDataReady",(o=>{fcn_initializeFollows(o)})),fcn_followsMenuItem?.addEventListener("mouseover",(()=>{fcn_setupFollowsHTML()}),{once:!0}),fcn_followsMenuItem?.addEventListener("focus",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$('.mobile-menu__frame-button[data-frame-target="follows"]')?.addEventListener("click",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$$(".button-follow-story").forEach((o=>{o.addEventListener("click",(o=>{fcn_toggleFollow(o.currentTarget.dataset.storyId)}))})),_$$(".mark-follows-read").forEach((o=>{o.addEventListener("click",(()=>{fcn_markFollowsRead()}))}));
|
||||
const fcn_desktopFollowList=_$$$("follow-menu-scroll"),fcn_mobileFollowList=_$$$("mobile-menu-follows-list"),fcn_followsMenuItem=_$$$("follow-menu-button");var fcn_userFollowsTimeout,fcn_follows;function fcn_initializeFollows(o){const t=o.detail.data.follows;!1!==t&&(fcn_follows=t,fcn_updateFollowsView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleFollow(o){const t=fcn_getUserData();if(fcn_follows&&t.follows){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_follows.data[o])!==JSON.stringify(t.follows.data[o]))return fcn_follows=t.follows,fcn_showNotification(__("Follows re-synchronized.","fictioneer")),void fcn_updateFollowsView();fcn_follows.data.hasOwnProperty(o)?delete fcn_follows.data[o]:fcn_follows.data[o]={story_id:parseInt(o),timestamp:Date.now()},t.follows.data[o]=fcn_follows.data[o],t.lastLoaded=0,fcn_setUserData(t),fcn_updateFollowsView(),clearTimeout(fcn_userFollowsTimeout),fcn_userFollowsTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_follow",fcn_fast_ajax:1,story_id:o,set:fcn_follows.data.hasOwnProperty(o)}).then((o=>{o.data.error&&fcn_showNotification(o.data.error,5,"warning")})).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateFollowsView(){const o=fcn_getUserData();if(!fcn_follows||!o.follows)return;_$$(".button-follow-story").forEach((o=>{o.classList.toggle("_followed",fcn_follows?.data.hasOwnProperty(o.dataset.storyId))})),_$$(".card").forEach((o=>{o.classList.toggle("has-follow",fcn_follows?.data.hasOwnProperty(o.dataset.storyId))}));const t=parseInt(fcn_follows.new)>0;_$$(".mark-follows-read, .follows-alert-number, .mobile-menu-button").forEach((o=>{o.classList.toggle("_new",t),t>0&&(o.dataset.newCount=fcn_follows.new)}))}function fcn_setupFollowsHTML(){fcn_followsMenuItem.classList.contains("_loaded")||fcn_ajaxGet({action:"fictioneer_ajax_get_follows_notifications",fcn_fast_ajax:1}).then((o=>{o.data.html&&(fcn_desktopFollowList.innerHTML=o.data.html,fcn_mobileFollowList.innerHTML=o.data.html)})).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning"),fcn_desktopFollowList.remove(),fcn_mobileFollowList.remove()})).then((()=>{fcn_followsMenuItem.classList.add("_loaded")}))}function fcn_markFollowsRead(){if(!fcn_followsMenuItem.classList.contains("_new")||!fcn_followsMenuItem.classList.contains("_loaded"))return;_$$(".mark-follows-read, .follows-alert-number, .follow-item, .mobile-menu-button").forEach((o=>{o.classList.remove("_new")}));const o=fcn_getUserData();o.new=0,o.lastLoaded=0,fcn_setUserData(o),fcn_ajaxPost({action:"fictioneer_ajax_mark_follows_read",fcn_fast_ajax:1}).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}document.addEventListener("fcnUserDataReady",(o=>{fcn_initializeFollows(o)})),fcn_followsMenuItem?.addEventListener("mouseover",(()=>{fcn_setupFollowsHTML()}),{once:!0}),fcn_followsMenuItem?.addEventListener("focus",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$('.mobile-menu__frame-button[data-frame-target="follows"]')?.addEventListener("click",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$$(".button-follow-story").forEach((o=>{o.addEventListener("click",(o=>{fcn_toggleFollow(o.currentTarget.dataset.storyId)}))})),_$$(".mark-follows-read").forEach((o=>{o.addEventListener("click",(()=>{fcn_markFollowsRead()}))}));
|
2
js/reminders.min.js
vendored
2
js/reminders.min.js
vendored
@ -1 +1 @@
|
||||
var fcn_userRemindersTimeout,fcn_reminders;function fcn_initializeReminders(e){const t=e.detail.data.reminders;!1!==t&&(fcn_reminders=t,fcn_updateRemindersView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleReminder(e){const t=fcn_getUserData();if(fcn_reminders&&t.reminders){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_reminders.data[e])!==JSON.stringify(t.reminders.data[e]))return fcn_reminders=t.reminders,fcn_showNotification(__("Reminders re-synchronized.","fictioneer")),void fcn_updateRemindersView();fcn_reminders.data.hasOwnProperty(e)?delete fcn_reminders.data[e]:fcn_reminders.data[e]={story_id:parseInt(e),timestamp:Date.now()},t.reminders.data[e]=fcn_reminders.data[e],t.lastLoaded=0,fcn_setUserData(t),fcn_updateRemindersView(),clearTimeout(fcn_userRemindersTimeout),fcn_userRemindersTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_reminder",fcn_fast_ajax:1,story_id:e,set:fcn_reminders.data.hasOwnProperty(e)}).then((e=>{e.data.error&&fcn_showNotification(e.data.error,5,"warning")})).catch((e=>{e.status&&e.statusText&&fcn_showNotification(`${e.status}: ${e.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateRemindersView(){fcn_getUserData().reminders&&(_$$(".button-read-later").forEach((e=>{e.classList.toggle("_remembered",fcn_reminders.data.hasOwnProperty(e.dataset.storyId))})),_$$(".card").forEach((e=>{e.classList.toggle("has-reminder",fcn_reminders?.data.hasOwnProperty(e.dataset.storyId))})))}document.addEventListener("fcnUserDataReady",(e=>{fcn_initializeReminders(e)})),_$$(".button-read-later").forEach((e=>{e.addEventListener("click",(e=>{fcn_toggleReminder(e.currentTarget.dataset.storyId)}))}));
|
||||
var fcn_userRemindersTimeout,fcn_reminders;function fcn_initializeReminders(e){const t=e.detail.data.reminders;!1!==t&&(fcn_reminders=t,fcn_updateRemindersView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleReminder(e){const t=fcn_getUserData();if(fcn_reminders&&t.reminders){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_reminders.data[e])!==JSON.stringify(t.reminders.data[e]))return fcn_reminders=t.reminders,fcn_showNotification(__("Reminders re-synchronized.","fictioneer")),void fcn_updateRemindersView();fcn_reminders.data.hasOwnProperty(e)?delete fcn_reminders.data[e]:fcn_reminders.data[e]={story_id:parseInt(e),timestamp:Date.now()},t.reminders.data[e]=fcn_reminders.data[e],t.lastLoaded=0,fcn_setUserData(t),fcn_updateRemindersView(),clearTimeout(fcn_userRemindersTimeout),fcn_userRemindersTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_reminder",fcn_fast_ajax:1,story_id:e,set:fcn_reminders.data.hasOwnProperty(e)}).then((e=>{e.data.error&&fcn_showNotification(e.data.error,5,"warning")})).catch((e=>{e.status&&e.statusText&&fcn_showNotification(`${e.status}: ${e.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateRemindersView(){const e=fcn_getUserData();fcn_reminders&&e.reminders&&(_$$(".button-read-later").forEach((e=>{e.classList.toggle("_remembered",fcn_reminders.data.hasOwnProperty(e.dataset.storyId))})),_$$(".card").forEach((e=>{e.classList.toggle("has-reminder",fcn_reminders?.data.hasOwnProperty(e.dataset.storyId))})))}document.addEventListener("fcnUserDataReady",(e=>{fcn_initializeReminders(e)})),_$$(".button-read-later").forEach((e=>{e.addEventListener("click",(e=>{fcn_toggleReminder(e.currentTarget.dataset.storyId)}))}));
|
2
js/user.min.js
vendored
2
js/user.min.js
vendored
@ -1 +1 @@
|
||||
function fcn_replaceProfileImage(e,a){const t=e.querySelector(".user-icon");if(t){const n=document.createElement("img");n.classList.add("user-profile-image"),n.src=a,t.remove(),e.appendChild(n)}}function fcn_setProfileImage(e,a=!0){e&&fcn_isValidUrl(e)&&(a&&localStorage.setItem("fcnProfileAvatar",e),_$$("a.subscriber-profile")?.forEach((a=>{fcn_replaceProfileImage(a,e)})))}function fcn_getProfileImage(){let e=localStorage.getItem("fcnProfileAvatar");fcn_isLoggedIn?(fcn_isValidUrl(e)||(e=!1),e?fcn_setProfileImage(e):fcn_getUserAvatar()):localStorage.removeItem("fcnProfileAvatar")}function fcn_getUserAvatar(){fcn_ajaxGet({action:"fictioneer_ajax_get_avatar",fcn_fast_ajax:1}).then((e=>{e.success&&fcn_setProfileImage(e.data.url)})).catch((()=>{fcn_theRoot.dataset.defaultAvatar&&fcn_setProfileImage(fcn_theRoot.dataset.defaultAvatar,!1)}))}var fcn_userData;function fcn_initializeUserData(){fcn_userData=fcn_getUserData(),fcn_fetchUserData()}function fcn_getUserData(){const e=localStorage.getItem("fcnUserData");return e&&fcn_isValidJSONString(e)?JSON.parse(e):{lastLoaded:0,timestamp:0,follows:!1,reminders:!1,checkmarks:!1,bookmarks:{},fingerprint:!1}}function fcn_setUserData(e){localStorage.setItem("fcnUserData",JSON.stringify(e))}function fcn_fetchUserData(){if(fcn_ajaxLimitThreshold<fcn_userData.lastLoaded){const e=new CustomEvent("fcnUserDataReady",{detail:{data:fcn_userData,time:new Date},bubbles:!1,cancelable:!0});document.dispatchEvent(e)}else fcn_ajaxGet({action:"fictioneer_ajax_get_user_data",fcn_fast_ajax:1}).then((e=>{if(e.success){(fcn_userData=e.data).lastLoaded=Date.now();const a=new CustomEvent("fcnUserDataReady",{detail:{data:e.data,time:new Date},bubbles:!0,cancelable:!1});fcn_setUserData(fcn_userData),document.dispatchEvent(a)}else{localStorage.removeItem("fcnUserData"),fcn_userData=!1;const a=new CustomEvent("fcnUserDataFailed",{detail:{response:e,time:new Date},bubbles:!0,cancelable:!1});document.dispatchEvent(a)}})).catch((e=>{localStorage.removeItem("fcnUserData"),fcn_userData=!1;const a=new CustomEvent("fcnUserDataError",{detail:{error:e,time:new Date},bubbles:!0,cancelable:!1});document.dispatchEvent(a)}))}fcn_getProfileImage(),document.addEventListener("DOMContentLoaded",(()=>{fcn_isLoggedIn&&!fcn_userData&&fcn_initializeUserData()}));
|
||||
function fcn_replaceProfileImage(e,a){const t=e.querySelector(".user-icon");if(t){const n=document.createElement("img");n.classList.add("user-profile-image"),n.src=a,t.remove(),e.appendChild(n)}}function fcn_setProfileImage(e,a=!0){e&&fcn_isValidUrl(e)&&(a&&localStorage.setItem("fcnProfileAvatar",e),_$$("a.subscriber-profile")?.forEach((a=>{fcn_replaceProfileImage(a,e)})))}function fcn_getProfileImage(){let e=localStorage.getItem("fcnProfileAvatar");fcn_isLoggedIn?(fcn_isValidUrl(e)||(e=!1),e?fcn_setProfileImage(e):fcn_getUserAvatar()):localStorage.removeItem("fcnProfileAvatar")}function fcn_getUserAvatar(){fcn_ajaxGet({action:"fictioneer_ajax_get_avatar",fcn_fast_ajax:1}).then((e=>{e.success&&fcn_setProfileImage(e.data.url)})).catch((()=>{fcn_theRoot.dataset.defaultAvatar&&fcn_setProfileImage(fcn_theRoot.dataset.defaultAvatar,!1)}))}var fcn_userData;function fcn_initializeUserData(){fcn_userData=fcn_getUserData(),fcn_fetchUserData()}function fcn_getUserData(){return fcn_parseJSON(localStorage.getItem("fcnUserData"))??{lastLoaded:0,timestamp:0,follows:!1,reminders:!1,checkmarks:!1,bookmarks:{},fingerprint:!1}}function fcn_setUserData(e){localStorage.setItem("fcnUserData",JSON.stringify(e))}function fcn_fetchUserData(){if(fcn_ajaxLimitThreshold<fcn_userData.lastLoaded){const e=new CustomEvent("fcnUserDataReady",{detail:{data:fcn_userData,time:new Date},bubbles:!1,cancelable:!0});document.dispatchEvent(e)}else fcn_ajaxGet({action:"fictioneer_ajax_get_user_data",fcn_fast_ajax:1}).then((e=>{if(e.success){(fcn_userData=e.data).lastLoaded=Date.now();const a=new CustomEvent("fcnUserDataReady",{detail:{data:e.data,time:new Date},bubbles:!0,cancelable:!1});fcn_setUserData(fcn_userData),document.dispatchEvent(a)}else{localStorage.removeItem("fcnUserData"),fcn_userData=!1;const a=new CustomEvent("fcnUserDataFailed",{detail:{response:e,time:new Date},bubbles:!0,cancelable:!1});document.dispatchEvent(a)}})).catch((e=>{localStorage.removeItem("fcnUserData"),fcn_userData=!1;const a=new CustomEvent("fcnUserDataError",{detail:{error:e,time:new Date},bubbles:!0,cancelable:!1});document.dispatchEvent(a)}))}!fcn_isLoggedIn&&fcn_theRoot.dataset.ajaxAuth||fcn_getProfileImage(),document.addEventListener("DOMContentLoaded",(()=>{(fcn_isLoggedIn&&!fcn_userData||!fcn_theRoot.dataset.ajaxAuth)&&fcn_initializeUserData()}));
|
2
js/utility.min.js
vendored
2
js/utility.min.js
vendored
File diff suppressed because one or more lines are too long
@ -227,8 +227,7 @@ _$$('.confirm-dialog').forEach(element => {
|
||||
_$('#wp-admin-bar-logout a')?.addEventListener('click', () => {
|
||||
localStorage.removeItem('fcnProfileAvatar');
|
||||
localStorage.removeItem('fcnUserData');
|
||||
localStorage.removeItem('fcnLoginState');
|
||||
localStorage.removeItem('fcnNonce');
|
||||
localStorage.removeItem('fcnAuth');
|
||||
localStorage.removeItem('fcnBookshelfContent');
|
||||
localStorage.removeItem('fcnChapterBookmarks');
|
||||
});
|
||||
|
@ -5,8 +5,8 @@
|
||||
const fcn_bookshelfTarget = _$$$('ajax-bookshelf-target');
|
||||
|
||||
// Initialize
|
||||
if (fcn_theRoot.dataset.ajaxNonce && !_$$$('fictioneer-ajax-nonce')) {
|
||||
fcn_theRoot.addEventListener('nonceReady', () => {
|
||||
if (fcn_theRoot.dataset.ajaxNonce) {
|
||||
document.addEventListener('fcnAuthReady', () => {
|
||||
fcn_updateBookshelfView();
|
||||
});
|
||||
} else {
|
||||
@ -21,15 +21,11 @@ if (fcn_theRoot.dataset.ajaxNonce && !_$$$('fictioneer-ajax-nonce')) {
|
||||
* Get bookshelf content from web storage or create new JSON.
|
||||
*
|
||||
* @since 4.3
|
||||
* @see fcn_isValidJSONString()
|
||||
* @see fcn_parseJSON()
|
||||
*/
|
||||
|
||||
function fcn_getBookshelfContent() {
|
||||
// Get JSON string from web storage
|
||||
const c = localStorage.getItem('fcnBookshelfContent');
|
||||
|
||||
// Parse and return JSON string if valid, otherwise return new JSON
|
||||
return (c && fcn_isValidJSONString(c)) ? JSON.parse(c) : { html: {}, count: {} };
|
||||
return fcn_parseJSON(localStorage.getItem('fcnBookshelfContent')) ?? { html: {}, count: {} };
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@ -77,7 +73,10 @@ function fcn_updateBookshelfView(action = null, page = null, order = null, scrol
|
||||
fcn_bookshelfTarget.classList.remove('ajax-in-progress');
|
||||
fcn_bookshelfTarget.dataset.page = page;
|
||||
_$('.item-number').innerHTML = `(${fcn_bookshelfStorage['count'][action]})`;
|
||||
if (scroll) _$$$('main').scrollIntoView({behavior: 'smooth'});
|
||||
|
||||
if (scroll) {
|
||||
_$$$('main').scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
} else {
|
||||
fcn_fetchBookshelfPart(action, page, order, scroll);
|
||||
}
|
||||
|
@ -198,9 +198,9 @@ function fcn_jumpToCommentPage() {
|
||||
|
||||
var /** @type {IntersectionObserver} */ fct_commentsObserver;
|
||||
|
||||
// In case of nonce deferment
|
||||
if (fcn_theRoot.dataset.ajaxNonce && !_$$$('fictioneer-ajax-nonce')) {
|
||||
fcn_theRoot.addEventListener('nonceReady', () => {
|
||||
// In case of AJAx authentication...
|
||||
if (fcn_theRoot.dataset.ajaxNonce) {
|
||||
document.addEventListener('fcnAuthReady', () => {
|
||||
fcn_setupCommentObserver();
|
||||
});
|
||||
} else {
|
||||
@ -234,9 +234,9 @@ function fcn_setupCommentObserver() {
|
||||
// SCROLL NEW COMMENT INTO VIEW SUBMITTING VIA RELOAD
|
||||
// =============================================================================
|
||||
|
||||
// In case of nonce deferment
|
||||
if (fcn_theRoot.dataset.ajaxNonce && !_$$$('fictioneer-ajax-nonce')) {
|
||||
fcn_theRoot.addEventListener('nonceReady', () => {
|
||||
// In case of AJAx authentication...
|
||||
if (fcn_theRoot.dataset.ajaxNonce) {
|
||||
document.addEventListener('fcnAuthReady', () => {
|
||||
fcn_loadCommentEarly();
|
||||
});
|
||||
} else {
|
||||
|
@ -10,9 +10,7 @@ const /** @const {HTMLElement} */ fcn_theSite = _$$$('site'),
|
||||
/** @const {URLSearchParams} */ fcn_urlSearchParams = new URLSearchParams(window.location.search),
|
||||
/** @const {Object} */ fcn_urlParams = Object.fromEntries(fcn_urlSearchParams.entries()),
|
||||
/** @const {Number} */ fcn_pageLoadTimestamp = Date.now(),
|
||||
/** @const {Number} */ fcn_ajaxLimitThreshold = Date.now() - parseInt(fictioneer_ajax.ttl), // Default: 60 seconds
|
||||
/** @const {Event} */ fcn_eventNonceReady = new Event('nonceReady'),
|
||||
/** @const {Boolean} */ fcn_isAjaxAuth = fcn_theRoot.dataset.ajaxAuth;
|
||||
/** @const {Number} */ fcn_ajaxLimitThreshold = Date.now() - parseInt(fictioneer_ajax.ttl); // Default: 60 seconds
|
||||
|
||||
var /** @type {Object} */ fcn_cssVars = getComputedStyle(document.documentElement),
|
||||
/** @type {Boolean} */ fcn_isLoggedIn = fcn_theBody.classList.contains('logged-in'),
|
||||
@ -33,14 +31,9 @@ if (fcn_chapterList) {
|
||||
// =============================================================================
|
||||
|
||||
// Remove superfluous data and nodes if not logged in
|
||||
if (!fcn_isLoggedIn && !fcn_isAjaxAuth) {
|
||||
if (!fcn_isLoggedIn && !fcn_theRoot.dataset.ajaxAuth) {
|
||||
fcn_cleanupWebStorage(true);
|
||||
|
||||
// Since chapter lists on story pages are globally cached, the checkmarks are
|
||||
// always delivered if enabled regardless of log-in status
|
||||
_$$('.chapter-group__list-item-checkmark').forEach(element => {
|
||||
element.remove();
|
||||
});
|
||||
fcn_cleanupGuestView();
|
||||
}
|
||||
|
||||
// Remove query args (defined in _theme_setup.php)
|
||||
@ -63,19 +56,17 @@ if (typeof fcn_removeQueryArgs === 'function') {
|
||||
function fcn_cleanupWebStorage(keepGuestData = false) {
|
||||
localStorage.removeItem('fcnProfileAvatar');
|
||||
localStorage.removeItem('fcnUserData');
|
||||
localStorage.removeItem('fcnLoginState');
|
||||
localStorage.removeItem('fcnBookshelfContent');
|
||||
|
||||
if (!keepGuestData) {
|
||||
localStorage.removeItem('fcnChapterBookmarks');
|
||||
}
|
||||
|
||||
// Clean up private nonce but keep public nonce
|
||||
let maybeNonce = localStorage.getItem('fcnNonce');
|
||||
maybeNonce = (maybeNonce && fcn_isValidJSONString(maybeNonce)) ? JSON.parse(maybeNonce) : false;
|
||||
// Clean up private authentication data
|
||||
const auth = fcn_parseJSON(localStorage.getItem('fcnAuth'));
|
||||
|
||||
if (maybeNonce && maybeNonce['loggedIn']) {
|
||||
localStorage.removeItem('fcnNonce');
|
||||
if (auth?.loggedIn) {
|
||||
localStorage.removeItem('fcnAuth');
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +76,7 @@ _$('#wp-admin-bar-logout a')?.addEventListener('click', () => {
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// VIEW CLEANUP
|
||||
// GUEST VIEW CLEANUP
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
@ -98,163 +89,155 @@ function fcn_cleanupGuestView() {
|
||||
fcn_isLoggedIn = false;
|
||||
fcn_theBody.classList.remove('logged-in', 'is-admin', 'is-moderator', 'is-editor', 'is-author');
|
||||
|
||||
_$$$('fictioneer-ajax-nonce')?.remove();
|
||||
|
||||
_$$('.only-moderators, .only-admins, .only-authors, .only-editors, .chapter-group__list-item-checkmark').forEach(element => {
|
||||
element.remove()
|
||||
});
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// LOAD NONCE VIA AJAX
|
||||
// AUTHENTICATE VIA AJAX
|
||||
// =============================================================================
|
||||
|
||||
if (fcn_theRoot.dataset.ajaxNonce) {
|
||||
fcn_fetchNonce();
|
||||
}
|
||||
// Initialize
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (fcn_theRoot.dataset.ajaxAuth) {
|
||||
fcn_ajaxAuth();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Fetch nonce via AJAX or web storage.
|
||||
* Authenticate user via AJAX or from web storage
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fcn_fetchNonce() {
|
||||
// Look for recent state in web storage
|
||||
let storage = localStorage.getItem('fcnNonce');
|
||||
function fcn_ajaxAuth() {
|
||||
let eventFired = false;
|
||||
|
||||
storage = (storage && fcn_isValidJSONString(storage)) ? JSON.parse(storage) : false;
|
||||
// Look for recent authentication in web storage
|
||||
let localAuth = fcn_parseJSON(localStorage.getItem('fcnAuth')) ?? false;
|
||||
|
||||
// Clear cached public nonce if any
|
||||
if (storage && !storage['loggedIn'] && fcn_isLoggedIn) {
|
||||
localStorage.removeItem('fcnNonce');
|
||||
storage = false;
|
||||
// Clear left over guest authentication
|
||||
if (fcn_isLoggedIn && !localAuth?.loggedIn) {
|
||||
localStorage.removeItem('fcnAuth');
|
||||
localAuth = false;
|
||||
}
|
||||
|
||||
// Only update from server after some time has passed (e.g. 60 seconds)
|
||||
if (storage) {
|
||||
// Add nonce to DOM
|
||||
fcn_addNonceAndAuth(storage['nonceHtml']);
|
||||
// Authenticate from web storage (if set)...
|
||||
if (localAuth) {
|
||||
fcn_addNonceHTML(localAuth['nonceHtml']);
|
||||
|
||||
// If not timed out, skip server request
|
||||
if (fcn_ajaxLimitThreshold < storage['lastLoaded']) {
|
||||
// Fire fcnAuthReady event
|
||||
const event = new CustomEvent('fcnAuthReady', {
|
||||
detail: {
|
||||
nonceHtml: localAuth['nonceHtml'],
|
||||
nonce: localAuth['nonce'],
|
||||
loggedIn: localAuth['loggedIn'],
|
||||
isAdmin: localAuth['isAdmin'],
|
||||
isModerator: localAuth['isModerator'],
|
||||
isAuthor: localAuth['isAuthor'],
|
||||
isEditor: localAuth['isEditor']
|
||||
},
|
||||
bubbles: true,
|
||||
cancelable: false
|
||||
});
|
||||
|
||||
document.dispatchEvent(event);
|
||||
eventFired = true;
|
||||
|
||||
// ... but refresh from server after some time has passed (e.g. 60 seconds)
|
||||
if (fcn_ajaxLimitThreshold < localAuth.lastLoaded) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load from server
|
||||
// Request nonce via AJAX
|
||||
fcn_ajaxGet({
|
||||
'action': 'fictioneer_ajax_get_nonce',
|
||||
'action': 'fictioneer_ajax_get_auth',
|
||||
'fcn_fast_ajax': 1
|
||||
}).then((response) => {
|
||||
// Remove cached nonce
|
||||
_$$$('fictioneer-ajax-nonce')?.remove();
|
||||
|
||||
}).then(response => {
|
||||
if (response.success) {
|
||||
// Append hidden input with nonce to DOM
|
||||
fcn_addNonceAndAuth(response.data.nonceHtml);
|
||||
fcn_addNonceHTML(response.data.nonceHtml);
|
||||
|
||||
// Unpack
|
||||
const data = {
|
||||
'lastLoaded': Date.now(),
|
||||
'nonceHtml': response.data.nonceHtml,
|
||||
'nonce': response.data.nonce,
|
||||
'loggedIn': response.data.loggedIn,
|
||||
'isAdmin': response.data.isAdmin,
|
||||
'isModerator': response.data.isModerator,
|
||||
'isAuthor': response.data.isAuthor,
|
||||
'isEditor': response.data.isEditor
|
||||
}
|
||||
|
||||
// Fire fcnAuthReady event (if not already done)
|
||||
if (!eventFired) {
|
||||
const event = new CustomEvent('fcnAuthReady', {
|
||||
detail: data,
|
||||
bubbles: true,
|
||||
cancelable: false
|
||||
});
|
||||
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
// Remember to avoid too many requests
|
||||
localStorage.setItem(
|
||||
'fcnNonce',
|
||||
JSON.stringify({ 'lastLoaded': Date.now(), 'nonceHtml': response.data.nonceHtml, 'loggedIn': fcn_isLoggedIn })
|
||||
'fcnAuth',
|
||||
JSON.stringify(data)
|
||||
);
|
||||
} else {
|
||||
// If unsuccessful, clear local data
|
||||
_$$$('fictioneer-ajax-nonce')?.remove();
|
||||
fcn_cleanupGuestView();
|
||||
|
||||
// Fire fcnAuthFailed event
|
||||
const event = new Event('fcnAuthFailed');
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Most likely 403 after likely unsafe logout, clear local data
|
||||
localStorage.removeItem('fcnNonce');
|
||||
_$$$('fictioneer-ajax-nonce')?.remove();
|
||||
localStorage.removeItem('fcnAuth');
|
||||
fcn_cleanupGuestView();
|
||||
|
||||
// Fire fcnAuthError event
|
||||
const event = new Event('fcnAuthError');
|
||||
document.dispatchEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Append hidden input element with nonce to DOM and fetch login state.
|
||||
* Append hidden input element with nonce to DOM.
|
||||
*
|
||||
* @since 5.0
|
||||
* @param {String} nonceHtml - HTML for the hidden input with nonce value.
|
||||
*/
|
||||
|
||||
function fcn_addNonceAndAuth(nonceHtml) {
|
||||
function fcn_addNonceHTML(nonceHtml) {
|
||||
// Remove old (if any)
|
||||
_$$$('fictioneer-ajax-nonce')?.remove();
|
||||
|
||||
// Append hidden input with nonce to DOM
|
||||
const node = document.createElement('div');
|
||||
node.innerHTML += nonceHtml;
|
||||
fcn_theBody.appendChild(node.firstChild);
|
||||
|
||||
// Fire nonceReady event
|
||||
fcn_theRoot.dispatchEvent(fcn_eventNonceReady);
|
||||
|
||||
// Call to fetch login state (if necessary)
|
||||
if (!fcn_isLoggedIn && fcn_isAjaxAuth) {
|
||||
fcn_fetchLoginState();
|
||||
}
|
||||
fcn_theBody.appendChild(fcn_html`${nonceHtml}`);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// UPDATE LOGIN STATE VIA AJAX
|
||||
// UPDATE LOGIN STATE
|
||||
// =============================================================================
|
||||
|
||||
// Only if public caching compatibility mode is active and the nonce is not deferred
|
||||
if (!fcn_isLoggedIn && (typeof fcn_isAjaxAuth !== 'undefined') && !fcn_theRoot.dataset.ajaxNonce) {
|
||||
fcn_fetchLoginState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch login state via AJAX or web storage.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
|
||||
function fcn_fetchLoginState() {
|
||||
// Look for recent state in web storage
|
||||
let storage = localStorage.getItem('fcnLoginState');
|
||||
storage = (storage && fcn_isValidJSONString(storage)) ? JSON.parse(storage) : false;
|
||||
|
||||
// Update from cache to avoid delays but only cache for a short while
|
||||
if (storage && storage['loggedIn']) {
|
||||
// Set logged-in state and call setup functions
|
||||
fcn_setLoggedInState(storage, false); // Do not initialize (happens later in this case)
|
||||
|
||||
// If not timed out, skip server request
|
||||
if (Date.now() - fictioneer_ajax.login_ttl < storage['lastLoaded']) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load from server
|
||||
fcn_ajaxGet({
|
||||
'action': 'fictioneer_ajax_is_user_logged_in',
|
||||
'fcn_fast_ajax': 1
|
||||
}).then((response) => {
|
||||
if (response.success && response.data.loggedIn) {
|
||||
// Update view to logged-in state (beware double initialize!)
|
||||
fcn_setLoggedInState(response.data, !storage['loggedIn']);
|
||||
|
||||
// Remember to avoid too many requests
|
||||
localStorage.setItem(
|
||||
'fcnLoginState',
|
||||
JSON.stringify({
|
||||
'lastLoaded': Date.now(),
|
||||
'loggedIn': response.data.loggedIn,
|
||||
'isAdmin': response.data.isAdmin,
|
||||
'isModerator': response.data.isModerator,
|
||||
'isAuthor': response.data.isAuthor,
|
||||
'isEditor': response.data.isEditor
|
||||
})
|
||||
);
|
||||
// Only if AJAX authentication is active
|
||||
if (!fcn_isLoggedIn && fcn_theRoot.dataset.ajaxAuth) {
|
||||
document.addEventListener('fcnAuthReady', (event) => {
|
||||
if (event.detail.loggedIn) {
|
||||
fcn_setLoggedInState(event.detail);
|
||||
} else {
|
||||
// Cleanup if not logged in (200)
|
||||
fcn_cleanupWebStorage(true);
|
||||
fcn_cleanupGuestView();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Most likely 403 after likely unsafe logout, clear local data
|
||||
fcn_cleanupWebStorage();
|
||||
fcn_cleanupGuestView();
|
||||
});
|
||||
}
|
||||
|
||||
@ -263,10 +246,9 @@ function fcn_fetchLoginState() {
|
||||
*
|
||||
* @since 5.0
|
||||
* @param {Object} state - Fetched/Cached login state.
|
||||
* @param {Boolean} initialize - Whether to call setup functions.
|
||||
*/
|
||||
|
||||
function fcn_setLoggedInState(state, initialize = true) {
|
||||
function fcn_setLoggedInState(state) {
|
||||
// Update state and DOM
|
||||
fcn_isLoggedIn = state.loggedIn;
|
||||
fcn_theBody.classList.add('logged-in');
|
||||
@ -294,11 +276,9 @@ function fcn_setLoggedInState(state, initialize = true) {
|
||||
|
||||
_$$('label[for="modal-login-toggle"], #modal-login-toggle, #login-modal').forEach(element => { element.remove() });
|
||||
|
||||
// Setup local user data, but only if the login state has not been added
|
||||
// synchronous from local storage (avoid double initialize).
|
||||
if (initialize) {
|
||||
fcn_getProfileImage();
|
||||
}
|
||||
// Initialize
|
||||
fcn_initializeUserData();
|
||||
fcn_getProfileImage();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@ -344,8 +324,14 @@ fcn_theBody.addEventListener('click', e => {
|
||||
e.target.classList.contains('toggle-last-clicked')
|
||||
)
|
||||
) {
|
||||
if (typeof fcn_toggleLastClicked === 'function') fcn_toggleLastClicked(lastClickTarget);
|
||||
if (typeof fcn_popupPosition === 'function') fcn_popupPosition();
|
||||
if (typeof fcn_toggleLastClicked === 'function') {
|
||||
fcn_toggleLastClicked(lastClickTarget);
|
||||
}
|
||||
|
||||
if (typeof fcn_popupPosition === 'function') {
|
||||
fcn_popupPosition();
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
@ -731,7 +717,8 @@ function fcn_toggleLightMode() {
|
||||
localStorage.getItem('fcnLightmode') ?
|
||||
localStorage.getItem('fcnLightmode') == 'true' :
|
||||
fcn_theRoot.dataset.modeDefault == 'light';
|
||||
fcn_setLightMode(!current);
|
||||
|
||||
fcn_setLightMode(!current);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -927,7 +914,10 @@ function fcn_setDarkenFromRange() {
|
||||
*/
|
||||
|
||||
function fcn_setDarkenFromText() {
|
||||
if (this.value == '-' || this.value == '') return;
|
||||
if (this.value == '-' || this.value == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
fcn_updateDarken((parseInt(this.value) ?? 0) / 100);
|
||||
}
|
||||
|
||||
@ -1046,23 +1036,21 @@ function fcn_defaultSiteSettings() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site settings JSON from local storage or create new one.
|
||||
* Get site settings JSON from web storage or create new one.
|
||||
*
|
||||
* @since 4.0
|
||||
* @see fcn_isValidJSONString()
|
||||
* @see fcn_parseJSON()
|
||||
* @see fcn_defaultSiteSettings()
|
||||
* @return {Object} The site settings.
|
||||
*/
|
||||
|
||||
function fcn_getSiteSettings() {
|
||||
// Look in local storage...
|
||||
let s = localStorage.getItem('fcnSiteSettings');
|
||||
// Get settings from web storage or use defaults
|
||||
const s = fcn_parseJSON(localStorage.getItem('fcnSiteSettings')) ?? fcn_defaultSiteSettings();
|
||||
|
||||
// ... parse if found, set defaults otherwise
|
||||
s = (s && fcn_isValidJSONString(s)) ? JSON.parse(s) : fcn_defaultSiteSettings();
|
||||
|
||||
// Update local storage and return
|
||||
// Update web storage and return
|
||||
fcn_setSiteSettings(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -1078,7 +1066,9 @@ function fcn_setSiteSettings(value = null) {
|
||||
value = value ? value : fcn_siteSettings;
|
||||
|
||||
// Simple validation
|
||||
if (typeof value !== 'object') return;
|
||||
if (typeof value !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep global updated
|
||||
fcn_siteSettings = value;
|
||||
@ -1216,9 +1206,17 @@ const /** @const {HTMLElement[]} */ fcn_cardLists = _$$('.card-list:not(._no-mut
|
||||
var /** @type {MutationObserver} */ fcn_cardListMutationObserver = new MutationObserver((e) => {
|
||||
if (e[0].addedNodes) {
|
||||
// Update view
|
||||
if (typeof fcn_updateFollowsView === 'function') fcn_updateFollowsView();
|
||||
if (typeof fcn_updateCheckmarksView === 'function') fcn_updateCheckmarksView();
|
||||
if (typeof fcn_updateRemindersView === 'function') fcn_updateRemindersView();
|
||||
if (typeof fcn_updateFollowsView === 'function') {
|
||||
fcn_updateFollowsView();
|
||||
}
|
||||
|
||||
if (typeof fcn_updateCheckmarksView === 'function') {
|
||||
fcn_updateCheckmarksView();
|
||||
}
|
||||
|
||||
if (typeof fcn_updateRemindersView === 'function') {
|
||||
fcn_updateRemindersView();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -918,10 +918,10 @@ const /** @const {HTMLElement} */ fcn_ajaxCommentForm = _$$$('ajax-comment-form-
|
||||
|
||||
// Check whether form target exists...
|
||||
if (fcn_ajaxCommentForm) {
|
||||
// Check for nonce deferment...
|
||||
if (fcn_theRoot.dataset.ajaxNonce && !_$$$('fictioneer-ajax-nonce')) {
|
||||
// In case of AJAx authentication...
|
||||
if (fcn_theRoot.dataset.ajaxNonce) {
|
||||
// Load after nonce has been fetched
|
||||
fcn_theRoot.addEventListener('nonceReady', () => {
|
||||
document.addEventListener('fcnAuthReady', () => {
|
||||
fcn_getCommentForm();
|
||||
});
|
||||
} else {
|
||||
|
@ -131,7 +131,7 @@ function fcn_updateFollowsView() {
|
||||
// Get current data
|
||||
const currentUserData = fcn_getUserData();
|
||||
|
||||
if (!currentUserData.follows) {
|
||||
if (!fcn_follows || !currentUserData.follows) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ function fcn_updateRemindersView() {
|
||||
// Get current data
|
||||
const currentUserData = fcn_getUserData();
|
||||
|
||||
if (!currentUserData.reminders) {
|
||||
if (!fcn_reminders || !currentUserData.reminders) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,9 @@ function fcn_getUserAvatar() {
|
||||
}
|
||||
|
||||
// Initialize
|
||||
fcn_getProfileImage();
|
||||
if (fcn_isLoggedIn || !fcn_theRoot.dataset.ajaxAuth) {
|
||||
fcn_getProfileImage();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// FETCH RELEVANT USER DATA
|
||||
@ -132,10 +134,10 @@ function fcn_initializeUserData() {
|
||||
|
||||
function fcn_getUserData() {
|
||||
// Get JSON string from local storage
|
||||
const data = localStorage.getItem('fcnUserData');
|
||||
const data = fcn_parseJSON(localStorage.getItem('fcnUserData'));
|
||||
|
||||
// Parse and return JSON string if valid, otherwise return new JSON
|
||||
return (data && fcn_isValidJSONString(data)) ? JSON.parse(data) :
|
||||
return data ??
|
||||
{
|
||||
'lastLoaded': 0,
|
||||
'timestamp': 0,
|
||||
@ -223,7 +225,7 @@ function fcn_fetchUserData() {
|
||||
|
||||
// Initialize
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (fcn_isLoggedIn && !fcn_userData) {
|
||||
if ((fcn_isLoggedIn && !fcn_userData) || !fcn_theRoot.dataset.ajaxAuth) {
|
||||
fcn_initializeUserData();
|
||||
}
|
||||
});
|
||||
|
@ -204,30 +204,9 @@ function fcn_copyToClipboard(text, message = false) {
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// JSONS
|
||||
// PARSE JSON
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Is a string a valid JSON?
|
||||
*
|
||||
* @since 4.0
|
||||
* @param {String} str - The string to test.
|
||||
* @return {Boolean} True if valid, false of not.
|
||||
*/
|
||||
|
||||
function fcn_isValidJSONString(str) {
|
||||
if (str === null || typeof str === 'undefined' || typeof str !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
JSON.parse(str);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON and account for invalid strings
|
||||
*
|
||||
@ -617,7 +596,10 @@ function fcn_getCookie(cname) {
|
||||
*/
|
||||
|
||||
function fcn_isValidUrl(url) {
|
||||
if (!url) return false;
|
||||
if (!url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return(url.match(/^(https?:\/\/)/) != null);
|
||||
}
|
||||
|
||||
@ -627,7 +609,7 @@ function fcn_isValidUrl(url) {
|
||||
|
||||
// This nonce is always included in the template file but may not be correct
|
||||
// if caching is active. Some caching plugins can localize nonces if you add
|
||||
// them to a special list. Otherwise use nonce deferment in the options.
|
||||
// them to a special list. Otherwise enable AJAX user authentication.
|
||||
var fcn_defaultNonce = _$$$('fictioneer-nonce')?.value ?? 0;
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user