From 5f942a20cb6eef69e89eef97879f311198fd39fb Mon Sep 17 00:00:00 2001 From: Xinyi Feng <105081458+FentPams@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:41:41 -0700 Subject: [PATCH] feat: Add decoration handler for handling fragment decoration (#39) ## Description The fragment decoration needs more logic on handling decorations. We leveraged Eventlistener, at the same time introduce decoration handler on index.js to handle the logic of redecorating. `reDecorateBlocks` function and `buildBlock` fucntion are defined inside of project's script.js, where we need to pass from. ``` export function reDecorateBlocks(el) { if (!el.classList.contains('block')) return; decorateBlock(el); loadBlock(el); } ``` ## Related Issue ## Motivation and Context ## How Has This Been Tested? ## Screenshots (if appropriate): ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) ## Checklist: - [ ] I have signed the [Adobe Open Source CLA](https://opensource.adobe.com/cla.html). - [ ] My code follows the code style of this project. - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have read the **CONTRIBUTING** document. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- README.md | 15 +++++++++++++++ src/index.js | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/README.md b/README.md index 3a997ab..daf5a5d 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,14 @@ runEager.call(document, { // See more details on the dedicated Experiments page linked below experimentsMetaTagPrefix: 'experiment', experimentsQueryParameter: 'experiment', + + /* Fragment experiment needs redecoration */ + // See more details below + decorationFunction: (el) => { + /* handle custom decoration here, for example: */ + buildBlock(el); + decorateBlock(el); + } }); ``` @@ -176,6 +184,13 @@ For detailed implementation instructions on the different features, please read - [Campaigns](/documentation/campaigns.md) - [Experiments](/documentation/experiments.md) +**Cases of passing `decorationFunction`** +Fragment replacement is handled by async observer, which may execute before or after default decoration complete. So, you need to provide a decoration method to redecorate. There are several common cases: +1. Have a selector for an element inside a block and the block needs to be redecorated => sample code above +2. Have a `.block` selector and need to redecorate => switch block status to `"loading"` and call `loadBlock(el)` +3. Have a `.section` selector and need to redecorate => call `decorateBlocks(el)` +4. Have a `main` selector and need to redecorate => call `decorateMain(el)` + ## Extensibility & integrations If you need to further integrate the experimentation plugin with custom analytics reporting or other 3rd-party libraries, you can listen for the `aem:experimentation` event: diff --git a/src/index.js b/src/index.js index 846c1d4..ccf7172 100644 --- a/src/index.js +++ b/src/index.js @@ -43,6 +43,9 @@ export const DEFAULT_OPTIONS = { // Experimentation related properties experimentsMetaTagPrefix: 'experiment', experimentsQueryParameter: 'experiment', + + // Redecoration function for fragments + decorateFunction: () => {}, }; /** @@ -436,6 +439,8 @@ function watchMutationsAndApplyFragments( if (url && new URL(url, window.location.origin).pathname !== window.location.pathname) { // eslint-disable-next-line no-await-in-loop res = await replaceInner(new URL(url, window.location.origin).pathname, el, entry.selector); + // eslint-disable-next-line no-await-in-loop + await pluginOptions.decorateFunction(el); } else { res = url; }