From 73c03ac21ef14a25d53854dcc5d1193346c6742e Mon Sep 17 00:00:00 2001 From: Dmitry Matiouchenko Date: Fri, 27 Jan 2023 00:17:25 -0800 Subject: [PATCH 01/10] chore: wip + saving indexing change with new index map --- .../gatsby-theme-aio/algolia/index-records.js | 20 +- .../src/components/Layout/index.js | 190 ++++++++++++++++-- yarn.lock | 98 +-------- 3 files changed, 189 insertions(+), 119 deletions(-) diff --git a/packages/gatsby-theme-aio/algolia/index-records.js b/packages/gatsby-theme-aio/algolia/index-records.js index dfbab3a6fa..02db9b2a7c 100644 --- a/packages/gatsby-theme-aio/algolia/index-records.js +++ b/packages/gatsby-theme-aio/algolia/index-records.js @@ -14,10 +14,10 @@ const getImportedContent = require('./helpers/get-imported-content'); const getIFrameContent = require('./helpers/get-iframe-content'); const getOpenApiContent = require('./helpers/get-openapi-content'); const mdxQuery = require('./mdx-query'); +const axios = require('axios').default; const parseHtml = require('./helpers/parse-html'); const parseMdx = require('./helpers/parse-mdx'); const createAlgoliaRecord = require('./create-record'); -const { getProductFromIndex } = require('./helpers/get-products-indexes'); function indexRecords() { return [ @@ -30,6 +30,22 @@ function indexRecords() { allFile: { nodes }, }, }) { + + let productIndexMap; + try { + const result = await axios.get("https://raw.githubusercontent.com/AdobeDocs/search-indices/main/product-index-map.json"); + productIndexMap = result.data; + } catch (error) { + console.error(`AIO: Failed fetching search index.\n${error}`) + process.exit(); + } + + const productFromPath = productIndexMap.find(prod => { + return prod.productIndices.some(index => { + return index.indexPathPrefix.includes(pathPrefix) + }) + }); + const markdownFiles = []; for (const node of nodes) { markdownFiles.push({ @@ -51,7 +67,7 @@ function indexRecords() { objectID: node.id, openAPISpec: node.childMdx.frontmatter.openAPISpec, pathPrefix: `${pathPrefix}/`, - product: getProductFromIndex(repository), + product: productFromPath.productName, size: node.size, slug: node.childMdx.slug, title: node.childMdx.frontmatter.title, diff --git a/packages/gatsby-theme-aio/src/components/Layout/index.js b/packages/gatsby-theme-aio/src/components/Layout/index.js index a7e5b9ce5f..b927fd45ae 100644 --- a/packages/gatsby-theme-aio/src/components/Layout/index.js +++ b/packages/gatsby-theme-aio/src/components/Layout/index.js @@ -117,11 +117,63 @@ const updatePageSrc = (type, frontMatter, setIsLoading) => { } }; +// Used to update the url in the browser +const setQueryStringParameter = (name, value) => { + const params = new URLSearchParams(window.location.search); + params.set(name, value); + window.history.replaceState({}, '', `${window.location.pathname}?${params}`); +}; + +/** + * @returns The query string from the URL + */ + export const getQueryString = () => { + const params = new URLSearchParams(window.location.search); + return params.toString(); +}; + +const setSearchFrameSource = () => { + /** + * Returns expected origin based on the host + * @param {*} host The host + * @param {*} suffix A suffix to append + * @returns The expected origin + */ + const setExpectedOrigin = (host, suffix = '') => { + if (isDevEnvironment(host)) { + return `http://localhost:8000`; + } + if (isStageEnvironment(host)) { + return `https://developer-stage.adobe.com${suffix}`; + } + if (isHlxPath(host)) { + return `${window.location.origin}${suffix}`; + } + return `https://developer.adobe.com${suffix}`; + }; + + /** + * Checks whether the current URL is a dev environment based on host value + * @param {*} host The host + * @returns True if the current URL is a dev environment, false otherwise + */ + function isDevEnvironment(host) { + return host.indexOf('localhost') >= 0; + } + + const src = isDevEnvironment(window.location.host) ? setExpectedOrigin(window.location.host) : `${setExpectedOrigin(window.location.host, '/search-frame')}`; + const queryString = new URLSearchParams(window.location.search); + return queryString && queryString.toString().length > 0 + ? `${src}?${queryString.toString()}` + : src; +}; + export default ({ children, pageContext, location }) => { const [ims, setIms] = useState(null); const [isLoadingIms, setIsLoadingIms] = useState(true); // ["index1", "index2", ...] const [indexAll, setIndexAll] = useState(false); + const [searchPathNameCheck, setSearchPathNameCheck] = useState(""); // Load and initialize IMS useEffect(() => { @@ -151,24 +203,6 @@ export default ({ children, pageContext, location }) => { } }, []); - // Set Search indexAll - useEffect(() => { - if (hasSearch) { - Axios.get("https://raw.githubusercontent.com/AdobeDocs/search-indices/main/product-index-map.json") - .then(result => { - const productIndexMap = result.data; - if (typeof productIndexMap === 'string') { - setIndexAll(JSON.parse(productIndexMap)); - } else if (Object.prototype.toString.call(productIndexMap) == '[object Array]') { // https://stackoverflow.com/a/12996879/15028986 - setIndexAll(productIndexMap); - } - }) - .catch(err => { - console.error(`AIO: Failed fetching search index.\n${err}`) - }) - } - }, []); - // Load all data once and pass it to the Provider const data = useStaticQuery( graphql` @@ -340,7 +374,27 @@ export default ({ children, pageContext, location }) => { updatePageSrc('openAPI', frontMatter, setIsLoading); updatePageSrc('frame', frontMatter, setIsLoading); + // Set Search indexAll + useEffect(() => { + if (hasSearch) { + Axios.get("https://raw.githubusercontent.com/AdobeDocs/search-indices/main/product-index-map.json") + .then(result => { + const productIndexMap = result.data; + if (typeof productIndexMap === 'string') { + setIndexAll(JSON.parse(productIndexMap)); + } else if (Object.prototype.toString.call(productIndexMap) == '[object Array]') { // https://stackoverflow.com/a/12996879/15028986 + setIndexAll(productIndexMap); + } + }) + .catch(err => { + console.error(`AIO: Failed fetching search index.\n${err}`) + }) + } + }, []); + + if (pathPrefix === "/search-frame") { + return ( <> @@ -469,6 +523,86 @@ export default ({ children, pageContext, location }) => { ); } + const searchFrameOnLoad = (renderedFrame, counter = 0, loaded) => { + console.log(searchPathNameCheck); + console.log(window.location.pathname); + renderedFrame.contentWindow.postMessage(JSON.stringify({ localPathName: window.location.pathname }), '*'); + + if (searchPathNameCheck !== window.location.pathname) { + // attempt to establish connection for 3 seconds then time out + if (counter > 30) { + // eslint-disable-next-line no-console + console.warn('Loading Search iFrame timed out'); + return; + } + window.setTimeout(() => { searchFrameOnLoad(renderedFrame, counter + 1, loaded); }, 100); + } + // Past this point we successfully passed the local pathname + // and received a confirmation from the iframe + if (!loaded) { + const queryString = getQueryString(); + if (queryString) { + let searchIframeContainer = document.querySelector('div.nav-console-search-frame'); + if (searchIframeContaine.length > 0) { + searchIframeContainer.style.visibility = 'visible'; + } + } + } + + loaded = true; + }; + + const onMessageReceivedFromIframe = (evt) => { + // const expectedOrigin = setExpectedOrigin(window.location.host); + // if (evt.origin !== expectedOrigin) return; + try { + const message = typeof evt.data === 'string' ? JSON.parse(evt.data) : evt.data; + + if (message.query) { + setQueryStringParameter(SEARCH_PARAMS.query, message.query); + setQueryStringParameter(SEARCH_PARAMS.keywords, message.keywords); + setQueryStringParameter(SEARCH_PARAMS.index, message.index); + } else if (message.received) { + setSearchPathNameCheck(message.received); + } + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + } + } + + // Referenced https://stackoverflow.com/a/10444444/15028986 + const checkIframeLoaded = (renderedFrame) => { + + // Get a handle to the iframe element + const iframeDoc = renderedFrame.contentDocument || renderedFrame.contentWindow.document; + + // Check if loading is complete + if (iframeDoc.readyState === 'complete') { + renderedFrame.onload = () => { + searchFrameOnLoad(renderedFrame); + }; + // The loading is complete, call the function we want executed once the iframe is loaded + return; + } + // If we are here, it is not loaded. + // Set things up so we check the status again in 100 milliseconds + window.setTimeout(checkIframeLoaded, 100); + }; + + useEffect(() => { + window.addEventListener("message", onMessageReceivedFromIframe); + console.log('message received'); + return () => + window.removeEventListener("message", onMessageReceivedFromIframe); + }, []); + + useEffect(() => { + if (showSearch) { + checkIframeLoaded(document.getElementById('searchIframe')); + } + }, [showSearch]) + return ( <> @@ -693,7 +827,23 @@ export default ({ children, pageContext, location }) => { - {hasSearch && showSearch && indexAll && ( + {hasSearch && showSearch && ( + + )} + {/* {hasSearch && showSearch && indexAll && ( { setShowSearch={setShowSearch} searchButtonId={searchButtonId} /> - )} + )} */}
Date: Fri, 27 Jan 2023 02:33:04 -0800 Subject: [PATCH 02/10] feat: local search seems to work but indexPrefix error --- .../src/components/Layout/index.js | 107 ++++++++---------- 1 file changed, 50 insertions(+), 57 deletions(-) diff --git a/packages/gatsby-theme-aio/src/components/Layout/index.js b/packages/gatsby-theme-aio/src/components/Layout/index.js index b927fd45ae..155b37b7d3 100644 --- a/packages/gatsby-theme-aio/src/components/Layout/index.js +++ b/packages/gatsby-theme-aio/src/components/Layout/index.js @@ -127,7 +127,7 @@ const setQueryStringParameter = (name, value) => { /** * @returns The query string from the URL */ - export const getQueryString = () => { +export const getQueryString = () => { const params = new URLSearchParams(window.location.search); return params.toString(); }; @@ -173,7 +173,6 @@ export default ({ children, pageContext, location }) => { const [isLoadingIms, setIsLoadingIms] = useState(true); // ["index1", "index2", ...] const [indexAll, setIndexAll] = useState(false); - const [searchPathNameCheck, setSearchPathNameCheck] = useState(""); // Load and initialize IMS useEffect(() => { @@ -300,6 +299,7 @@ export default ({ children, pageContext, location }) => { const [showSearch, setShowSearch] = useState(false); const [showSideNav, setShowSideNav] = useState(false); const [isLoading, setIsLoading] = useState(false); + const [loadSearchFrame, setLoadSearchFrame] = useState(false); // Show search if search param is set useEffect(() => { @@ -523,47 +523,71 @@ export default ({ children, pageContext, location }) => { ); } - const searchFrameOnLoad = (renderedFrame, counter = 0, loaded) => { - console.log(searchPathNameCheck); - console.log(window.location.pathname); - renderedFrame.contentWindow.postMessage(JSON.stringify({ localPathName: window.location.pathname }), '*'); + let searchPathNameCheck = ""; - if (searchPathNameCheck !== window.location.pathname) { - // attempt to establish connection for 3 seconds then time out - if (counter > 30) { - // eslint-disable-next-line no-console - console.warn('Loading Search iFrame timed out'); - return; + const searchFrameOnLoad = (counter = 0, loaded) => { + const renderedFrame = document.getElementById('searchIframe'); + + renderedFrame.contentWindow.postMessage(JSON.stringify({ localPathName: window.location.pathname }), '*'); + if (window.location.pathname !== '/') { + if (searchPathNameCheck !== window.location.pathname) { + // attempt to establish connection for 3 seconds then time out + if (counter > 30) { + // eslint-disable-next-line no-console + console.warn('Loading Search iFrame timed out'); + return; + } + window.setTimeout(() => { searchFrameOnLoad(renderedFrame, counter + 1, loaded); }, 100); } - window.setTimeout(() => { searchFrameOnLoad(renderedFrame, counter + 1, loaded); }, 100); } // Past this point we successfully passed the local pathname // and received a confirmation from the iframe if (!loaded) { const queryString = getQueryString(); if (queryString) { - let searchIframeContainer = document.querySelector('div.nav-console-search-frame'); - if (searchIframeContaine.length > 0) { - searchIframeContainer.style.visibility = 'visible'; - } + // let searchIframeContainer = document.querySelector('div.nav-console-search-frame'); + // if (searchIframeContainer.length > 0) { + // searchIframeContainer.style.visibility = 'visible'; + // } + setShowSearch(true); } } loaded = true; }; + // Referenced https://stackoverflow.com/a/10444444/15028986 + const checkIframeLoaded = () => { + const renderedFrame = document.getElementById('searchIframe'); + // Get a handle to the iframe element + let iframeDoc; + try { + iframeDoc = renderedFrame.contentDocument; + // Check if loading is complete + if (iframeDoc.readyState === 'complete') { + renderedFrame.onload = () => { + searchFrameOnLoad(); + }; + // The loading is complete, call the function we want executed once the iframe is loaded + return; + } + } catch (error) { + window.setTimeout(checkIframeLoaded, 100); + } + + }; + const onMessageReceivedFromIframe = (evt) => { // const expectedOrigin = setExpectedOrigin(window.location.host); // if (evt.origin !== expectedOrigin) return; try { const message = typeof evt.data === 'string' ? JSON.parse(evt.data) : evt.data; - if (message.query) { setQueryStringParameter(SEARCH_PARAMS.query, message.query); setQueryStringParameter(SEARCH_PARAMS.keywords, message.keywords); setQueryStringParameter(SEARCH_PARAMS.index, message.index); } else if (message.received) { - setSearchPathNameCheck(message.received); + searchPathNameCheck = message.received; } } catch (e) { // eslint-disable-next-line no-console @@ -571,37 +595,16 @@ export default ({ children, pageContext, location }) => { } } - // Referenced https://stackoverflow.com/a/10444444/15028986 - const checkIframeLoaded = (renderedFrame) => { - - // Get a handle to the iframe element - const iframeDoc = renderedFrame.contentDocument || renderedFrame.contentWindow.document; - - // Check if loading is complete - if (iframeDoc.readyState === 'complete') { - renderedFrame.onload = () => { - searchFrameOnLoad(renderedFrame); - }; - // The loading is complete, call the function we want executed once the iframe is loaded - return; - } - // If we are here, it is not loaded. - // Set things up so we check the status again in 100 milliseconds - window.setTimeout(checkIframeLoaded, 100); - }; - useEffect(() => { window.addEventListener("message", onMessageReceivedFromIframe); - console.log('message received'); - return () => - window.removeEventListener("message", onMessageReceivedFromIframe); + if (hasSearch) { + setLoadSearchFrame(true); + } }, []); useEffect(() => { - if (showSearch) { - checkIframeLoaded(document.getElementById('searchIframe')); - } - }, [showSearch]) + checkIframeLoaded(); + }, [loadSearchFrame]) return ( <> @@ -827,7 +830,7 @@ export default ({ children, pageContext, location }) => {
- {hasSearch && showSearch && ( + {hasSearch && loadSearchFrame && ( )} - {/* {hasSearch && showSearch && indexAll && ( - - )} */}
Date: Fri, 27 Jan 2023 14:48:15 -0800 Subject: [PATCH 03/10] feat: iframed search works --- .../src/components/Layout/index.js | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/gatsby-theme-aio/src/components/Layout/index.js b/packages/gatsby-theme-aio/src/components/Layout/index.js index 155b37b7d3..addb88ec2c 100644 --- a/packages/gatsby-theme-aio/src/components/Layout/index.js +++ b/packages/gatsby-theme-aio/src/components/Layout/index.js @@ -132,7 +132,7 @@ export const getQueryString = () => { return params.toString(); }; -const setSearchFrameSource = () => { +const searchIFrameSource = () => { /** * Returns expected origin based on the host * @param {*} host The host @@ -143,13 +143,11 @@ const setSearchFrameSource = () => { if (isDevEnvironment(host)) { return `http://localhost:8000`; } - if (isStageEnvironment(host)) { + else if (isStageEnvironment(host)) { return `https://developer-stage.adobe.com${suffix}`; + } else { + return `https://developer.adobe.com${suffix}`; } - if (isHlxPath(host)) { - return `${window.location.origin}${suffix}`; - } - return `https://developer.adobe.com${suffix}`; }; /** @@ -161,6 +159,16 @@ const setSearchFrameSource = () => { return host.indexOf('localhost') >= 0; } + /** + * Checks whether the current URL is a stage environment based on host value + * @param {*} host The host + * @returns True if the current URL is a stage environment, false otherwise + */ + function isStageEnvironment(host) { + return host.indexOf('developer-stage') >= 0; + } + + const src = isDevEnvironment(window.location.host) ? setExpectedOrigin(window.location.host) : `${setExpectedOrigin(window.location.host, '/search-frame')}`; const queryString = new URLSearchParams(window.location.search); return queryString && queryString.toString().length > 0 @@ -833,7 +841,7 @@ export default ({ children, pageContext, location }) => { {hasSearch && loadSearchFrame && (