Added experiment for firefox download promo
This commit is contained in:
parent
d0d41b743a
commit
e7fdf76120
@ -1,6 +1,28 @@
|
|||||||
import hash from 'string-hash';
|
import hash from 'string-hash';
|
||||||
|
|
||||||
const experiments = {};
|
const experiments = {
|
||||||
|
'SyI-hI7gT9agiH-f3f0BYg': {
|
||||||
|
id: 'SyI-hI7gT9agiH-f3f0BYg',
|
||||||
|
run: function(variant, state, emitter) {
|
||||||
|
state.promo = variant === 1 ? 'body' : 'header';
|
||||||
|
emitter.emit('render');
|
||||||
|
},
|
||||||
|
eligible: function() {
|
||||||
|
return (
|
||||||
|
!/firefox/i.test(navigator.userAgent) &&
|
||||||
|
document.querySelector('html').lang === 'en-US'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
variant: function(state) {
|
||||||
|
return this.luckyNumber(state) > 0.5 ? 1 : 0;
|
||||||
|
},
|
||||||
|
luckyNumber: function(state) {
|
||||||
|
return luckyNumber(
|
||||||
|
`${this.id}:${state.storage.get('testpilot_ga__cid')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//Returns a number between 0 and 1
|
//Returns a number between 0 and 1
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
@ -32,12 +54,12 @@ export default function initialize(state, emitter) {
|
|||||||
checkExperiments(state, emitter);
|
checkExperiments(state, emitter);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const enrolled = state.storage.enrolled;
|
const enrolled = state.storage.enrolled.filter(([id, variant]) => {
|
||||||
enrolled.forEach(([id, variant]) => {
|
|
||||||
const xp = experiments[id];
|
const xp = experiments[id];
|
||||||
if (xp) {
|
if (xp) {
|
||||||
xp.run(variant, state, emitter);
|
xp.run(variant, state, emitter);
|
||||||
}
|
}
|
||||||
|
return !!xp;
|
||||||
});
|
});
|
||||||
// single experiment per session for now
|
// single experiment per session for now
|
||||||
if (enrolled.length === 0) {
|
if (enrolled.length === 0) {
|
||||||
|
@ -47,4 +47,4 @@ app.use(fileManager);
|
|||||||
app.use(dragManager);
|
app.use(dragManager);
|
||||||
app.use(experiments);
|
app.use(experiments);
|
||||||
|
|
||||||
app.mount('#page-one');
|
app.mount('body');
|
||||||
|
@ -20,7 +20,7 @@ let experiment = null;
|
|||||||
export default function initialize(state, emitter) {
|
export default function initialize(state, emitter) {
|
||||||
appState = state;
|
appState = state;
|
||||||
emitter.on('DOMContentLoaded', () => {
|
emitter.on('DOMContentLoaded', () => {
|
||||||
addExitHandlers();
|
// addExitHandlers();
|
||||||
experiment = storage.enrolled[0];
|
experiment = storage.enrolled[0];
|
||||||
sendEvent(category(), 'visit', {
|
sendEvent(category(), 'visit', {
|
||||||
cm5: storage.totalUploads,
|
cm5: storage.totalUploads,
|
||||||
@ -29,6 +29,9 @@ export default function initialize(state, emitter) {
|
|||||||
});
|
});
|
||||||
//TODO restart handlers... somewhere
|
//TODO restart handlers... somewhere
|
||||||
});
|
});
|
||||||
|
emitter.on('exit', evt => {
|
||||||
|
exitEvent(evt);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function category() {
|
function category() {
|
||||||
@ -81,6 +84,8 @@ function urlToMetric(url) {
|
|||||||
case 'https://testpilot.firefox.com/':
|
case 'https://testpilot.firefox.com/':
|
||||||
case 'https://testpilot.firefox.com/experiments/send':
|
case 'https://testpilot.firefox.com/experiments/send':
|
||||||
return 'testpilot';
|
return 'testpilot';
|
||||||
|
case 'https://www.mozilla.org/firefox/new/?utm_campaign=send-acquisition&utm_medium=referral&utm_source=send.firefox.com':
|
||||||
|
return 'promo';
|
||||||
default:
|
default:
|
||||||
return 'other';
|
return 'other';
|
||||||
}
|
}
|
||||||
@ -244,6 +249,7 @@ function exitEvent(target) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
function addExitHandlers() {
|
function addExitHandlers() {
|
||||||
const links = Array.from(document.querySelectorAll('a'));
|
const links = Array.from(document.querySelectorAll('a'));
|
||||||
links.forEach(l => {
|
links.forEach(l => {
|
||||||
|
@ -1,17 +1,43 @@
|
|||||||
const choo = require('choo');
|
const choo = require('choo');
|
||||||
|
const html = require('choo/html');
|
||||||
const download = require('./download');
|
const download = require('./download');
|
||||||
|
const header = require('../templates/header');
|
||||||
|
const footer = require('../templates/footer');
|
||||||
|
const fxPromo = require('../templates/fxPromo');
|
||||||
|
|
||||||
const app = choo();
|
const app = choo();
|
||||||
|
|
||||||
app.route('/', require('./home'));
|
function body(template) {
|
||||||
app.route('/share/:id', require('../templates/share'));
|
return function(state, emit) {
|
||||||
app.route('/download/:id', download);
|
const b = html`<body>
|
||||||
app.route('/download/:id/:key', download);
|
${state.promo === 'header' ? fxPromo(state, emit) : ''}
|
||||||
app.route('/completed', require('../templates/completed'));
|
${header(state)}
|
||||||
app.route('/unsupported/:reason', require('../templates/unsupported'));
|
<div class="all">
|
||||||
app.route('/legal', require('../templates/legal'));
|
<noscript>
|
||||||
app.route('/error', require('../templates/error'));
|
<h2>Firefox Send requires JavaScript</h2>
|
||||||
app.route('/blank', require('../templates/blank'));
|
<p><a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-does-firefox-send-require-javascript">Why does Firefox Send require JavaScript?</a></p>
|
||||||
app.route('*', require('../templates/notFound'));
|
<p>Please enable JavaScript and try again.</p>
|
||||||
|
</noscript>
|
||||||
|
${template(state, emit)}
|
||||||
|
</div>
|
||||||
|
${footer(state)}
|
||||||
|
</body>`;
|
||||||
|
if (state.layout) {
|
||||||
|
return state.layout(state, b);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
app.route('/', body(require('./home')));
|
||||||
|
app.route('/share/:id', body(require('../templates/share')));
|
||||||
|
app.route('/download/:id', body(download));
|
||||||
|
app.route('/download/:id/:key', body(download));
|
||||||
|
app.route('/completed', body(require('../templates/completed')));
|
||||||
|
app.route('/unsupported/:reason', body(require('../templates/unsupported')));
|
||||||
|
app.route('/legal', body(require('../templates/legal')));
|
||||||
|
app.route('/error', body(require('../templates/error')));
|
||||||
|
app.route('/blank', body(require('../templates/blank')));
|
||||||
|
app.route('*', body(require('../templates/notFound')));
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
|
|
||||||
module.exports = function(state) {
|
module.exports = function() {
|
||||||
const div = html`<div id="page-one"></div>`;
|
const div = html`<div id="page-one"></div>`;
|
||||||
if (state.layout) {
|
|
||||||
return state.layout(state, div);
|
|
||||||
}
|
|
||||||
return div;
|
return div;
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
const progress = require('./progress');
|
const progress = require('./progress');
|
||||||
const { fadeOut } = require('../utils');
|
const { fadeOut } = require('../utils');
|
||||||
|
const fxPromo = require('./fxPromo');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
const div = html`
|
const div = html`
|
||||||
|
<div id="page-one">
|
||||||
<div id="download" class="fadeIn">
|
<div id="download" class="fadeIn">
|
||||||
<div id="download-progress">
|
<div id="download-progress">
|
||||||
<div id="dl-title" class="title">${state.translate(
|
<div id="dl-title" class="title">${state.translate(
|
||||||
@ -19,6 +21,8 @@ module.exports = function(state, emit) {
|
|||||||
sendNew
|
sendNew
|
||||||
}>${state.translate('sendYourFilesLink')}</a>
|
}>${state.translate('sendYourFilesLink')}</a>
|
||||||
</div>
|
</div>
|
||||||
|
${state.promo === 'body' ? fxPromo(state, emit) : ''}
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
async function sendNew(e) {
|
async function sendNew(e) {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
const progress = require('./progress');
|
const progress = require('./progress');
|
||||||
const { bytes } = require('../utils');
|
const { bytes } = require('../utils');
|
||||||
|
const fxPromo = require('./fxPromo');
|
||||||
|
|
||||||
module.exports = function(state) {
|
module.exports = function(state, emit) {
|
||||||
const transfer = state.transfer;
|
const transfer = state.transfer;
|
||||||
const div = html`
|
const div = html`
|
||||||
|
<div id="page-one">
|
||||||
<div id="download-progress" class="fadeIn">
|
<div id="download-progress" class="fadeIn">
|
||||||
<div id="dl-title" class="title">${state.translate(
|
<div id="dl-title" class="title">${state.translate(
|
||||||
'downloadingPageProgress',
|
'downloadingPageProgress',
|
||||||
@ -21,6 +23,8 @@ module.exports = function(state) {
|
|||||||
transfer.sizes
|
transfer.sizes
|
||||||
)}</div>
|
)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
${state.promo === 'body' ? fxPromo(state, emit) : ''}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
31
app/templates/footer.js
Normal file
31
app/templates/footer.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
const html = require('choo/html');
|
||||||
|
const assets = require('../../common/assets');
|
||||||
|
|
||||||
|
module.exports = function(state) {
|
||||||
|
return html`<div class="footer">
|
||||||
|
<div class="legal-links">
|
||||||
|
<a href="https://www.mozilla.org" role="presentation"><img class="mozilla-logo" src="${assets.get(
|
||||||
|
'mozilla-logo.svg'
|
||||||
|
)}" alt="mozilla"/></a>
|
||||||
|
<a href="https://www.mozilla.org/about/legal">${state.translate(
|
||||||
|
'footerLinkLegal'
|
||||||
|
)}</a>
|
||||||
|
<a href="https://testpilot.firefox.com/about">${state.translate(
|
||||||
|
'footerLinkAbout'
|
||||||
|
)}</a>
|
||||||
|
<a href="/legal">${state.translate('footerLinkPrivacy')}</a>
|
||||||
|
<a href="/legal">${state.translate('footerLinkTerms')}</a>
|
||||||
|
<a href="https://www.mozilla.org/privacy/websites/#cookies">${state.translate(
|
||||||
|
'footerLinkCookies'
|
||||||
|
)}</a>
|
||||||
|
</div>
|
||||||
|
<div class="social-links">
|
||||||
|
<a href="https://github.com/mozilla/send" role="presentation"><img class="github" src="${assets.get(
|
||||||
|
'github-icon.svg'
|
||||||
|
)}" alt="github"/></a>
|
||||||
|
<a href="https://twitter.com/FxTestPilot" role="presentation"><img class="twitter" src="${assets.get(
|
||||||
|
'twitter-icon.svg'
|
||||||
|
)}" alt="twitter"/></a>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
};
|
44
app/templates/fxPromo.js
Normal file
44
app/templates/fxPromo.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
const html = require('choo/html');
|
||||||
|
const assets = require('../../common/assets');
|
||||||
|
|
||||||
|
// function replaceLinks(str, urls) {
|
||||||
|
// let i = -1;
|
||||||
|
// const s = str.replace(/<a>([^<]+)<\/a>/g, (m, v) => {
|
||||||
|
// i++;
|
||||||
|
// return `<a class="link" href="${urls[i]}">${v}</a>`;
|
||||||
|
// });
|
||||||
|
// return [`<span>${s}</span>`];
|
||||||
|
// }
|
||||||
|
|
||||||
|
module.exports = function(state, emit) {
|
||||||
|
// function close() {
|
||||||
|
// document.querySelector('.banner').remove();
|
||||||
|
// }
|
||||||
|
|
||||||
|
function clicked(evt) {
|
||||||
|
emit('exit', evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="banner">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
src="${assets.get('firefox_logo-only.svg')}"
|
||||||
|
class="firefox-logo-small"
|
||||||
|
alt="Firefox"/>
|
||||||
|
<span>Send is brought to you by the all-new Firefox.
|
||||||
|
<a
|
||||||
|
class="link"
|
||||||
|
href="https://www.mozilla.org/firefox/new/?utm_campaign=send-acquisition&utm_medium=referral&utm_source=send.firefox.com"
|
||||||
|
onclick=${clicked}
|
||||||
|
>Download Firefox now ≫</a></span>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
<img
|
||||||
|
src="${assets.get('close-16.svg')}"
|
||||||
|
class="icon-delete"
|
||||||
|
onclick=${close}>
|
||||||
|
*/
|
21
app/templates/header.js
Normal file
21
app/templates/header.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const html = require('choo/html');
|
||||||
|
const assets = require('../../common/assets');
|
||||||
|
|
||||||
|
module.exports = function(state) {
|
||||||
|
return html`<header class="header">
|
||||||
|
<div class="send-logo">
|
||||||
|
<a href="/">
|
||||||
|
<img src="${assets.get(
|
||||||
|
'send_logo.svg'
|
||||||
|
)}" alt="Send"/><h1 class="site-title">Send</h1>
|
||||||
|
</a>
|
||||||
|
<div class="site-subtitle">
|
||||||
|
<a href="https://testpilot.firefox.com">Firefox Test Pilot</a>
|
||||||
|
<div>${state.translate('siteSubtitle')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send" rel="noreferrer noopener" class="feedback" target="_blank">${state.translate(
|
||||||
|
'siteFeedback'
|
||||||
|
)}</a>
|
||||||
|
</header>`;
|
||||||
|
};
|
@ -30,9 +30,5 @@ module.exports = function(state) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (state.layout) {
|
|
||||||
return state.layout(state, div);
|
|
||||||
}
|
|
||||||
return div;
|
return div;
|
||||||
};
|
};
|
||||||
|
@ -17,9 +17,5 @@ module.exports = function(state) {
|
|||||||
)}</a>
|
)}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
if (state.layout) {
|
|
||||||
return state.layout(state, div);
|
|
||||||
}
|
|
||||||
return div;
|
return div;
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ const assets = require('../../common/assets');
|
|||||||
const notFound = require('./notFound');
|
const notFound = require('./notFound');
|
||||||
const downloadPassword = require('./downloadPassword');
|
const downloadPassword = require('./downloadPassword');
|
||||||
const { bytes } = require('../utils');
|
const { bytes } = require('../utils');
|
||||||
|
const fxPromo = require('./fxPromo');
|
||||||
|
|
||||||
function getFileFromDOM() {
|
function getFileFromDOM() {
|
||||||
const el = document.getElementById('dl-file');
|
const el = document.getElementById('dl-file');
|
||||||
@ -61,6 +62,7 @@ module.exports = function(state, emit) {
|
|||||||
</div>
|
</div>
|
||||||
<a class="send-new" href="/">${state.translate('sendYourFilesLink')}</a>
|
<a class="send-new" href="/">${state.translate('sendYourFilesLink')}</a>
|
||||||
</div>
|
</div>
|
||||||
|
${state.promo === 'body' ? fxPromo(state, emit) : ''}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -68,9 +70,5 @@ module.exports = function(state, emit) {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
emit('download', fileInfo);
|
emit('download', fileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.layout) {
|
|
||||||
return state.layout(state, div);
|
|
||||||
}
|
|
||||||
return div;
|
return div;
|
||||||
};
|
};
|
||||||
|
@ -42,9 +42,5 @@ module.exports = function(state) {
|
|||||||
)}</div>
|
)}</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
const div = html`<div id="page-one">${msg}</div>`;
|
const div = html`<div id="page-one">${msg}</div>`;
|
||||||
|
|
||||||
if (state.layout) {
|
|
||||||
return state.layout(state, div);
|
|
||||||
}
|
|
||||||
return div;
|
return div;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const html = require('choo/html');
|
const html = require('choo/html');
|
||||||
const assets = require('../../common/assets');
|
const assets = require('../../common/assets');
|
||||||
const fileList = require('./fileList');
|
const fileList = require('./fileList');
|
||||||
|
const fxPromo = require('./fxPromo');
|
||||||
const { fadeOut } = require('../utils');
|
const { fadeOut } = require('../utils');
|
||||||
|
|
||||||
module.exports = function(state, emit) {
|
module.exports = function(state, emit) {
|
||||||
@ -35,6 +36,7 @@ module.exports = function(state, emit) {
|
|||||||
title="${state.translate('uploadPageBrowseButton1')}">
|
title="${state.translate('uploadPageBrowseButton1')}">
|
||||||
${state.translate('uploadPageBrowseButton1')}</label>
|
${state.translate('uploadPageBrowseButton1')}</label>
|
||||||
</div>
|
</div>
|
||||||
|
${state.promo === 'body' ? fxPromo(state, emit) : ''}
|
||||||
${fileList(state, emit)}
|
${fileList(state, emit)}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -67,9 +69,5 @@ module.exports = function(state, emit) {
|
|||||||
await fadeOut('page-one');
|
await fadeOut('page-one');
|
||||||
emit('upload', { file, type: 'click' });
|
emit('upload', { file, type: 'click' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.layout) {
|
|
||||||
return state.layout(state, div);
|
|
||||||
}
|
|
||||||
return div;
|
return div;
|
||||||
};
|
};
|
||||||
|
@ -108,7 +108,8 @@ function bytes(num) {
|
|||||||
let nStr = n.toFixed(1);
|
let nStr = n.toFixed(1);
|
||||||
if (LOCALIZE_NUMBERS) {
|
if (LOCALIZE_NUMBERS) {
|
||||||
try {
|
try {
|
||||||
nStr = n.toLocaleString(navigator.languages.map(l => l.split(';')[0]), {
|
const locale = document.querySelector('html').lang;
|
||||||
|
nStr = n.toLocaleString(locale, {
|
||||||
minimumFractionDigits: 1,
|
minimumFractionDigits: 1,
|
||||||
maximumFractionDigits: 1
|
maximumFractionDigits: 1
|
||||||
});
|
});
|
||||||
@ -122,10 +123,8 @@ function bytes(num) {
|
|||||||
function percent(ratio) {
|
function percent(ratio) {
|
||||||
if (LOCALIZE_NUMBERS) {
|
if (LOCALIZE_NUMBERS) {
|
||||||
try {
|
try {
|
||||||
return ratio.toLocaleString(
|
const locale = document.querySelector('html').lang;
|
||||||
navigator.languages.map(l => l.split(';')[0]),
|
return ratio.toLocaleString(locale, { style: 'percent' });
|
||||||
{ style: 'percent' }
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// fall through
|
// fall through
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 239 KiB After Width: | Height: | Size: 16 KiB |
@ -8,7 +8,6 @@ html {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center top;
|
background-position: center top;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 1440px;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +129,7 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
max-width: 630px;
|
max-width: 650px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -213,7 +212,7 @@ a {
|
|||||||
|
|
||||||
.upload-window {
|
.upload-window {
|
||||||
border: 3px dashed rgba(0, 148, 251, 0.5);
|
border: 3px dashed rgba(0, 148, 251, 0.5);
|
||||||
margin: 0 auto;
|
margin: 0 auto 10px;
|
||||||
height: 255px;
|
height: 255px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -709,6 +708,10 @@ tbody {
|
|||||||
width: 70px;
|
width: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.firefox-logo-small {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
#dl-firefox,
|
#dl-firefox,
|
||||||
#update-firefox {
|
#update-firefox {
|
||||||
margin-bottom: 181px;
|
margin-bottom: 181px;
|
||||||
@ -766,7 +769,7 @@ tbody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#download {
|
#download {
|
||||||
margin: 0 auto;
|
margin: 0 auto 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -955,6 +958,29 @@ tbody {
|
|||||||
background-position: 2px 1px;
|
background-position: 2px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
padding: 0 15px;
|
||||||
|
height: 48px;
|
||||||
|
background-color: #efeff1;
|
||||||
|
color: #4a4a4f;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner > div > span {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-device-width: 992px), (max-width: 992px) {
|
@media (max-device-width: 992px), (max-width: 992px) {
|
||||||
.popup .popuptext {
|
.popup .popuptext {
|
||||||
left: auto;
|
left: auto;
|
||||||
|
@ -112,6 +112,7 @@
|
|||||||
"en-US",
|
"en-US",
|
||||||
"ast",
|
"ast",
|
||||||
"az",
|
"az",
|
||||||
|
"bs",
|
||||||
"ca",
|
"ca",
|
||||||
"cak",
|
"cak",
|
||||||
"cs",
|
"cs",
|
||||||
@ -132,6 +133,7 @@
|
|||||||
"id",
|
"id",
|
||||||
"it",
|
"it",
|
||||||
"ja",
|
"ja",
|
||||||
|
"ka",
|
||||||
"kab",
|
"kab",
|
||||||
"ko",
|
"ko",
|
||||||
"ms",
|
"ms",
|
||||||
@ -145,6 +147,7 @@
|
|||||||
"sl",
|
"sl",
|
||||||
"sr",
|
"sr",
|
||||||
"sv-SE",
|
"sv-SE",
|
||||||
|
"tl",
|
||||||
"tr",
|
"tr",
|
||||||
"uk",
|
"uk",
|
||||||
"vi",
|
"vi",
|
||||||
|
@ -8,7 +8,7 @@ module.exports = function(state, body = '') {
|
|||||||
: '';
|
: '';
|
||||||
return html`
|
return html`
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="${state.locale}">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@ -31,7 +31,7 @@ module.exports = function(state, body = '') {
|
|||||||
<title>${state.title}</title>
|
<title>${state.title}</title>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="${assets.get('main.css')}" />
|
<link rel="stylesheet" type="text/css" href="${assets.get('main.css')}" />
|
||||||
|
|
||||||
<!-- generic favicons -->
|
<!-- generic favicons -->
|
||||||
<link rel="icon" href="${assets.get('favicon-32.png')}" sizes="32x32">
|
<link rel="icon" href="${assets.get('favicon-32.png')}" sizes="32x32">
|
||||||
<link rel="icon" href="${assets.get('favicon-96.png')}" sizes="96x96">
|
<link rel="icon" href="${assets.get('favicon-96.png')}" sizes="96x96">
|
||||||
@ -62,8 +62,8 @@ module.exports = function(state, body = '') {
|
|||||||
|
|
||||||
<!— Windows 8.1 + IE11 and above —>
|
<!— Windows 8.1 + IE11 and above —>
|
||||||
<meta name="msapplication-config" content="/browserconfig.xml"/>
|
<meta name="msapplication-config" content="/browserconfig.xml"/>
|
||||||
|
|
||||||
|
|
||||||
${firaTag}
|
${firaTag}
|
||||||
<script defer src="/jsconfig.js"></script>
|
<script defer src="/jsconfig.js"></script>
|
||||||
<script defer src="${assets.get('runtime.js')}"></script>
|
<script defer src="${assets.get('runtime.js')}"></script>
|
||||||
@ -71,58 +71,7 @@ module.exports = function(state, body = '') {
|
|||||||
<script defer src="${locales.get(state.locale)}"></script>
|
<script defer src="${locales.get(state.locale)}"></script>
|
||||||
<script defer src="${assets.get('app.js')}"></script>
|
<script defer src="${assets.get('app.js')}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
${body}
|
||||||
<header class="header">
|
|
||||||
<div class="send-logo">
|
|
||||||
<a href="/">
|
|
||||||
<img src="${assets.get(
|
|
||||||
'send_logo.svg'
|
|
||||||
)}" alt="Send"/><h1 class="site-title">Send</h1>
|
|
||||||
</a>
|
|
||||||
<div class="site-subtitle">
|
|
||||||
<a href="https://testpilot.firefox.com">Firefox Test Pilot</a>
|
|
||||||
<div>${state.translate('siteSubtitle')}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send" rel="noreferrer noopener" class="feedback" target="_blank">${state.translate(
|
|
||||||
'siteFeedback'
|
|
||||||
)}</a>
|
|
||||||
</header>
|
|
||||||
<div class="all">
|
|
||||||
<noscript>
|
|
||||||
<h2>Firefox Send requires JavaScript</h2>
|
|
||||||
<p><a href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-does-firefox-send-require-javascript">Why does Firefox Send require JavaScript?</a></p>
|
|
||||||
<p>Please enable JavaScript and try again.</p>
|
|
||||||
</noscript>
|
|
||||||
${body}
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<div class="legal-links">
|
|
||||||
<a href="https://www.mozilla.org" role="presentation"><img class="mozilla-logo" src="${assets.get(
|
|
||||||
'mozilla-logo.svg'
|
|
||||||
)}" alt="mozilla"/></a>
|
|
||||||
<a href="https://www.mozilla.org/about/legal">${state.translate(
|
|
||||||
'footerLinkLegal'
|
|
||||||
)}</a>
|
|
||||||
<a href="https://testpilot.firefox.com/about">${state.translate(
|
|
||||||
'footerLinkAbout'
|
|
||||||
)}</a>
|
|
||||||
<a href="/legal">${state.translate('footerLinkPrivacy')}</a>
|
|
||||||
<a href="/legal">${state.translate('footerLinkTerms')}</a>
|
|
||||||
<a href="https://www.mozilla.org/privacy/websites/#cookies">${state.translate(
|
|
||||||
'footerLinkCookies'
|
|
||||||
)}</a>
|
|
||||||
</div>
|
|
||||||
<div class="social-links">
|
|
||||||
<a href="https://github.com/mozilla/send" role="presentation"><img class="github" src="${assets.get(
|
|
||||||
'github-icon.svg'
|
|
||||||
)}" alt="github"/></a>
|
|
||||||
<a href="https://twitter.com/FxTestPilot" role="presentation"><img class="twitter" src="${assets.get(
|
|
||||||
'twitter-icon.svg'
|
|
||||||
)}" alt="twitter"/></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user