From ddb1ae5f40fccc8c7eae221c10734d4e5c4b620c Mon Sep 17 00:00:00 2001 From: sanderelias Date: Mon, 8 Jun 2020 13:49:58 +0200 Subject: [PATCH] feat(monorepo): add option to flashPrevention so set other display type When fhasl prevention is done, it sets the type to 'inherit'. This pr adds an option to set it to anything you need. ISSUES CLOSED: #608 --- libs/scully-plugin-flash-prevention/README.md | 103 +++++++++++++++++- .../package.json | 2 +- .../src/lib/flash-prevention.plugin.ts | 12 +- 3 files changed, 109 insertions(+), 8 deletions(-) diff --git a/libs/scully-plugin-flash-prevention/README.md b/libs/scully-plugin-flash-prevention/README.md index aad1443c5..75d178b64 100644 --- a/libs/scully-plugin-flash-prevention/README.md +++ b/libs/scully-plugin-flash-prevention/README.md @@ -1,7 +1,102 @@ -# scully-plugin-flash-prevention +# ScullyPluginFlashPrevention -This library was generated with [Nx](https://nx.dev). +The `scully-plugin-flash-prevention` is a postRenderer that helps you hide any flashes that your +app may be experiencing once you add Scully to your project. -## Running unit tests +After adding Scully, your app will appear instantly because the pre-rendered HTML and CSS is +immediately available. After appearing instantly, the JavaScript and CSS files will download and +then your Angular app will bootstrap (init). When it bootstraps, the pre-rendered version may +disappear for a moment, and then once the app is ready, the view will re-appear. This +disappearing-then-appearing is very normal for apps that are pre-rendered on a server. This +project is to prevent that. -Run `ng test scully-plugin-flash-prevention` to execute the unit tests via [Jest](https://jestjs.io). +This project shows the pre-rendered copy of your app until your app is fully render and the +flash is over. It then shows your app and deletes the copy. + +### How it works + +Before this plugin, you app would pre-render and then save to file, like this: + +```html + + // The entire content of your app here + +``` + +After this plugin, you will see the following in your pre-rendered template: + +```html + + + // The entire content of your app here + +``` + +This `app-root-scully` will be the pre-rendered copy of your app. Prior to your app being +rendered fully, `app-root` will be hidden and `app-root-scully` will be displayed. Once your +app has fully bootstrapped, `app-root-scully` will be hidden and then 100ms later removed +from the DOM. The mechanism that shows and hides these two is CSS. There is some CSS added +during the Scully build that looks like the following: + +```css +body:not(.loaded) app-root { + display: none; +} +body.loaded app-root-scully { + display: inherit; +} +``` + +Once the app has been fully loaded, the `loaded` class is added to the `` tag. + +And that's how it all works!!! + +## Getting Started + +**1 -** Install the package: `npm install -D scully-plugin-flash-prevention` + +**2 -** Add the postRenderer to your `scully.config`: + +```javascript +// Add this line to your imports +const { getFlashPreventionPlugin } = require('scully-plugin-flash-prevention'); + +// Add the following to your `scully.config.postRenderers` +exports.config = { + ... + postRenderers : [getFlashPreventionPlugin({appRootSelector: 'custom-app-root'})], + ... +} +``` + +You only need to pass the `{appRootSelector: 'custom-app-root'}` if your app has a selector other +than `app-root`. It is defaulted to `app-root`. + +**3 -** Update `app.module` to include `alwaysMonitor` in the `ScullyLibModule.forRoot` call. + +```typescript +ScullyLibModule.forRoot({ + useTransferState: true, + alwaysMonitor: true, <-- Add this line to your `app.module.ts` +}); +``` + +**4 -** Apply any styles from `app-root` to `app-root-scully` as well. Any styles that are in your +`app.component.(css|scss|less)` need to be applied to the copy of your app that was made. This means +that you need to possibly move any styles that apply to the `app-root` specifically, and put them +in a location where you can also make those styles apply to `app-root-scully` as well. See here: + +```css +// BEFORE +app-root { + ... some styles; +} + +// AFTER +app-root, +app-root-scully { + ... some styles; +} +``` + +That's all it takes to get set up. diff --git a/libs/scully-plugin-flash-prevention/package.json b/libs/scully-plugin-flash-prevention/package.json index 1082e75fe..ab5c3d12c 100644 --- a/libs/scully-plugin-flash-prevention/package.json +++ b/libs/scully-plugin-flash-prevention/package.json @@ -1,6 +1,6 @@ { "name": "scully-plugin-flash-prevention", - "version": "0.0.37", + "version": "0.0.38", "peerDependencies": { "@scullyio/scully": "^0.0.78" }, diff --git a/libs/scully-plugin-flash-prevention/src/lib/flash-prevention.plugin.ts b/libs/scully-plugin-flash-prevention/src/lib/flash-prevention.plugin.ts index 3b518ae9d..eded61f6d 100644 --- a/libs/scully-plugin-flash-prevention/src/lib/flash-prevention.plugin.ts +++ b/libs/scully-plugin-flash-prevention/src/lib/flash-prevention.plugin.ts @@ -4,6 +4,7 @@ import { appendToHead } from './utils'; let AppRootSelector = 'app-root'; let LoadedClass = 'loaded'; +let DisplayType = 'inherit'; const FlashPrevention = 'ScullyPluginFlashPrevention'; const AppRootAttrsBlacklist = ['_nghost', 'ng-version']; const MockRootAttrsBlacklist = []; @@ -14,6 +15,7 @@ registerPlugin('router', FlashPrevention, async ur => [{ route: ur }]); interface FlashPreventionPluginOptions { appRootSelector?: string; appLoadedClass?: string; + displayType?: string; appRootAttributesBlacklist?: string[]; mockAttributesBlacklist?: string[]; } @@ -22,7 +24,8 @@ export function getFlashPreventionPlugin({ appRootSelector, appLoadedClass, appRootAttributesBlacklist, - mockAttributesBlacklist + mockAttributesBlacklist, + displayType }: FlashPreventionPluginOptions = {}) { if (appRootSelector) { AppRootSelector = appRootSelector; @@ -30,6 +33,9 @@ export function getFlashPreventionPlugin({ if (appLoadedClass) { LoadedClass = appLoadedClass; } + if (displayType) { + DisplayType = displayType; + } pushItemsToArray(appRootAttributesBlacklist, AppRootAttrsBlacklist); pushItemsToArray(mockAttributesBlacklist, MockRootAttrsBlacklist); @@ -87,8 +93,8 @@ async function addBitsToHead(html) { `;