diff --git a/firebase.json b/firebase.json index 4d94824..198ef62 100644 --- a/firebase.json +++ b/firebase.json @@ -70,6 +70,14 @@ { "key": "Supports-Loading-Mode", "value": "fenced-frame" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Shared-Storage-Cross-Origin-Worklet-Allowed", + "value": "?1" } ] } diff --git a/functions/app/helpers/setup-view.js b/functions/app/helpers/setup-view.js index 5ab32af..5b9407d 100644 --- a/functions/app/helpers/setup-view.js +++ b/functions/app/helpers/setup-view.js @@ -25,6 +25,7 @@ module.exports = (app, viewName) => { hbs.engine({ extname: '.hbs', layoutsDir: path.join(__dirname + '/../../view'), + partialsDir: path.join(__dirname + '/../../view/partials') }) ); diff --git a/functions/view/main.hbs b/functions/view/main.hbs index 3c13b09..a872f06 100644 --- a/functions/view/main.hbs +++ b/functions/view/main.hbs @@ -31,9 +31,16 @@ diff --git a/functions/view/partials/creativeRotationDemoControls.hbs b/functions/view/partials/creativeRotationDemoControls.hbs new file mode 100644 index 0000000..e32cbd1 --- /dev/null +++ b/functions/view/partials/creativeRotationDemoControls.hbs @@ -0,0 +1,26 @@ +
+ +
+
Demo control
+
+ + + +
+
+
\ No newline at end of file diff --git a/functions/view/publisher-a/creative-rotation.hbs b/functions/view/publisher-a/creative-rotation.hbs index ae4853b..2098845 100644 --- a/functions/view/publisher-a/creative-rotation.hbs +++ b/functions/view/publisher-a/creative-rotation.hbs @@ -13,7 +13,7 @@

Shared storage - Creative rotation demo

- + {{> creativeRotationDemoControls}}

Description

@@ -55,6 +55,7 @@

+ diff --git a/functions/view/publisher-b/creative-rotation.hbs b/functions/view/publisher-b/creative-rotation.hbs index 4908500..249ed6b 100644 --- a/functions/view/publisher-b/creative-rotation.hbs +++ b/functions/view/publisher-b/creative-rotation.hbs @@ -13,7 +13,7 @@

Shared storage - Creative rotation demo

- + {{> creativeRotationDemoControls}}

Description

@@ -55,6 +55,7 @@

+ diff --git a/sites/content-producer/url-selection/ab-testing.js b/sites/content-producer/url-selection/ab-testing.js index 576fbe7..bf54113 100644 --- a/sites/content-producer/url-selection/ab-testing.js +++ b/sites/content-producer/url-selection/ab-testing.js @@ -42,7 +42,9 @@ function getRandomExperiment() { async function injectAd() { // Load the worklet module - await window.sharedStorage.worklet.addModule('ab-testing-worklet.js'); + const abTestingWorklet = await window.sharedStorage.createWorklet( + 'ab-testing-worklet.js' + ); // Set the initial value in the storage to a random experiment group window.sharedStorage.set('ab-testing-group', getRandomExperiment(), { @@ -56,7 +58,7 @@ async function injectAd() { const resolveToConfig = typeof window.FencedFrameConfig !== 'undefined'; // Run the URL selection operation to select an ad based on the experiment group in shared storage - const selectedUrl = await window.sharedStorage.selectURL('ab-testing', urls, { + const selectedUrl = await abTestingWorklet.selectURL('ab-testing', urls, { data: groups, resolveToConfig, keepAlive: true, @@ -71,7 +73,7 @@ async function injectAd() { } // Run the reporting operation - await window.sharedStorage.run('experiment-group-reporting') + await abTestingWorklet.run('experiment-group-reporting') } injectAd(); diff --git a/sites/content-producer/url-selection/creative-rotation-worklet.js b/sites/content-producer/url-selection/creative-rotation-worklet.js index d276d9c..2bb9ef1 100644 --- a/sites/content-producer/url-selection/creative-rotation-worklet.js +++ b/sites/content-producer/url-selection/creative-rotation-worklet.js @@ -16,6 +16,9 @@ class SelectURLOperation { async run(urls, data) { + // Initially set the storage to sequential mode for the demo + await SelectURLOperation.seedStorage(); + // Read the rotation mode from Shared Storage const rotationMode = await sharedStorage.get('creative-rotation-mode'); @@ -77,7 +80,25 @@ class SelectURLOperation { console.log(JSON.stringify({ index, randomNumber, rotationMode })); return index; } + + // Set the mode to sequential and set the starting index to 0. + static async seedStorage() { + await sharedStorage.set('creative-rotation-mode', 'sequential', { + ignoreIfPresent: true, + }); + + await sharedStorage.set('creative-rotation-index', 0, { + ignoreIfPresent: true, + }); + } +} + +class SetRotationModeOperation { + async run({ rotationMode }) { + await sharedStorage.set('creative-rotation-mode', rotationMode); + } } // Register the operation as 'creative-rotation' register('creative-rotation', SelectURLOperation); +register('set-rotation-mode', SetRotationModeOperation); diff --git a/sites/content-producer/url-selection/creative-rotation.html b/sites/content-producer/url-selection/creative-rotation.html deleted file mode 100644 index 0dcfd77..0000000 --- a/sites/content-producer/url-selection/creative-rotation.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - Shared storage demo - - - - - - - - - - - - -
-
Demo control
-
- - - -
-
- - diff --git a/sites/content-producer/url-selection/creative-rotation.js b/sites/content-producer/url-selection/creative-rotation.js index 845d90d..5f0db96 100644 --- a/sites/content-producer/url-selection/creative-rotation.js +++ b/sites/content-producer/url-selection/creative-rotation.js @@ -16,41 +16,43 @@ // For demo purposes. The hostname is used to determine the usage of // development localhost URL vs production URL -const contentProducerUrl = window.location.host; +const contentProducerUrl = window.getContentProducerUrl(); // Ad confg with the URL of the ad, a probability weight for rotation, and the clickthrough rate. const DEMO_AD_CONFIG = [ { - url: `https://${contentProducerUrl}/ads/ad-1.html`, + url: `${contentProducerUrl}/ads/ad-1.html`, weight: 0.7, }, { - url: `https://${contentProducerUrl}/ads/ad-2.html`, + url: `${contentProducerUrl}/ads/ad-2.html`, weight: 0.2, }, { - url: `https://${contentProducerUrl}/ads/ad-3.html`, + url: `${contentProducerUrl}/ads/ad-3.html`, weight: 0.1, }, ]; -// Set the mode to sequential and set the starting index to 0. -async function seedStorage() { - await window.sharedStorage.set('creative-rotation-mode', 'sequential', { - ignoreIfPresent: true, - }); +async function setRotationMode(rotationMode) { + // Load the worklet module + const creativeRotationWorklet = await window.sharedStorage.createWorklet( + `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`, + { dataOrigin: 'script-origin' } + ); - await window.sharedStorage.set('creative-rotation-index', 0, { - ignoreIfPresent: true, + await creativeRotationWorklet.run('set-rotation-mode', { + data: { rotationMode } }); + console.log(`creative rotation mode set to ${rotationMode}`); } async function injectAd() { // Load the worklet module - await window.sharedStorage.worklet.addModule('creative-rotation-worklet.js'); - - // Initially set the storage to sequential mode for the demo - seedStorage(); + const creativeRotationWorklet = await window.sharedStorage.createWorklet( + `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`, + { dataOrigin: 'script-origin' } + ); const urls = DEMO_AD_CONFIG.map(({ url }) => ({ url })); @@ -58,7 +60,7 @@ async function injectAd() { const resolveToConfig = typeof window.FencedFrameConfig !== 'undefined'; // Run the URL selection operation to determine the next ad that should be rendered - const selectedUrl = await window.sharedStorage.selectURL('creative-rotation', urls, { + const selectedUrl = await creativeRotationWorklet.selectURL('creative-rotation', urls, { data: DEMO_AD_CONFIG, resolveToConfig }); diff --git a/sites/publisher-a/index.css b/sites/publisher-a/index.css index 181a4a7..5bdb461 100644 --- a/sites/publisher-a/index.css +++ b/sites/publisher-a/index.css @@ -105,3 +105,51 @@ card { background-color: var(--orange-9); } } + +.demo__controls-section { + width: 300px; +} +#ad-slot { + height: 250px; + border: none; +} + +#button-slot { + height: 100px; + border: none; +} + +.demo__card, +.demo__controls { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--size-2); + background: var(--surface-3); + border: 1px solid var(--surface-1); + padding: var(--size-3); + margin: var(--size-3) 0; + border-radius: var(--radius-3); + box-shadow: var(--shadow-2); + margin-top: 0; +} + +.demo__controls h5 { + margin-bottom: var(--size-2); +} + +.demo__buttons-container { + display: flex; + flex-direction: column; + width: fit-content; +} + +.demo__button { + zoom: 90%; + /* max-width: var(--size-13); */ + --_bg: linear-gradient(var(--indigo-5), var(--indigo-7)); + --_border: var(--indigo-6); + --_text: var(--indigo-0); + --_ink-shadow: 0 1px 0 var(--indigo-9); + margin: 5px; +} diff --git a/sites/publisher-b/index.css b/sites/publisher-b/index.css index 6ef5157..ce7a9f5 100644 --- a/sites/publisher-b/index.css +++ b/sites/publisher-b/index.css @@ -101,3 +101,52 @@ card { background-color: var(--orange-9); } } + +.demo__controls-section { + width: 300px; +} + +#ad-slot { + height: 250px; + border: none; +} + +#button-slot { + height: 100px; + border: none; +} + +.demo__card, +.demo__controls { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--size-2); + background: var(--surface-3); + border: 1px solid var(--surface-1); + padding: var(--size-3); + margin: var(--size-3) 0; + border-radius: var(--radius-3); + box-shadow: var(--shadow-2); + margin-top: 0; +} + +.demo__controls h5 { + margin-bottom: var(--size-2); +} + +.demo__buttons-container { + display: flex; + flex-direction: column; + width: fit-content; +} + +.demo__button { + zoom: 90%; + /* max-width: var(--size-13); */ + --_bg: linear-gradient(var(--indigo-5), var(--indigo-7)); + --_border: var(--indigo-6); + --_text: var(--indigo-0); + --_ink-shadow: 0 1px 0 var(--indigo-9); + margin: 5px; +}