mozvr.github.com Ghost "template" (header and footer from https://mozvr.ghost.io/ghost/settings/code-injection/)
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js"></script>
<script>
(function () {
/* global ga, performance */
// Toggle this variable to output to the console debug GA messages.
var debug = false;
function initGoogleAnalytics (id, opts) {
(function (c, v, a, n) {
c.GoogleAnalyticsObject = n;
c[n] = c[n] || function () {
(c[n].q = c[n].q || []).push(arguments);
};
c[n].l = 1 * new Date();
var s = v.createElement('script');
s.async = true;
s.src = a;
s.addEventListener('load', enableDebug);
var m = v.getElementsByTagName('script')[0];
m.parentNode.insertBefore(s, m);
})(window, document, 'https://www.google-analytics.com/analytics.js', 'ga');
function enableDebug () {
if (!debug) {
return;
}
window.ga = ga = console.info.bind(console);
}
enableDebug();
ga('create', id, opts);
ga('set', 'forceSSL', true);
ga('send', 'pageview');
}
function initGoogleAnalyticsEvents () {
var indexPage = document.documentElement;
var gdcPage = document.querySelector('html[data-gdc]');
var unityPage = document.querySelector('canvas.emscripten, body[data-unity-loaded]');
window.addEventListener('load', function () {
setTimeout(function () {
var t = performance.timing;
// Credit to https://github.com/addyosmani/timing.js/blob/c58c164/timing.js#L67-L88:
// Total time from start to load.
gaSendPageTiming('loadTime', t.loadEventEnd - t.fetchStart);
// Time spent constructing the DOM tree.
gaSendPageTiming('domReadyTime', t.domComplete - t.domInteractive);
// Time consumed preparing the new page.
gaSendPageTiming('readyStart', t.fetchStart - t.navigationStart);
// Time spent during redirection.
gaSendPageTiming('redirectTime', t.redirectEnd - t.redirectStart);
// AppCache.
gaSendPageTiming('appcacheTime', t.domainLookupStart - t.fetchStart);
// Time spent unloading documents.
gaSendPageTiming('unloadEventTime', t.unloadEventEnd - t.unloadEventStart);
// DNS query time.
gaSendPageTiming('lookupDomainTime', t.domainLookupEnd - t.domainLookupStart);
// TCP connection time.
gaSendPageTiming('connectTime', t.connectEnd - t.connectStart);
// Time spent during the request.
gaSendPageTiming('requestTime', t.responseEnd - t.requestStart);
// Request to completion of the DOM loading.
gaSendPageTiming('initDomTreeTime', t.domInteractive - t.responseEnd);
// Load event time.
gaSendPageTiming('loadEventTime', t.loadEventEnd - t.loadEventStart);
});
});
var gaSendTiming = function (timingCategory, timingLabel) {
return function (timingVar, timeEnd) {
if (typeof timeEnd === 'undefined') {
timeEnd = performance.now();
}
ga('send', {
hitType: 'timing',
timingCategory: timingCategory,
timingVar: timingVar,
timingValue: timeEnd,
timingLabel: timingLabel
});
};
};
var gaSendPageTiming = gaSendTiming('page');
var gaSendEmscriptenTiming = gaSendTiming('emscripten', unityPage ? 'unity' : '<unknown>');
if ('Module' in window && 'performance' in window) {
gaSendEmscriptenTiming('preinit');
Module.onRuntimeInitialized = gaSendEmscriptenTiming.bind(this, 'init');
Module.postRun = [
gaSendEmscriptenTiming.bind(this, 'load')
];
}
ga('send', 'event', 'pageload.title', document.title);
ga('send', 'event', 'pageload.location', window.location.href);
ga('send', 'event', 'pageload.pathname', window.location.pathname);
ga('send', 'event', 'pageload.querystring', window.location.search);
ga('send', 'event', 'pageload.hash', window.location.hash);
ga('send', 'event', 'supports.getVRDisplays', 'getVRDisplays' in navigator);
ga('send', 'event', 'supports.getVRDevices', 'getVRDevices' in navigator);
var getDeviceNames = function (devices) {
var names = (devices || []).map(function (device) {
return device ? (device.displayName || device.deviceName || '<unknown>') : '<unknown>';
});
return JSON.stringify(names);
};
var getPresentationStates = function (devices) {
var states = (devices || []).map(function (device) {
return device.isPresenting;
});
return JSON.stringify(states);
};
if (document.body.requestFullscreen) {
var fsElement = 'fullscreenElement';
var fsEvent = 'fullscreenchange';
} else if (document.body.mozRequestFullScreen) {
var fsElement = 'mozFullScreenElement';
var fsEvent = 'mozfullscreenchange';
} else if (document.body.webkitRequestFullscreen) {
var fsElement = 'webkitFullscreenElement';
var fsEvent = 'webkitfullscreenchange';
} else if (document.body.msRequestFullscreen) {
var fsElement = 'msFullscreenElement';
var fsEvent = 'MSFullscreenChange';
}
document.addEventListener(fsEvent, function () {
var isFs = document[fsElement] instanceof HTMLElement;
ga('send', 'event', 'modechange.fullscreen', isFs);
if (navigator.getVRDevices) {
// NOTE: With the old API, we unfortunately cannot discern between
// entering/exiting fullscreen or VR mode - that is, whether
// `requestFullscreen({vrDisplay: display})` or
// `requestFullscreen(canvas)` was called.
var devices = [{isPresenting: isFs}];
ga('send', 'event', 'modechange.vr', getPresentationStates(devices));
}
});
if (navigator.getVRDisplays) {
window.addEventListener('vrdisplaypresentchange', function () {
ga('send', 'event', 'modechange.vr', getPresentationStates(devices));
});
navigator.getVRDisplays().then(function (devices) {
ga('send', 'event', 'pageload.getVRDisplays', getDeviceNames(devices));
});
} else if (navigator.getVRDevices) {
navigator.getVRDevices().then(function (devices) {
ga('send', 'event', 'pageload.getVRDevices', getDeviceNames(devices));
});
}
window.addEventListener('click', function (e) {
var el = e.target.closest && e.target.closest('a, input[type=button], button, img, picture');
if (!el) { return; }
var txt = getElText(el);
if (txt) {
ga('send', 'event', 'click.link', txt);
}
});
}
function getElText (el) {
var txt = el.textContent ? el.textContent.trim() : '';
if (txt) {
return txt;
}
var img = el.tagName === 'IMG' ? el : el.querySelector('img');
if (img) {
return img.getAttribute('alt') || img.getAttribute('title');
}
return '';
}
initGoogleAnalytics('UA-74058648-3', {alwaysSendReferrer: true});
initGoogleAnalyticsEvents();
})();
</script>
<style>
li > pre[class*="language-"] {
margin: 1.5rem 0 3rem;
}
iframe {
border: 0;
}
.view-source {
display: block;
margin-top: .25rem;
}
.post-head.main-header {
height: 55vh;
}
.post-head.main-header[style*="w3c_home"] {
background-size: contain;
background-color: #fff;
height: 45vh;
}
a code,
a tt {
border: none;
background: none;
padding: 0 0.25ch;
}
code,
tt,
pre {
font-family: Consolas, Andale Mono, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
}
.post-template .post-content a {
border-bottom: 1px dotted rgba(0,0,0,.25);
padding-bottom: 1px;
text-decoration: none;
transition: .1s border-bottom-color ease-in-out, .1s color ease-in-out;
}
.post-template .post-content a:hover {
border-bottom-color: rgba(0,0,0,.45);
color: #333;
}
.post-template .post-content a:active {
border-bottom-color: magenta;
color: magenta;
}
/* fonts */
html {
font-size: 12px;
}
body,
.page-description,
.author-profile .author-meta {
line-height: 1.6;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
textarea,
select,
input,
button,
.main-nav a,
.subscribe-button,
.page-title,
.read-next-story .post:before,
.post-meta,
.pagination,
.gh-subscripe-rss,
.site-footer {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.4;
}
h1,
h1.post-title {
font-size: 3.75rem;
line-height: 1.2;
}
h2 {
font-size: 2.5rem;
line-height: 1.3;
}
/* general */
pre + p { margin-top: 1.75em; }
pre[class*=language-] { font-size: 1.1rem; }
.home-template .blog-logo,
.nav li:before,
.nav li a:after,
.scroll-down,
.home-template .main-header:after {
display: none;
}
.blog-logo {
opacity: .8;
transition: .1s border-width ease-in-out, .1s opacity ease-in-out, .1s transform ease-in-out;
}
.blog-logo img {
border: 1px solid #ddd;
border-radius: 3px;
box-shadow: -3px 3px 0 0 rgba(0,0,0,.05);
height: auto;
padding: 0;
width: 48px;
}
.blog-logo:hover {
opacity: 1;
transform: scale(1.05);
}
.blog-logo:hover img {
border-width: 0;
}
.main-header {
height: auto;
text-align: right;
}
.home-template .main-header {
background-color: rgb(21,169,224);
background-position: -5vw 50%;
}
.main-nav-overlay {
background: linear-gradient(to bottom, rgba(0,0,0,.6) 0%, rgba(0,0,0,0) 100%);
}
@media only screen and (max-width: 900px) {
.main-header {
min-height: auto;
height: auto;
padding: 1% 0;
text-align: left;
}
.home-template .main-header {
background-position: 33vw 50%;
}
}
@media only screen and (max-width: 500px) {
.main-header {
text-align: center;
}
}
h1.page-title {
background: #ffcd02;
box-shadow: -3px 3px 0 0 rgba(0,0,0,.15);
color: #333;
display: inline-block;
font-size: 1.85rem;
font-size: calc(1.85rem + 1vw);
font-style: italic;
font-weight: 200;
letter-spacing: 0.015em;
margin: 6vw auto;
padding: 1rem 2rem;
text-align: center;
text-transform: uppercase;
}
.page-description {
display: none;
}
.post figure {
margin: 1.75em 40px;
}
.post figcaption {
color: #999;
font-size: 1.5rem;
line-height: 1.7;
}
.post .assets-link img {
margin: 0 1rem 0 .5rem;
}
.post img,
.post-content img {
max-width: 100%;
}
.w3 {
width: 3rem;
}
.left {
float: left;
}
.table {
display: table;
width: 100%;
}
.table-cell {
display: table-cell;
vertical-align: middle;
}
a.assets-link {
/* border: 0.5rem solid rgb(255,205,2,); */
background: rgb(255,205,2);
box-sizing: border-box;
color: #111;
display: inline-block;
font-size: 1.5rem;
font-weight: 500;
letter-spacing: .05em;
line-height: 1.5;
margin-right: .5rem;
padding: .4rem 0 .4rem 1.2rem;
text-decoration: none;
text-transform: uppercase;
}
a.assets-link img {
margin: 0 1rem 0 0.5rem;
padding: 0;
}
a.assets-link:hover {
background: rgb(12,153,213);
border-color: rgb(12,153,213);
color: #fff;
}
.assets-link:active {
background: rgb(0,81,137);
border-color: rgb(0,81,137);
color: #fff;
text-decoration: none;
}
.post .intro {
border-bottom: .1rem dotted #c7c7c7;
font-size: 1.75rem;
font-weight: 400;
line-height: 1.5;
margin: 0 0 2.5rem;
padding: 0 0 2.5rem;
}
.post .subintro {
display: block;
font-size: 1.75rem;
margin: 1.5rem 0 0;
opacity: 0.6;
}
.post-summary {
background-color: #f4f4f4;
border-left: .8rem solid rgb(255,205,2);
margin: 3rem 0;
padding: 1rem 2rem;
}
.post-summary ol {
font-weight: 300;
margin: 0 0 2rem;
padding: 0 1.65rem;
}
.post-summary li {
font-size: 1.35rem;
line-height: 1.75;
}
li {
margin: 0;
}
li + li {
margin-top: .5em;
}
.post-excerpt p {
color: #555;
}
body:not(.post-template) .post-title {
font-size: 2.25rem;
}
.post-title,
.post-title a {
color: #f37; /* pink */
}
.post-title a {
text-shadow: -2px 0 0 #fff, 2px 0 0 #fff, 0 -2px 0 #fff, 0 1px 0 #fff;
transition: .1s background-image ease-in-out, .1s color ease-in-out;
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
.post-title a {
background-repeat: repeat-x;
background-size: 1px .2ch;
background-position: 0 1.55ch;
}
.post-title a:hover {
background-image: linear-gradient(to bottom, transparent 50%, currentColor 50%);
}
}
.post {
font-size: 1.4rem;
max-width: calc(710px + 20vw);
}
/*
body:not(.post-template) .post {
opacity: 0.8;
transition: .1s opacity ease-in-out;
}
body:not(.post-template) .post:hover {
opacity: 1;
}
*/
/* Add space between heading and byline on individual post pages */
.post-template .post-meta {
margin-top: 1rem;
}
.post-footer .share h4 {
font-size: 1.1rem;
font-weight: 300;
margin-top: 0.75rem;
}
.poweredby { display: none; }
.author-bio {
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
}
/* Not sure why needed. */
.copyright { margin-left: 15px; }
.author-image { top: -80px; }
</style>
<link async rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css">
<style>
pre[class*="language-"] > code[data-language] {
overflow: auto;
}
</style>