Skip to content

Commit

Permalink
🏗 Add specific RTV opt-in to experiments.html (#26434)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielrozenberg authored Jan 23, 2020
1 parent a9369d5 commit 7f4d134
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 20 deletions.
44 changes: 44 additions & 0 deletions tools/experiments/experiments.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@
min-width: 60px;
}

details {
border: solid 1px gray;
margin-top: 5px;
padding: 10px;
}

details summary {
color: gray;
cursor: pointer;
}

details[open] summary {
color: inherit;
}

#subdomain {
color: gray;
font-family: 'Courier New', Courier, monospace;
Expand Down Expand Up @@ -112,6 +127,21 @@
display: block;
}

#rtv {
border: solid 1px gray;
width: calc(100% - 150px);
padding: 10px;
}

#rtv-submit {
background: #aaa;
margin: 5px;
}

#rtv-submit[disabled] {
color: #777;
}

#redirect > input {
border: solid 1px gray;
width: calc(100% - 20px);
Expand Down Expand Up @@ -218,6 +248,20 @@ <h2>Release channels</h2>

<section class="content">
<table id="channels-table" border=1></table>
<details id="rtv-details">
<summary>Advanced</summary>
<p>
You can manually opt in to a previously released RTV using this form.
</p>
<p>
<em>Warning:</em> This is an advanced setting. It is intended for use while debugging AMP runtime code, and is
not meant to be used to publish AMP documents. To opt out of this setting, clear the RTV in the input field.
</p>
<div>
<input id="rtv" placeholder="E.g., 011912312359590" maxlength="15" type="text">
<button id="rtv-submit" disabled>opt-in</button>
</div>
</detail>
</section>

<!-- Only displayed on top-level cdn.ampproject.org. -->
Expand Down
78 changes: 58 additions & 20 deletions tools/experiments/experiments.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ setReportError(reportError);
const COOKIE_MAX_AGE_DAYS = 180; // 6 month
const MS_PER_DAY = 24 * 60 * 60 * 1000;
const COOKIE_MAX_AGE_MS = COOKIE_MAX_AGE_DAYS * MS_PER_DAY;
const RTV_COOKIE_MAX_AGE_MS = MS_PER_DAY / 2;

const RTV_PATTERN = /^\d{15}$/;

/**
* @typedef {{
* id: string,
Expand All @@ -49,8 +53,9 @@ let ExperimentDef;
* interpreted by the server to deliver a different version of the AMP
* JS libraries.
*/
const CANARY_EXPERIMENT_ID = 'dev-channel';
const RC_EXPERIMENT_ID = 'rc-channel';
const EXPERIMENTAL_CHANNEL_ID = 'experimental-channel';
const BETA_CHANNEL_ID = 'beta-channel';
const RTV_CHANNEL_ID = 'rtv-channel';

