1/** 2 * Detects whether scripting is enabled during login. 3 * 4 * This sets a cookie which demonstrates that JavaScript is currently enabled. This cookie only needs to live until 5 * the 'attach_session_information' filter in PHP runs upon successful login, hence why no expiration is set, so that 6 * the cookie will be removed when the browser session ends. Only when JavaScript is enabled (and the user has checked 7 * "Remember Me") will the bfcache session token cookie be set, and only when this cookie is set will the `no-store` 8 * directive be removed from the `Cache-Control` response header. This is important because the pages in bfcache can 9 * only be invalidated (when a user logs out) when JavaScript is enabled. 10 * 11 * This is a JavaScript module, so the global namespace is not polluted. 12 * 13 * @since 1.2.0 14 */ 15 16/** 17 * Script module ID. 18 * 19 * @since 1.1.0 20 * @type {string} 21 */ 22const moduleId = '@nocache-bfcache/detect-scripting-enabled-at-login'; 23 24/** 25 * JSON script containing the PHP exports. 26 * 27 * @since 1.1.0 28 * @type {HTMLScriptElement} 29 */ 30const jsonScript = /** @type {HTMLScriptElement} */ ( 31 document.getElementById( `wp-script-module-data-${ moduleId }` ) 32); 33 34/** 35 * Exports from PHP. 36 * 37 * @since 1.1.0 38 * @type {{ 39 * cookieName: string, 40 * cookiePath: string, 41 * siteCookiePath: string, 42 * loginPostUrl: string, 43 * }} 44 */ 45const data = JSON.parse( jsonScript.text ); 46 47/** 48 * Gets the form action from the `submit` event. 49 * 50 * @since 1.2.0 51 * @param {SubmitEvent} event - Submit event. 52 * @return {string} Action. 53 */ 54function getFormActionFromSubmitEvent( event ) { 55 if ( 56 event.submitter instanceof HTMLInputElement || 57 event.submitter instanceof HTMLButtonElement 58 ) { 59 /* 60 * > The formAction IDL attribute must reflect the formaction content attribute, except that on getting, when 61 * > the content attribute is missing or its value is the empty string, the element's node document's URL must 62 * > be returned instead. 63 * 64 * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-formaction 65 */ 66 const contentAttribute = event.submitter.getAttribute( 'formaction' ); 67 if ( 68 typeof contentAttribute === 'string' && 69 contentAttribute.trim() !== '' 70 ) { 71 return event.submitter.formAction; 72 } 73 } 74 const form = /** @type {HTMLFormElement} */ ( event.target ); 75 return form.action; 76} 77 78/** 79 * Sets a cookie to indicate JavaScript is enabled when the login form is submitted. 80 * 81 * Note that a hidden input field is not used because plugins like Two Factor may introduce interstitial login screens 82 * which drop hidden fields when redirecting to a final authenticated state. See {@link https://github.com/WordPress/two-factor/issues/705}. 83 * 84 * @since 1.2.0 85 * @param {SubmitEvent} event - Submit event. 86 */ 87function setCookieOnLoginFormSubmit( event ) { 88 const action = new URL( 89 getFormActionFromSubmitEvent( event ), 90 window.location.href 91 ); 92 const loginPostUrl = new URL( data.loginPostUrl, window.location.href ); 93 94 if ( 95 action.origin === loginPostUrl.origin && 96 action.pathname === loginPostUrl.pathname 97 ) { 98 document.cookie = `${ data.cookieName }=1; path=${ data.cookiePath }`; 99 if ( data.cookiePath !== data.siteCookiePath ) { 100 document.cookie = `${ data.cookieName }=1; path=${ data.siteCookiePath }`; 101 } 102 } 103} 104 105document.addEventListener( 'submit', setCookieOnLoginFormSubmit );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.