Skip to content

Commit

Permalink
Swap cross-origin iframe to cross-origin request
Browse files Browse the repository at this point in the history
I've picked the creative rotation example at random to try out the
createWorklet function here. Unlike the previous commit where you
can do a straight swap between addModule and createWorklet, in this
commit I've removed the iframe completely. As we're relying on the
data being managed by the script-origin I've also had to move the
seedStorage function into the worklet so it is written into the
storage for the content producer instead of the publisher. I've
also set a new click handler for the demo controls, this also loads
the worklet to ensure we write to Shared Storage with the script-
origin.

Whenever we request a worklet from a different origin we need to
set the headers to allow cors and enable cross origin worklets. As
I've removed the iframe, I've moved the controls of the demo into
the invoking page directly (using hbs partials). For the sake of
the demo I've added the global getContentProducerUrl function to
make it easier to check the domain of the content producer within
the JS files for getting the worklet and the ads.

Also, as the demo is no longer being styled within the iframe I've
copied the css styles to the publisher pages.
  • Loading branch information
taraojo committed Oct 29, 2024
1 parent 7a90bb3 commit 27247a6
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 90 deletions.
8 changes: 8 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}
Expand Down
1 change: 1 addition & 0 deletions functions/app/helpers/setup-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = (app, viewName) => {
hbs.engine({
extname: '.hbs',
layoutsDir: path.join(__dirname + '/../../view'),
partialsDir: path.join(__dirname + '/../../view/partials')
})
);

Expand Down
13 changes: 10 additions & 3 deletions functions/view/main.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,16 @@
<link rel='stylesheet' href='https://unpkg.com/open-props/buttons.min.css' />
<link rel='stylesheet' href='index.css' />
<script>
function checkSharedStorage() { if (!('sharedStorage' in window)) {
document.querySelector('.demo__content').style.display = 'none';
document.querySelector('.demo__instructions').style.display = 'inherit'; } }
function getContentProducerUrl() {
return "{{{contentProducerUrl}}}";
}
function checkSharedStorage() {
if (!('sharedStorage' in window)) {
document.querySelector('.demo__content').style.display = 'none';
document.querySelector('.demo__instructions').style.display = 'inherit';
}
}
</script>
</head>

Expand Down
26 changes: 26 additions & 0 deletions functions/view/partials/creativeRotationDemoControls.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div class="demo__controls-section">
<fencedframe id="ad-slot" mode="opaque-ads"></fencedframe>
<div class="demo__controls">
<h5>Demo control</h5>
<div class="demo__buttons-container">
<button
class="mdl-button mdl-js-button mdl-button--raised demo__button"
onclick="setRotationMode('sequential')"
>
Set rotation mode to <br />"Sequential"
</button>
<button
class="mdl-button mdl-js-button mdl-button--raised demo__button"
onclick="setRotationMode('even-distribution')"
>
Set rotation mode to <br />"Even distribution"<br />(~33% / ~33% / ~33%)
</button>
<button
class="mdl-button mdl-js-button mdl-button--raised demo__button"
onclick="setRotationMode('weighted-distribution')"
>
Set rotation mode to <br />"Weighted distribution"<br />(70% / 20% / 10%)
</button>
</div>
</div>
</div>
3 changes: 2 additions & 1 deletion functions/view/publisher-a/creative-rotation.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<h3>Shared storage - Creative rotation demo</h3>
</div>
<div class='demo__content'>
<iframe class='demo__dsp-iframe' src='{{{contentProducerUrl}}}/url-selection/creative-rotation.html'></iframe>
{{> creativeRotationDemoControls}}
<card class='demo__description'>
<h4>Description</h4>
<p>
Expand Down Expand Up @@ -55,6 +55,7 @@
</p>
</card>
</main>
<script src="{{{contentProducerUrl}}}/url-selection/creative-rotation.js"></script>
<script defer>
checkSharedStorage()
</script>
3 changes: 2 additions & 1 deletion functions/view/publisher-b/creative-rotation.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<h3>Shared storage - Creative rotation demo</h3>
</div>
<div class='demo__content'>
<iframe class='demo__dsp-iframe' src='{{{contentProducerUrl}}}/url-selection/creative-rotation.html'></iframe>
{{> creativeRotationDemoControls}}
<card class='demo__description'>
<h4>Description</h4>
<p>
Expand Down Expand Up @@ -55,6 +55,7 @@
</p>
</card>
</main>
<script src="{{{contentProducerUrl}}}/url-selection/creative-rotation.js"></script>
<script defer>
checkSharedStorage()
</script>
21 changes: 21 additions & 0 deletions sites/content-producer/url-selection/creative-rotation-worklet.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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);
69 changes: 0 additions & 69 deletions sites/content-producer/url-selection/creative-rotation.html

This file was deleted.

34 changes: 18 additions & 16 deletions sites/content-producer/url-selection/creative-rotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,51 @@

// 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 }));

// Resolve the selectURL call to a fenced frame config only when it exists on the page
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
});
Expand Down
48 changes: 48 additions & 0 deletions sites/publisher-a/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
49 changes: 49 additions & 0 deletions sites/publisher-b/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 27247a6

Please sign in to comment.