[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 import * as __WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__ from "@wordpress/interactivity"; 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 317: 5 /***/ ((module) => { 6 7 module.exports = import("@wordpress/a11y");; 8 9 /***/ }) 10 11 /******/ }); 12 /************************************************************************/ 13 /******/ // The module cache 14 /******/ var __webpack_module_cache__ = {}; 15 /******/ 16 /******/ // The require function 17 /******/ function __webpack_require__(moduleId) { 18 /******/ // Check if module is in cache 19 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 20 /******/ if (cachedModule !== undefined) { 21 /******/ return cachedModule.exports; 22 /******/ } 23 /******/ // Create a new module (and put it into the cache) 24 /******/ var module = __webpack_module_cache__[moduleId] = { 25 /******/ // no module.id needed 26 /******/ // no module.loaded needed 27 /******/ exports: {} 28 /******/ }; 29 /******/ 30 /******/ // Execute the module function 31 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 32 /******/ 33 /******/ // Return the exports of the module 34 /******/ return module.exports; 35 /******/ } 36 /******/ 37 /************************************************************************/ 38 /******/ /* webpack/runtime/define property getters */ 39 /******/ (() => { 40 /******/ // define getter functions for harmony exports 41 /******/ __webpack_require__.d = (exports, definition) => { 42 /******/ for(var key in definition) { 43 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 44 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 45 /******/ } 46 /******/ } 47 /******/ }; 48 /******/ })(); 49 /******/ 50 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 51 /******/ (() => { 52 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 53 /******/ })(); 54 /******/ 55 /************************************************************************/ 56 var __webpack_exports__ = {}; 57 58 // EXPORTS 59 __webpack_require__.d(__webpack_exports__, { 60 o: () => (/* binding */ actions), 61 w: () => (/* binding */ state) 62 }); 63 64 ;// external "@wordpress/interactivity" 65 var x = (y) => { 66 var x = {}; __webpack_require__.d(x, y); return x 67 } 68 var y = (x) => (() => (x)) 69 const interactivity_namespaceObject = x({ ["getConfig"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getConfig), ["privateApis"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.privateApis), ["store"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.store) }); 70 ;// ./node_modules/@wordpress/interactivity-router/build-module/head.js 71 /** 72 * The cache of prefetched stylesheets and scripts. 73 */ 74 const headElements = new Map(); 75 76 /** 77 * Helper to update only the necessary tags in the head. 78 * 79 * @async 80 * @param newHead The head elements of the new page. 81 */ 82 const updateHead = async newHead => { 83 // Helper to get the tag id store in the cache. 84 const getTagId = tag => tag.id || tag.outerHTML; 85 86 // Map incoming head tags by their content. 87 const newHeadMap = new Map(); 88 for (const child of newHead) { 89 newHeadMap.set(getTagId(child), child); 90 } 91 const toRemove = []; 92 93 // Detect nodes that should be added or removed. 94 for (const child of document.head.children) { 95 const id = getTagId(child); 96 // Always remove styles and links as they might change. 97 if (child.nodeName === 'LINK' || child.nodeName === 'STYLE') { 98 toRemove.push(child); 99 } else if (newHeadMap.has(id)) { 100 newHeadMap.delete(id); 101 } else if (child.nodeName !== 'SCRIPT' && child.nodeName !== 'META') { 102 toRemove.push(child); 103 } 104 } 105 await Promise.all([...headElements.entries()].filter(([, { 106 tag 107 }]) => tag.nodeName === 'SCRIPT').map(async ([url]) => { 108 await import(/* webpackIgnore: true */url); 109 })); 110 111 // Prepare new assets. 112 const toAppend = [...newHeadMap.values()]; 113 114 // Apply the changes. 115 toRemove.forEach(n => n.remove()); 116 document.head.append(...toAppend); 117 }; 118 119 /** 120 * Fetches and processes head assets (stylesheets and scripts) from a specified document. 121 * 122 * @async 123 * @param doc The document from which to fetch head assets. It should support standard DOM querying methods. 124 * 125 * @return Returns an array of HTML elements representing the head assets. 126 */ 127 const fetchHeadAssets = async doc => { 128 const headTags = []; 129 130 // We only want to fetch module scripts because regular scripts (without 131 // `async` or `defer` attributes) can depend on the execution of other scripts. 132 // Scripts found in the head are blocking and must be executed in order. 133 const scripts = doc.querySelectorAll('script[type="module"][src]'); 134 scripts.forEach(script => { 135 const src = script.getAttribute('src'); 136 if (!headElements.has(src)) { 137 // add the <link> elements to prefetch the module scripts 138 const link = doc.createElement('link'); 139 link.rel = 'modulepreload'; 140 link.href = src; 141 document.head.append(link); 142 headElements.set(src, { 143 tag: script 144 }); 145 } 146 }); 147 const stylesheets = doc.querySelectorAll('link[rel=stylesheet]'); 148 await Promise.all(Array.from(stylesheets).map(async tag => { 149 const href = tag.getAttribute('href'); 150 if (!href) { 151 return; 152 } 153 if (!headElements.has(href)) { 154 try { 155 const response = await fetch(href); 156 const text = await response.text(); 157 headElements.set(href, { 158 tag, 159 text 160 }); 161 } catch (e) { 162 // eslint-disable-next-line no-console 163 console.error(e); 164 } 165 } 166 const headElement = headElements.get(href); 167 const styleElement = doc.createElement('style'); 168 styleElement.textContent = headElement.text; 169 headTags.push(styleElement); 170 })); 171 return [doc.querySelector('title'), ...doc.querySelectorAll('style'), ...headTags]; 172 }; 173 174 ;// ./node_modules/@wordpress/interactivity-router/build-module/index.js 175 var _getConfig$navigation; 176 /** 177 * WordPress dependencies 178 */ 179 180 181 /** 182 * Internal dependencies 183 */ 184 185 const { 186 directivePrefix, 187 getRegionRootFragment, 188 initialVdom, 189 toVdom, 190 render, 191 parseServerData, 192 populateServerData, 193 batch 194 } = (0,interactivity_namespaceObject.privateApis)('I acknowledge that using private APIs means my theme or plugin will inevitably break in the next version of WordPress.'); 195 // Check if the navigation mode is full page or region based. 196 const navigationMode = (_getConfig$navigation = (0,interactivity_namespaceObject.getConfig)('core/router').navigationMode) !== null && _getConfig$navigation !== void 0 ? _getConfig$navigation : 'regionBased'; 197 198 // The cache of visited and prefetched pages, stylesheets and scripts. 199 const pages = new Map(); 200 201 // Helper to remove domain and hash from the URL. We are only interesting in 202 // caching the path and the query. 203 const getPagePath = url => { 204 const u = new URL(url, window.location.href); 205 return u.pathname + u.search; 206 }; 207 208 // Fetch a new page and convert it to a static virtual DOM. 209 const fetchPage = async (url, { 210 html 211 }) => { 212 try { 213 if (!html) { 214 const res = await window.fetch(url); 215 if (res.status !== 200) { 216 return false; 217 } 218 html = await res.text(); 219 } 220 const dom = new window.DOMParser().parseFromString(html, 'text/html'); 221 return regionsToVdom(dom); 222 } catch (e) { 223 return false; 224 } 225 }; 226 227 // Return an object with VDOM trees of those HTML regions marked with a 228 // `router-region` directive. 229 const regionsToVdom = async (dom, { 230 vdom 231 } = {}) => { 232 const regions = { 233 body: undefined 234 }; 235 let head; 236 if (false) {} 237 if (navigationMode === 'regionBased') { 238 const attrName = `data-$directivePrefix}-router-region`; 239 dom.querySelectorAll(`[$attrName}]`).forEach(region => { 240 const id = region.getAttribute(attrName); 241 regions[id] = vdom?.has(region) ? vdom.get(region) : toVdom(region); 242 }); 243 } 244 const title = dom.querySelector('title')?.innerText; 245 const initialData = parseServerData(dom); 246 return { 247 regions, 248 head, 249 title, 250 initialData 251 }; 252 }; 253 254 // Render all interactive regions contained in the given page. 255 const renderRegions = async page => { 256 if (false) {} 257 if (navigationMode === 'regionBased') { 258 const attrName = `data-$directivePrefix}-router-region`; 259 batch(() => { 260 populateServerData(page.initialData); 261 document.querySelectorAll(`[$attrName}]`).forEach(region => { 262 const id = region.getAttribute(attrName); 263 const fragment = getRegionRootFragment(region); 264 render(page.regions[id], fragment); 265 }); 266 }); 267 } 268 if (page.title) { 269 document.title = page.title; 270 } 271 }; 272 273 /** 274 * Load the given page forcing a full page reload. 275 * 276 * The function returns a promise that won't resolve, useful to prevent any 277 * potential feedback indicating that the navigation has finished while the new 278 * page is being loaded. 279 * 280 * @param href The page href. 281 * @return Promise that never resolves. 282 */ 283 const forcePageReload = href => { 284 window.location.assign(href); 285 return new Promise(() => {}); 286 }; 287 288 // Listen to the back and forward buttons and restore the page if it's in the 289 // cache. 290 window.addEventListener('popstate', async () => { 291 const pagePath = getPagePath(window.location.href); // Remove hash. 292 const page = pages.has(pagePath) && (await pages.get(pagePath)); 293 if (page) { 294 await renderRegions(page); 295 // Update the URL in the state. 296 state.url = window.location.href; 297 } else { 298 window.location.reload(); 299 } 300 }); 301 302 // Initialize the router and cache the initial page using the initial vDOM. 303 // Once this code is tested and more mature, the head should be updated for 304 // region based navigation as well. 305 if (false) {} 306 pages.set(getPagePath(window.location.href), Promise.resolve(regionsToVdom(document, { 307 vdom: initialVdom 308 }))); 309 310 // Check if the link is valid for client-side navigation. 311 const isValidLink = ref => ref && ref instanceof window.HTMLAnchorElement && ref.href && (!ref.target || ref.target === '_self') && ref.origin === window.location.origin && !ref.pathname.startsWith('/wp-admin') && !ref.pathname.startsWith('/wp-login.php') && !ref.getAttribute('href').startsWith('#') && !new URL(ref.href).searchParams.has('_wpnonce'); 312 313 // Check if the event is valid for client-side navigation. 314 const isValidEvent = event => event && event.button === 0 && 315 // Left clicks only. 316 !event.metaKey && 317 // Open in new tab (Mac). 318 !event.ctrlKey && 319 // Open in new tab (Windows). 320 !event.altKey && 321 // Download. 322 !event.shiftKey && !event.defaultPrevented; 323 324 // Variable to store the current navigation. 325 let navigatingTo = ''; 326 let hasLoadedNavigationTextsData = false; 327 const navigationTexts = { 328 loading: 'Loading page, please wait.', 329 loaded: 'Page Loaded.' 330 }; 331 const { 332 state, 333 actions 334 } = (0,interactivity_namespaceObject.store)('core/router', { 335 state: { 336 url: window.location.href, 337 navigation: { 338 hasStarted: false, 339 hasFinished: false 340 } 341 }, 342 actions: { 343 /** 344 * Navigates to the specified page. 345 * 346 * This function normalizes the passed href, fetches the page HTML if 347 * needed, and updates any interactive regions whose contents have 348 * changed. It also creates a new entry in the browser session history. 349 * 350 * @param href The page href. 351 * @param [options] Options object. 352 * @param [options.force] If true, it forces re-fetching the URL. 353 * @param [options.html] HTML string to be used instead of fetching the requested URL. 354 * @param [options.replace] If true, it replaces the current entry in the browser session history. 355 * @param [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000. 356 * @param [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`. 357 * @param [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`. 358 * 359 * @return Promise that resolves once the navigation is completed or aborted. 360 */ 361 *navigate(href, options = {}) { 362 const { 363 clientNavigationDisabled 364 } = (0,interactivity_namespaceObject.getConfig)(); 365 if (clientNavigationDisabled) { 366 yield forcePageReload(href); 367 } 368 const pagePath = getPagePath(href); 369 const { 370 navigation 371 } = state; 372 const { 373 loadingAnimation = true, 374 screenReaderAnnouncement = true, 375 timeout = 10000 376 } = options; 377 navigatingTo = href; 378 actions.prefetch(pagePath, options); 379 380 // Create a promise that resolves when the specified timeout ends. 381 // The timeout value is 10 seconds by default. 382 const timeoutPromise = new Promise(resolve => setTimeout(resolve, timeout)); 383 384 // Don't update the navigation status immediately, wait 400 ms. 385 const loadingTimeout = setTimeout(() => { 386 if (navigatingTo !== href) { 387 return; 388 } 389 if (loadingAnimation) { 390 navigation.hasStarted = true; 391 navigation.hasFinished = false; 392 } 393 if (screenReaderAnnouncement) { 394 a11ySpeak('loading'); 395 } 396 }, 400); 397 const page = yield Promise.race([pages.get(pagePath), timeoutPromise]); 398 399 // Dismiss loading message if it hasn't been added yet. 400 clearTimeout(loadingTimeout); 401 402 // Once the page is fetched, the destination URL could have changed 403 // (e.g., by clicking another link in the meantime). If so, bail 404 // out, and let the newer execution to update the HTML. 405 if (navigatingTo !== href) { 406 return; 407 } 408 if (page && !page.initialData?.config?.['core/router']?.clientNavigationDisabled) { 409 yield renderRegions(page); 410 window.history[options.replace ? 'replaceState' : 'pushState']({}, '', href); 411 412 // Update the URL in the state. 413 state.url = href; 414 415 // Update the navigation status once the the new page rendering 416 // has been completed. 417 if (loadingAnimation) { 418 navigation.hasStarted = false; 419 navigation.hasFinished = true; 420 } 421 if (screenReaderAnnouncement) { 422 a11ySpeak('loaded'); 423 } 424 425 // Scroll to the anchor if exits in the link. 426 const { 427 hash 428 } = new URL(href, window.location.href); 429 if (hash) { 430 document.querySelector(hash)?.scrollIntoView(); 431 } 432 } else { 433 yield forcePageReload(href); 434 } 435 }, 436 /** 437 * Prefetches the page with the passed URL. 438 * 439 * The function normalizes the URL and stores internally the fetch 440 * promise, to avoid triggering a second fetch for an ongoing request. 441 * 442 * @param url The page URL. 443 * @param [options] Options object. 444 * @param [options.force] Force fetching the URL again. 445 * @param [options.html] HTML string to be used instead of fetching the requested URL. 446 */ 447 prefetch(url, options = {}) { 448 const { 449 clientNavigationDisabled 450 } = (0,interactivity_namespaceObject.getConfig)(); 451 if (clientNavigationDisabled) { 452 return; 453 } 454 const pagePath = getPagePath(url); 455 if (options.force || !pages.has(pagePath)) { 456 pages.set(pagePath, fetchPage(pagePath, { 457 html: options.html 458 })); 459 } 460 } 461 } 462 }); 463 464 /** 465 * Announces a message to screen readers. 466 * 467 * This is a wrapper around the `@wordpress/a11y` package's `speak` function. It handles importing 468 * the package on demand and should be used instead of calling `ally.speak` direacly. 469 * 470 * @param messageKey The message to be announced by assistive technologies. 471 */ 472 function a11ySpeak(messageKey) { 473 if (!hasLoadedNavigationTextsData) { 474 hasLoadedNavigationTextsData = true; 475 const content = document.getElementById('wp-script-module-data-@wordpress/interactivity-router')?.textContent; 476 if (content) { 477 try { 478 const parsed = JSON.parse(content); 479 if (typeof parsed?.i18n?.loading === 'string') { 480 navigationTexts.loading = parsed.i18n.loading; 481 } 482 if (typeof parsed?.i18n?.loaded === 'string') { 483 navigationTexts.loaded = parsed.i18n.loaded; 484 } 485 } catch {} 486 } else { 487 // Fallback to localized strings from Interactivity API state. 488 // @todo This block is for Core < 6.7.0. Remove when support is dropped. 489 490 // @ts-expect-error 491 if (state.navigation.texts?.loading) { 492 // @ts-expect-error 493 navigationTexts.loading = state.navigation.texts.loading; 494 } 495 // @ts-expect-error 496 if (state.navigation.texts?.loaded) { 497 // @ts-expect-error 498 navigationTexts.loaded = state.navigation.texts.loaded; 499 } 500 } 501 } 502 const message = navigationTexts[messageKey]; 503 Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 317)).then(({ 504 speak 505 }) => speak(message), 506 // Ignore failures to load the a11y module. 507 () => {}); 508 } 509 510 // Add click and prefetch to all links. 511 if (false) {} 512 513 var __webpack_exports__actions = __webpack_exports__.o; 514 var __webpack_exports__state = __webpack_exports__.w; 515 export { __webpack_exports__actions as actions, __webpack_exports__state as state };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Sun Mar 9 08:20:01 2025 | Cross-referenced by PHPXref |