/**
* The different states of the AMP_CANARY cookie.
Expand All @@ -65,15 +70,15 @@ const AMP_CANARY_COOKIE = {
const CHANNELS = [
// Experimental Channel
{
id: CANARY_EXPERIMENT_ID,
id: EXPERIMENTAL_CHANNEL_ID,
name: 'AMP Experimental Channel (more info)',
spec:
'https://github.com/ampproject/amphtml/blob/master/' +
'contributing/release-schedule.md#amp-experimental-and-beta-channels',
},
// Beta Channel
{
id: RC_EXPERIMENT_ID,
id: BETA_CHANNEL_ID,
name: 'AMP Beta Channel (more info)',
spec:
'https://github.com/ampproject/amphtml/blob/master/' +
Expand Down Expand Up @@ -138,6 +143,32 @@ function build() {
} else {
redirect.setAttribute('hidden', '');
}

const rtvInput = document.getElementById('rtv');
const rtvButton = document.getElementById('rtv-submit');
rtvInput.addEventListener('input', () => {
rtvButton.disabled = rtvInput.value && !RTV_PATTERN.test(rtvInput.value);
rtvButton.textContent = rtvInput.value ? 'opt-in' : 'opt-out';
});
rtvButton.addEventListener('click', () => {
if (!rtvInput.value) {
showConfirmation_(
'Do you really want to opt out of RTV?',
setAmpCanaryCookie_.bind(null, AMP_CANARY_COOKIE.DISABLED)
);
} else if (RTV_PATTERN.test(rtvInput.value)) {
showConfirmation_(
`Do you really want to opt in to RTV ${rtvInput.value}?`,
setAmpCanaryCookie_.bind(null, rtvInput.value)
);
}
});

if (isExperimentOn_(RTV_CHANNEL_ID)) {
rtvInput.value = getCookie(window, 'AMP_CANARY');
rtvInput.dispatchEvent(new Event('input'));
document.getElementById('rtv-details').open = true;
}
}

/**
Expand Down Expand Up @@ -237,24 +268,31 @@ function updateExperimentRow(experiment) {
* @return {boolean}
*/
function isExperimentOn_(id) {
if (id == CANARY_EXPERIMENT_ID) {
return getCookie(window, 'AMP_CANARY') == AMP_CANARY_COOKIE.CANARY;
} else if (id == RC_EXPERIMENT_ID) {
return getCookie(window, 'AMP_CANARY') == AMP_CANARY_COOKIE.RC;
switch (id) {
case EXPERIMENTAL_CHANNEL_ID:
return getCookie(window, 'AMP_CANARY') == AMP_CANARY_COOKIE.CANARY;
case BETA_CHANNEL_ID:
return getCookie(window, 'AMP_CANARY') == AMP_CANARY_COOKIE.RC;
case RTV_CHANNEL_ID:
return RTV_PATTERN.test(getCookie(window, 'AMP_CANARY'));
default:
return isExperimentOn(window, /*OK*/ id);
}
return isExperimentOn(window, /*OK*/ id);
}

/**
* Opts in to / out of the "canary" or "rc" runtime types by setting the
* AMP_CANARY cookie.
* @param {string} cookieState One of AMP_CANARY_COOKIE.{DISABLED|CANARY|RC}
* @param {string} cookieState One of AMP_CANARY_COOKIE.{DISABLED|CANARY|RC} or
* a 15-digit RTV.
*/
function setAmpCanaryCookie_(cookieState) {
const validUntil =
cookieState != AMP_CANARY_COOKIE.DISABLED
? Date.now() + COOKIE_MAX_AGE_MS
: 0;
let validUntil = 0;
if (RTV_PATTERN.test(cookieState)) {
validUntil = Date.now() + RTV_COOKIE_MAX_AGE_MS;
} else if (cookieState != AMP_CANARY_COOKIE.DISABLED) {
validUntil = Date.now() + COOKIE_MAX_AGE_MS;
}
const cookieOptions = {
// Set explicit domain, so the cookie gets sent to sub domains.
domain: location.hostname,
Expand All @@ -279,17 +317,17 @@ function setAmpCanaryCookie_(cookieState) {
function toggleExperiment_(id, name, opt_on) {
const currentlyOn = isExperimentOn_(id);
const on = opt_on === undefined ? !currentlyOn : opt_on;
// Protect against click jacking.
// Protect against accidental choice.
const confirmMessage = on
? 'Do you really want to activate the AMP experiment'
: 'Do you really want to deactivate the AMP experiment';
? 'Do you really want to activate the AMP experiment?'
: 'Do you really want to deactivate the AMP experiment?';

showConfirmation_(`${confirmMessage}: "${name}"`, () => {
if (id == CANARY_EXPERIMENT_ID) {
if (id == EXPERIMENTAL_CHANNEL_ID) {
setAmpCanaryCookie_(
on ? AMP_CANARY_COOKIE.CANARY : AMP_CANARY_COOKIE.DISABLED
);
} else if (id == RC_EXPERIMENT_ID) {
} else if (id == BETA_CHANNEL_ID) {
setAmpCanaryCookie_(
on ? AMP_CANARY_COOKIE.RC : AMP_CANARY_COOKIE.DISABLED
);
Expand Down Expand Up @@ -348,7 +386,7 @@ function getAmpConfig() {
xhr.send(null);
return promise
.then(text => {
const match = text.match(/self\.AMP_CONFIG=([^;]+)/);
const match = text.match(/self\.AMP_CONFIG=(\{.+?\})/);
if (!match) {
throw new Error("Can't find AMP_CONFIG in: " + text);
}
Expand Down

0 comments on commit 7f4d134

Please sign in to comment.