| @@ -1,22 +1,5 @@ | ||
| 1 | -/** | |
| 2 | - * WordPress dependencies | |
| 3 | - */ | |
| 4 | -import { escapeHTML } from '@wordpress/escape-html'; | |
| 5 | -import { __, sprintf } from '@wordpress/i18n'; | |
| 6 | - | |
| 7 | -/** | |
| 8 | - * Internal dependencies | |
| 9 | - */ | |
| 10 | -import { | |
| 11 | - ContentHelperError, | |
| 12 | - ContentHelperErrorCode, | |
| 13 | -} from '../content-helper/common/content-helper-error'; | |
| 14 | -import { CheckAuthProvider } from '../content-helper/common/providers/check-auth-provider'; | |
| 15 | - | |
| 16 | 1 | document.addEventListener( 'DOMContentLoaded', (): void => { |
| 17 | - displayContentHelperSectionMessages(); | |
| 18 | - addContentHelperTabEventHandlers(); | |
| 19 | 2 | setActiveTab(); |
| 20 | 3 | window.addEventListener( 'hashchange', setActiveTab ); |
| 21 | 4 | document.querySelector( '.media-single-image button.browse' )?.addEventListener( 'click', selectImage ); |
| 22 | 5 | } ); |
| @@ -67,235 +50,5 @@ | ||
| 67 | 50 | } |
| 68 | 51 | } ); |
| 69 | 52 | |
| 70 | 53 | imageFrame.open(); |
| 71 | -} | |
| 72 | - | |
| 73 | -/** | |
| 74 | - * Adds the necessary event handlers to the Content Helper tab. | |
| 75 | - * | |
| 76 | - * @since 3.16.0 | |
| 77 | - */ | |
| 78 | -function addContentHelperTabEventHandlers(): void { | |
| 79 | - // Selector for the checkbox that enables/disables all AI features. | |
| 80 | - const aiFeaturesCheckbox = document.querySelector<HTMLInputElement>( | |
| 81 | - 'input#content_helper_ai_features_enabled' | |
| 82 | - ); | |
| 83 | - | |
| 84 | - // Selector for the checkboxes that enable/disable individual AI features. | |
| 85 | - const featureCheckboxes = document.querySelectorAll<HTMLInputElement>( | |
| 86 | - 'input#content_helper_smart_linking_enabled, ' + | |
| 87 | - 'input#content_helper_title_suggestions_enabled, ' + | |
| 88 | - 'input#content_helper_excerpt_suggestions_enabled, ' + | |
| 89 | - 'input#content_helper_traffic_boost_enabled' | |
| 90 | - ); | |
| 91 | - | |
| 92 | - // Selector for all fieldsets in the Content Helper section. | |
| 93 | - const fieldsets = document.querySelectorAll( | |
| 94 | - 'div.content-helper-section fieldset' | |
| 95 | - ); | |
| 96 | - | |
| 97 | - // Event handlers. | |
| 98 | - enableAllFormFieldsOnSubmit(); | |
| 99 | - updateAllFeatureSections(); // Must run on load to update the UI. | |
| 100 | - | |
| 101 | - aiFeaturesCheckbox?.addEventListener( 'change', (): void => { | |
| 102 | - updateAllFeatureSections(); | |
| 103 | - } ); | |
| 104 | - | |
| 105 | - featureCheckboxes.forEach( ( checkbox ): void => { | |
| 106 | - checkbox.addEventListener( 'change', (): void => { | |
| 107 | - updateFeatureSection( checkbox ); | |
| 108 | - } ); | |
| 109 | - } ); | |
| 110 | - | |
| 111 | - /** | |
| 112 | - * Turns on/off all AI feature sections in the UI. | |
| 113 | - * | |
| 114 | - * @since 3.16.0 | |
| 115 | - */ | |
| 116 | - function updateAllFeatureSections(): void { | |
| 117 | - if ( ! aiFeaturesCheckbox ) { | |
| 118 | - return; | |
| 119 | - } | |
| 120 | - | |
| 121 | - if ( aiFeaturesCheckbox.checked ) { | |
| 122 | - // Enable all applicable fieldsets. | |
| 123 | - fieldsets.forEach( ( fieldset: Element ): void => { | |
| 124 | - setDisabled( fieldset, false ); | |
| 125 | - | |
| 126 | - featureCheckboxes.forEach( ( checkbox ): void => { | |
| 127 | - updateFeatureSection( checkbox ); | |
| 128 | - } ); | |
| 129 | - } ); | |
| 130 | - } else { | |
| 131 | - // Disable all fieldsets. | |
| 132 | - fieldsets.forEach( ( fieldset: Element ): void => { | |
| 133 | - if ( ! fieldset.querySelector( `#${ aiFeaturesCheckbox.id }` ) ) { | |
| 134 | - setDisabled( fieldset ); | |
| 135 | - } | |
| 136 | - } ); | |
| 137 | - | |
| 138 | - // Disable "Enabled" labels. | |
| 139 | - document.querySelectorAll( 'label.prevent-disable' ) | |
| 140 | - .forEach( ( label: Element ): void => { | |
| 141 | - setPreventDisable( label, false ); | |
| 142 | - } ); | |
| 143 | - } | |
| 144 | - } | |
| 145 | - | |
| 146 | - /** | |
| 147 | - * Turns on/off a specific feature section in the UI. | |
| 148 | - * | |
| 149 | - * @since 3.16.0 | |
| 150 | - * | |
| 151 | - * @param {HTMLInputElement} checkbox The checkbox controlling the feature. | |
| 152 | - */ | |
| 153 | - function updateFeatureSection( checkbox: HTMLInputElement ): void { | |
| 154 | - const userRolesFieldset = checkbox | |
| 155 | - .closest( 'fieldset' )?.nextSibling?.nextSibling as HTMLElement; | |
| 156 | - | |
| 157 | - if ( checkbox.checked ) { | |
| 158 | - setDisabled( [ checkbox, userRolesFieldset ], false ); | |
| 159 | - } else { | |
| 160 | - setDisabled( userRolesFieldset ); | |
| 161 | - | |
| 162 | - // Keep enabled styling on "Enabled" labels for visibility. | |
| 163 | - const enabledLabel = checkbox.parentElement as HTMLLabelElement; | |
| 164 | - setPreventDisable( enabledLabel ); | |
| 165 | - } | |
| 166 | - } | |
| 167 | - | |
| 168 | - /** | |
| 169 | - * Allows or prevents an element from being shown as disabled. | |
| 170 | - * | |
| 171 | - * This is done by injecting a class into the element, which is used in CSS. | |
| 172 | - * | |
| 173 | - * @since 3.16.0 | |
| 174 | - * | |
| 175 | - * @param {Element} element The target element. | |
| 176 | - * @param {boolean} status true to prevent disabled style, false to allow. | |
| 177 | - */ | |
| 178 | - function setPreventDisable( element: Element, status: boolean = true ): void { | |
| 179 | - if ( status ) { | |
| 180 | - element.classList.add( 'prevent-disable' ); | |
| 181 | - } else { | |
| 182 | - element.classList.remove( 'prevent-disable' ); | |
| 183 | - } | |
| 184 | - } | |
| 185 | - | |
| 186 | - /** | |
| 187 | - * Sets the disabled attribute on an element. | |
| 188 | - * | |
| 189 | - * @since 3.16.0 | |
| 190 | - * | |
| 191 | - * @param {Element | Element[]} element The target element. | |
| 192 | - * @param {boolean} status true to disable, false to enable. | |
| 193 | - */ | |
| 194 | - function setDisabled( element: Element | Element[], status: boolean = true ): void { | |
| 195 | - if ( ! Array.isArray( element ) ) { | |
| 196 | - element = [ element ]; | |
| 197 | - } | |
| 198 | - | |
| 199 | - element.forEach( ( el: Element ): void => { | |
| 200 | - if ( status ) { | |
| 201 | - el.setAttribute( 'disabled', 'disabled' ); | |
| 202 | - } else { | |
| 203 | - el.removeAttribute( 'disabled' ); | |
| 204 | - } | |
| 205 | - } ); | |
| 206 | - } | |
| 207 | - | |
| 208 | - /** | |
| 209 | - * Allows the form to post its whole data. | |
| 210 | - * | |
| 211 | - * When elements are disabled, they are not included when submitting the | |
| 212 | - * form, resulting in missing data. | |
| 213 | - * | |
| 214 | - * This workaround removes any disabled attribute so the form can submit its | |
| 215 | - * whole data. It also prevents styling changes while the data is being | |
| 216 | - * submitted, in order to avoid visual glitches. | |
| 217 | - * | |
| 218 | - * @since 3.16.0 | |
| 219 | - */ | |
| 220 | - function enableAllFormFieldsOnSubmit(): void { | |
| 221 | - document.querySelector( '.wp-admin form[name="parsely"]' ) | |
| 222 | - ?.addEventListener( 'submit', (): void => { | |
| 223 | - const baseSelector = '.wp-admin .content-helper-section fieldset'; | |
| 224 | - | |
| 225 | - document.querySelectorAll( `${ baseSelector }[disabled]` ) | |
| 226 | - .forEach( ( fieldset: Element ): void => { | |
| 227 | - // Style the whole setting table row as disabled. | |
| 228 | - fieldset.parentElement?.parentElement?.classList.add( | |
| 229 | - 'disabled-before-posting' | |
| 230 | - ); | |
| 231 | - | |
| 232 | - // Avoid disabled checkbox styling changes. | |
| 233 | - fieldset.querySelectorAll( | |
| 234 | - `${ baseSelector } label input[type="checkbox"]` | |
| 235 | - ).forEach( ( input: Element ): void => { | |
| 236 | - input.classList.add( 'disabled' ); | |
| 237 | - } ); | |
| 238 | - | |
| 239 | - fieldset.removeAttribute( 'disabled' ); | |
| 240 | - } ); | |
| 241 | - } ); | |
| 242 | - } | |
| 243 | -} | |
| 244 | - | |
| 245 | -/** | |
| 246 | - * Displays any messages needed under the Content Helper section. | |
| 247 | - * | |
| 248 | - * @since 3.19.0 | |
| 249 | - */ | |
| 250 | -async function displayContentHelperSectionMessages(): Promise<void> { | |
| 251 | - let message = null; | |
| 252 | - let authResponse = null; | |
| 253 | - | |
| 254 | - try { | |
| 255 | - const [ apiAuth, trafficBoostAuth ] = await Promise.all( [ | |
| 256 | - CheckAuthProvider.getInstance().getAuthorizationResponse( | |
| 257 | - { auth_scope: 'suggestions_api' } | |
| 258 | - ), | |
| 259 | - CheckAuthProvider.getInstance().getAuthorizationResponse( | |
| 260 | - { auth_scope: 'traffic_boost' } | |
| 261 | - ), | |
| 262 | - ] ); | |
| 263 | - | |
| 264 | - authResponse = { | |
| 265 | - api: apiAuth, | |
| 266 | - traffic_boost: trafficBoostAuth, | |
| 267 | - }; | |
| 268 | - } catch ( err: unknown ) { | |
| 269 | - console.error( err ); // eslint-disable-line no-console | |
| 270 | - | |
| 271 | - if ( err instanceof ContentHelperError ) { | |
| 272 | - if ( ContentHelperErrorCode.PluginSettingsApiSecretNotSet === err.code ) { | |
| 273 | - message = sprintf( '<p><strong>%s</strong></p>', escapeHTML( __( 'All Content Helper AI functionality is disabled because an API Secret has not been set.', 'wp-parsely' ) ) ); | |
| 274 | - } | |
| 275 | - } | |
| 276 | - } finally { | |
| 277 | - if ( authResponse ) { | |
| 278 | - if ( 200 !== authResponse.api.code ) { | |
| 279 | - const requestAccessLink = sprintf( '<a href="%1$s" target="_blank" rel="noopener">%2$s</a>', 'https://wpvip.com/content-helper/#content-helper-form', __( 'Request access here', 'wp-parsely' ) ); | |
| 280 | - /* translators: %s: Link to request access to Content Helper AI functionality. */ | |
| 281 | - const messageWithAccessLink = sprintf( escapeHTML( __( 'All Content Helper AI functionality is disabled for this website. %s.', 'wp-parsely' ) ), requestAccessLink ); | |
| 282 | - message = sprintf( '<p><strong>%s</strong></p>', messageWithAccessLink ); | |
| 283 | - } else if ( 200 === authResponse.api.code && 200 !== authResponse.traffic_boost.code ) { | |
| 284 | - const contactSupportLink = sprintf( '<a href="%1$s">%2$s</a>', 'mailto:support@parsely.com', 'support@parsely.com' ); | |
| 285 | - /* translators: %s: Link to request access to Content Helper AI functionality. */ | |
| 286 | - const messageWithAccessLink = sprintf( escapeHTML( __( 'Traffic Boost functionality is disabled for this website. To enable it, contact %s.', 'wp-parsely' ) ), contactSupportLink ); | |
| 287 | - message = sprintf( '<p><strong>%s</strong></p>', messageWithAccessLink ); | |
| 288 | - } | |
| 289 | - } | |
| 290 | - | |
| 291 | - if ( message ) { | |
| 292 | - const div = document.createElement( 'div' ); | |
| 293 | - div.className = 'content-helper-message notice notice-error'; | |
| 294 | - div.innerHTML = message; | |
| 295 | - const contentHelperSection = document.querySelector( '.content-helper-section' ); | |
| 296 | - if ( contentHelperSection ) { | |
| 297 | - contentHelperSection.insertBefore( div, contentHelperSection.firstChild ); | |
| 298 | - } | |
| 299 | - } | |
| 300 | - } | |
| 301 | 54 | } |