diff --git a/packages/docusaurus/lib/client/clientEntry.js b/packages/docusaurus/lib/client/clientEntry.js index c26e6a6036..967aec9e65 100644 --- a/packages/docusaurus/lib/client/clientEntry.js +++ b/packages/docusaurus/lib/client/clientEntry.js @@ -16,7 +16,7 @@ import routes from '@generated/routes'; // eslint-disable-line // Client-side render (e.g: running in browser) to become single-page application (SPA). if (typeof window !== 'undefined' && typeof document !== 'undefined') { - window.__docusaurus = docusaurus; + window.docusaurus = docusaurus; // For production, attempt to hydrate existing markup for performant first-load experience. // For development, there is no existing markup so we had to render it. // Note that we also preload async component to avoid first-load loading screen. diff --git a/packages/docusaurus/lib/client/docusaurus.js b/packages/docusaurus/lib/client/docusaurus.js index 3a0e752cc8..7926314f8c 100644 --- a/packages/docusaurus/lib/client/docusaurus.js +++ b/packages/docusaurus/lib/client/docusaurus.js @@ -9,32 +9,10 @@ import routesChunkNames from '@generated/routesChunkNames'; import routes from '@generated/routes'; // eslint-disable-line import prefetchHelper from './prefetch'; import preloadHelper from './preload'; +import flat from './flat'; const fetched = {}; -function flatten(target) { - const delimiter = '.'; - const output = {}; - - function step(object, prev) { - Object.keys(object).forEach(key => { - const value = object[key]; - const isArray = Array.isArray(value); - const type = typeof value; - const isObject = type === 'object' && !!value; - const newKey = prev ? prev + delimiter + key : key; - - if (!isArray && isObject && Object.keys(value).length) { - step(value, newKey); - return; - } - output[newKey] = value; - }); - } - step(target); - return output; -} - const canPrefetchOrLoad = routePath => { // if user is on slow or constrained connection if (`connection` in navigator) { @@ -58,7 +36,7 @@ const docusaurus = { const matches = matchRoutes(routes, routePath); const chunkNamesNeeded = matches.reduce((arr, match) => { const chunkNames = Object.values( - flatten(routesChunkNames[match.route.path]), + flat(routesChunkNames[match.route.path]), ); return arr.concat(chunkNames); }, []); diff --git a/packages/docusaurus/lib/client/exports/Link.js b/packages/docusaurus/lib/client/exports/Link.js index 257b77d76b..b7c7b03726 100644 --- a/packages/docusaurus/lib/client/exports/Link.js +++ b/packages/docusaurus/lib/client/exports/Link.js @@ -42,7 +42,7 @@ function Link(props) { if (IOSupported && ref && isInternal) { // If IO supported and element reference found, setup Observer functionality handleIntersection(ref, () => { - window.__docusaurus.prefetch(targetLink); + window.docusaurus.prefetch(targetLink); }); } }; @@ -50,7 +50,7 @@ function Link(props) { useEffect(() => { // If IO is not supported. We prefetch by default (only once) if (!IOSupported && isInternal) { - window.__docusaurus.prefetch(targetLink); + window.docusaurus.prefetch(targetLink); } // when unmount, stops intersection observer from watching return () => { @@ -66,7 +66,7 @@ function Link(props) { ) : ( window.__docusaurus.preload(targetLink)} + onBreach={() => window.docusaurus.preload(targetLink)} once> diff --git a/packages/docusaurus/lib/client/flat.js b/packages/docusaurus/lib/client/flat.js new file mode 100644 index 0000000000..4d9ee5703a --- /dev/null +++ b/packages/docusaurus/lib/client/flat.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +function flat(target) { + const delimiter = '.'; + const output = {}; + + function step(object, prev) { + Object.keys(object).forEach(key => { + const value = object[key]; + const type = typeof value; + const isObject = type === 'object' && !!value; + const newKey = prev ? prev + delimiter + key : key; + + if (isObject && Object.keys(value).length) { + step(value, newKey); + return; + } + output[newKey] = value; + }); + } + step(target); + return output; +} + +export default flat; diff --git a/packages/docusaurus/test/client/flat.test.js b/packages/docusaurus/test/client/flat.test.js new file mode 100644 index 0000000000..99c0fd0672 --- /dev/null +++ b/packages/docusaurus/test/client/flat.test.js @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import flat from '@lib/client/flat'; + +describe('flat', () => { + test('nested', () => { + expect( + flat({ + foo: { + bar: { + baz: 'lorem ipsum', + }, + }, + }), + ).toEqual({ + 'foo.bar.baz': 'lorem ipsum', + }); + + expect( + flat({ + foo: { + bar: 'baz', + }, + }), + ).toEqual({ + 'foo.bar': 'baz', + }); + }); + + test('primitives', () => { + const primitives = { + String: 'good morning', + Number: 1234.99, + Boolean: true, + Date: new Date(), + null: null, + undefined, + }; + Object.keys(primitives).forEach(key => { + const value = primitives[key]; + expect( + flat({ + foo: { + bar: value, + }, + }), + ).toEqual({ + 'foo.bar': value, + }); + }); + }); + + test('multiple keys', () => { + expect( + flat({ + foo: { + bar: 'baz', + endi: 'lie', + }, + }), + ).toEqual({ + 'foo.bar': 'baz', + 'foo.endi': 'lie', + }); + }); + + test('empty object', () => { + expect( + flat({ + foo: { + bar: {}, + }, + }), + ).toEqual({ + 'foo.bar': {}, + }); + }); + + test('array', () => { + expect( + flat({ + hello: [{world: {again: 'foo'}}, {lorem: 'ipsum'}], + }), + ).toEqual({ + 'hello.0.world.again': 'foo', + 'hello.1.lorem': 'ipsum', + }); + }); +}); diff --git a/website/pages/index.js b/website/pages/index.js index ef4e0d03fd..cfc0275a65 100644 --- a/website/pages/index.js +++ b/website/pages/index.js @@ -68,8 +68,8 @@ function Home() { useEffect(() => { // Prefetch feedback pages & getting started pages - __docusaurus.prefetch(feedbackUrl); - __docusaurus.prefetch(gettingStartedUrl); + window.docusaurus.prefetch(feedbackUrl); + window.docusaurus.prefetch(gettingStartedUrl); }, []); return (