Move thanks to "sponsors"

* Implement (server-side) templating and parsing of sponsors to take some
  of the toil out of updating what was thanks.html, and pave the way for
  making this dynamically loaded outside of the codebase.
* Support corporate sponsorships. Currently showing two (unapproved, NOT
  for merging) ideas of possible sponsors.
* Some minor tweaks to try and support small screens better for these.
This commit is contained in:
Matt Godbolt
2020-04-06 21:59:10 -05:00
parent c888929865
commit 420462bdfd
15 changed files with 663 additions and 288 deletions

View File

@@ -67,15 +67,15 @@ clean: ## Cleans up everything
run: export NODE_ENV=production
run: export WEBPACK_ARGS="-p"
run: prereqs webpack ## Runs the site normally
./node_modules/.bin/supervisor -w app.js,lib,etc/config -e 'js|node|properties' --exec $(NODE) $(NODE_ARGS) -- ./app.js $(EXTRA_ARGS)
./node_modules/.bin/supervisor -w app.js,lib,etc/config -e 'js|node|properties|yaml' --exec $(NODE) $(NODE_ARGS) -- ./app.js $(EXTRA_ARGS)
dev: export NODE_ENV=development
dev: prereqs install-git-hooks ## Runs the site as a developer; including live reload support and installation of git hooks
./node_modules/.bin/supervisor -w app.js,lib,etc/config -e 'js|node|properties' --exec $(NODE) $(NODE_ARGS) -- ./app.js $(EXTRA_ARGS)
./node_modules/.bin/supervisor -w app.js,lib,etc/config -e 'js|node|properties|yaml' --exec $(NODE) $(NODE_ARGS) -- ./app.js $(EXTRA_ARGS)
debug: export NODE_ENV=development
debug: prereqs install-git-hooks ## Runs the site as a developer with full debugging; including live reload support and installation of git hooks
./node_modules/.bin/supervisor -w app.js,lib,etc/config -e 'js|node|properties' --exec $(NODE) $(NODE_ARGS) -- ./app.js --debug $(EXTRA_ARGS)
./node_modules/.bin/supervisor -w app.js,lib,etc/config -e 'js|node|properties|yaml' --exec $(NODE) $(NODE_ARGS) -- ./app.js --debug $(EXTRA_ARGS)
HASH := $(shell git rev-parse HEAD)
dist: export NODE_ENV=production

6
app.js
View File

@@ -164,7 +164,8 @@ logger.info(`properties hierarchy: ${propHierarchy.join(', ')}`);
if (opts.propDebug) props.setDebug(true);
// *All* files in config dir are parsed
props.initialize(defArgs.rootDir + '/config', propHierarchy);
const configDir = defArgs.rootDir + '/config';
props.initialize(configDir, propHierarchy);
// Now load up our libraries.
const aws = require('./lib/aws'),
@@ -409,6 +410,7 @@ async function main() {
const sourceHandler = new SourceHandler(fileSources, staticHeaders);
const CompilerFinder = require('./lib/compiler-finder');
const compilerFinder = new CompilerFinder(compileHandler, compilerProps, awsProps, defArgs, clientOptionsHandler);
const sponsors = require('./lib/sponsors');
logger.info("=======================================");
if (gitReleaseName) logger.info(` git release ${gitReleaseName}`);
@@ -503,6 +505,7 @@ async function main() {
res.render('error', renderConfig({error: {code: status, message: message}}));
});
const sponsorConfig = sponsors.loadFromString(fs.readFileSync(configDir + '/sponsors.yaml', 'utf-8'));
function renderConfig(extra, urlOptions) {
const urlOptionsWhitelist = [
'readOnly', 'hideEditorToolbars'
@@ -519,6 +522,7 @@ async function main() {
options.staticRoot = staticRoot;
options.storageSolution = storageSolution;
options.require = pugRequireHandler;
options.sponsors = sponsorConfig;
return options;
}

View File

@@ -22,6 +22,7 @@ formatter.clangformat.styles=Google:LLVM:Mozilla:Chromium:WebKit
motdUrl=/motd/motd-prod.json
storageSolution=s3
healthCheckFilePath=/efs/.health
showSponsors=true
eventLoopMeasureIntervalMs=50
eventLoopLagThresholdWarn=100

View File

@@ -17,6 +17,7 @@ googleShortLinkRewrite=^https?://goo.gl/(.*)$|https://godbolt.org/g/$1
urlShortenService=default
storageSolution=local
localStorageFolder=./lib/storage/data/
showSponsors=true
demanglerClassFile=./demangler

235
etc/config/sponsors.yaml Normal file
View File

@@ -0,0 +1,235 @@
---
levels:
- name: Corporate Sponsors
description: 'Enormous thanks to our corporate sponsors. Please click and visit their websites below:'
class: corporate
sponsors:
- name: Solid Sands
description: The one-stop shop for C and C++ compiler and library testing, validation and safety services.
img: https://solidsands.com/wp-content/uploads/2017/11/small-solid-sands-logo.png
url: https://solidsands.com/
priority: 100
topIcon: true
- name: JetBrains
img: https://static.ce-cdn.net/jetbrains.svg
description: Developer Tools for Professionals and Teams
priority: 50
url: https://jetbrains.com/
- name: Patreon Legends
description: 'These amazing people have pledged at the highest level of support. Huge thanks to these fine folks:'
class: legendary
sponsors:
- name: Ólafur Waage
url: https://twitter.com/olafurw
- name: Aras Pranckevičius
url: https://aras-p.info/
- name: Stefan Hagen
url: https://stefan-hagen.website/
- name: Robert Douglas
url: https://www.youtube.com/channel/UCxwGBrWeIIWO9V_uLwRWCdA/videos
- Dylan Houlihan
- Igor Zarzycki
- TocarIP
- name: Jane Lusby
url: https://rustbeginners.github.io/awesome-rust-mentors/
- Corey Kosak
- name: Ondra Karlik
url: https://cgg.mff.cuni.cz/~jaroslav/
description: In memory of Jaroslav Křivánek
- name: Patreons
description: 'Thanks to all my patrons:'
sponsors:
- Karl
- Matthew Butler
- Gareth Lloyd
- Arne Mertz
- Peter Bindels
- Slobodan Milnovic
- Martin
- Sylvain Joubert
- Nathan Bronson
- Kaz Tros
- Jean-François
- Charles Wilkes
- Kaido Kert
- Carsten Schultz
- Cornel Izbasa
- Stefan Groth
- Sorin Suciu
- Andreas Gravgaard Andersen
- Nathan Myers
- Eugene Nemchenko
- Bill Caputo
- Christoph Siedentop
- Dendi Suhubdy
- Ilya F.
- Bastian Kauschke
- Youngsuk Kim
- Trent Nelson
- Guts
- Noel Cower
- Alina Banerjee
- Jean-Luc Burhop
- Detlef Grohs
- Phil Burr
- Mike Babb
- Matias Christensen
- Siddhant Nadkarni
- Emyr Williams
- Ed Rochenski
- William Wold
- Juan Gómez
- Christopher Koschack
- Björn Fahller
- Michael Pearce
- Solid Sands
- William Woodall
- Stefan Petersen
- Jason Lovett
- Tomas Dittmann
- Cory Benfield
- Tyler Hou
- Austin Morton
- William Andersen
- Joseph Malle
- Chris Marchetti
- Ian Cullinan
- Devon Richard
- Greg Miller
- Heinz N. Gies
- Alison Chaiken
- David Capello
- Amos Wenger
- Kacper Kolodziej
- Tony Magro
- Morten Brenna
- Jake Arkinstall
- ghochee
- Shane Clifford
- Eduardo Costa
- Ryan Sims
- Dmytro Lytovchenko
- Wraithan McCarroll
- Jean-Simon Lapointe
- David C Black
- Venkatesh Srinivas
- Ruslan Abdikeev
- Benjamin Demick
- Reiner Eiteljoerge
- Johnathan Roatch
- John Biesnecker
- Paul Williams
- CB Bailey
- Joe Doyle
- Jason Rice
- Rui Ueyama
- Narut Sereewattanawoot
- Travis Geiselbrecht
- Chris Kennelly
- Tom Hulton-Harrop
- Adenilson Cavalcanti
- Wojciech Bartnik
- Richard Powell
- Hayk Karapetyan
- Colden Cullen
- Josh Seba
- Matt Pharr
- Ajay Agrawal
- Dog Junko
- Robert Bigelow
- Lewis Cowles
- Yuri Kunde Schlesner
- Glen Fernandes
- Richard Smith
- Keith Bennett
- Herman Polloni
- Simon Parker
- Andrew McKinlay
- Adam Badura
- Max Langhof
- Ben Gras
- Alexandre Baiao
- Daniel Nissenbaum
- Gynvael
- Mikhail Smirnov
- Mike Cowan
- paercebal
- ThePhD
- Michał Bartoszkiewicz
- James Clarke
- Kalyankumar Ramaseshan
- Pierre-Marie Charavel
- Brian L. Troutwine
- -Y-
- Graham Carl Evans
- Frank Leon Rose
- Nathan Burles
- Tianyu Ge
- Kale Blankenship
- Erik Lundin
- Matt Weber
- Marcin # dmz1978
- Laurențiu Nicola
- Joe Ranweiler
- modocache
- Shao Voon
- Paul Groke # swampmonster9
- Travis Wehrman
- Shivanker Goel
- Hana Dusíková
- Chris Warner
- Evan Rowley
- Glenn
- Alexander Guettler
- Alejandro Lucena
- xyx
- Chris Luke
- Casey Carter
- Adam Greig
- Eric Perko
- Christopher Di Bella
- William Killian
- Matt Hargett
- Jeff Trull
- John McFarlane
- Jaewon Jung
- Garret Kelly
- Dan Luu
- Tim Cool
- Jerry Ryle
- ileonte
- Matt Weber
- Simon Haegler
- Jon Kalb
- Reuben Scratton
- Gaëtan Barel
- Zhihao Yuan
- David Jones
- relgukxilef
- Markus Lanner
- Igor Ivanov
- Thomas Trummer
- Andy Bond
- Michael Spencer
- Dmitry Kozhevnikov
- David Starr
- Nejc Vivod
- Thomas Goyne
- Federico Lebron
- François Andrieux
- Mark Atkinson
- Thomas Pape
- Robin Jubber
- Laurynas Biveinis
- Robert Snell
- Michał Dominiak
- Chris Newland
- Miguel Escudero
- Ian Carroll
- Jonathan Anderson
- Vimarsh Raina
- Gabriel Garcia
- Malcolm Rowe
- Jon Raymond
- Bene
- Billy

View File

@@ -77,6 +77,7 @@ class ClientOptionsHandler {
googleAnalyticsEnabled: ceProps('clientGoogleAnalyticsEnabled', false),
sharingEnabled: ceProps('clientSharingEnabled', true),
githubEnabled: ceProps('clientGitHubRibbonEnabled', true),
showSponsors: ceProps('showSponsors', false),
gapiKey: ceProps('googleApiKey', ''),
googleShortLinkRewrite: ceProps('googleShortLinkRewrite', '').split('|'),
urlShortenService: ceProps('urlShortenService', 'default'),

66
lib/sponsors.js Normal file
View File

@@ -0,0 +1,66 @@
// Copyright (c) 2020, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
"use strict";
const yaml = require('yaml');
function namify(mapOrString) {
if (typeof (mapOrString) == "string") return {name: mapOrString};
return mapOrString;
}
function clickify(sponsor) {
if (sponsor.url) {
sponsor.onclick=`window.onSponsorClick(${JSON.stringify(sponsor)});`;
}
return sponsor;
}
function compareSponsors(lhs, rhs) {
const lhsPrio = lhs.priority || 0;
const rhsPrio = rhs.priority || 0;
if (lhsPrio !== rhsPrio) return rhsPrio - lhsPrio;
return lhs.name.localeCompare(rhs.name);
}
function loadFromString(stringConfig) {
const sponsorConfig = yaml.parse(stringConfig);
// TODO: on final merge, update Patreon information.
// TODO: on final merge, ensure thanks.html matches sponsors.yaml
sponsorConfig.icons = [];
for (const level of sponsorConfig.levels) {
for (const required of ['name', 'description'])
if (!level[required])
throw new Error(`Level is missing '${required}'`);
level.sponsors = level.sponsors
.map(namify)
.map(clickify)
.sort(compareSponsors);
sponsorConfig.icons.push(...level.sponsors.filter(sponsor => sponsor.topIcon && sponsor.img));
}
return sponsorConfig;
}
exports.loadFromString = loadFromString;

45
package-lock.json generated
View File

@@ -202,6 +202,21 @@
"integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==",
"dev": true
},
"@babel/runtime": {
"version": "7.9.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
"integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==",
"requires": {
"regenerator-runtime": "^0.13.4"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.13.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
"integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
}
}
},
"@babel/template": {
"version": "7.8.6",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
@@ -2518,6 +2533,15 @@
"regexp.prototype.flags": "^1.2.0"
}
},
"deep-equal-in-any-order": {
"version": "1.0.27",
"resolved": "https://registry.npmjs.org/deep-equal-in-any-order/-/deep-equal-in-any-order-1.0.27.tgz",
"integrity": "sha512-yxZ1zYvaiZidcpprBq5hZdbiWNzNXQtcDjc10R2iMfoCgYx6oIdwkPrIaXbcvZkk6spsJvG/C1nRyVTcI748Jg==",
"requires": {
"lodash.mapvalues": "^4.6.0",
"sort-any": "^1.1.21"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -5816,6 +5840,11 @@
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"lodash.mapvalues": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
"integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw="
},
"log-symbols": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
@@ -8962,6 +8991,14 @@
}
}
},
"sort-any": {
"version": "1.1.22",
"resolved": "https://registry.npmjs.org/sort-any/-/sort-any-1.1.22.tgz",
"integrity": "sha512-RDDFA8jZTeYQgH7icQQV+O6ZMC3ZmNLIx8EBbqQPM3J/Wi0iuHrdd/BIr8V6mUlaYEL8RFK2wP+G3q1OiiviWQ==",
"requires": {
"lodash": "^4.17.15"
}
},
"sort-keys": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
@@ -10951,6 +10988,14 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"yaml": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.3.tgz",
"integrity": "sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw==",
"requires": {
"@babel/runtime": "^7.8.7"
}
},
"yamljs": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.2.10.tgz",

View File

@@ -28,6 +28,7 @@
"compiler-opt-info": "0.0.4",
"compression": "^1.7.1",
"cross-env": "^7.0.2",
"deep-equal-in-any-order": "^1.0.27",
"es6-promise": "^4.2.8",
"es6-shim": "^0.35.5",
"express": "^4.17.1",
@@ -66,7 +67,8 @@
"which": "^2.0.2",
"winston": "^3.2.1",
"winston-papertrail": "^1.0.5",
"wolfy87-eventemitter": "^5.2.9"
"wolfy87-eventemitter": "^5.2.9",
"yaml": "^1.8.3"
},
"devDependencies": {
"@sentry/cli": "^1.52.1",

View File

@@ -539,4 +539,90 @@ kbd {
/* Fix the width to allow bootstrap's right-justify to work, else it truncates. See https://github.com/mattgodbolt/compiler-explorer/issues/1863 */
div.populararguments div.dropdown-menu {
width: 300px;
}
}
.sponsor-root {
max-height: 200px;
overflow-y: scroll;
}
@media (min-height: 700px) {
.sponsor-root {
max-height: 350px;
}
}
@media (min-height: 1000px) {
.sponsor-root {
max-height: 600px;
}
}
@media (min-height: 1200px) {
.sponsor-root {
max-height: 700px;
}
}
@media (min-height: 1800px) {
.sponsor-root {
max-height: 1200px;
}
}
@media (max-width: 1000px) {
.sponsor-root {
font-size: 60%;
}
}
.sponsor-block:not(:first-child) {
margin-top: 6em;
}
.sponsors {
margin-top: 1em;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
}
.sponsor-title {
font-size: 200%;
font-weight: bold;
}
.sponsor-title img {
margin: 0.5em;
}
.sponsor {
flex-grow: 1;
margin: 2px;
font-size: 70%;
}
.sponsor button {
padding: 4px;
height: 100%;
}
.corporate .sponsor {
font-size: 180%;
height: 300px
}
.legendary .sponsor {
font-size: 175%;
height: 7em;
}
.legendary .sponsor {
font-size: 175%;
height: 7em;
}
.legendary .sponsor button {
padding: 1em;
}

View File

@@ -69,7 +69,9 @@ if (!String.prototype.includes) {
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) { start = 0; }
if (start === undefined) {
start = 0;
}
return this.indexOf(search, start) !== -1;
};
}
@@ -167,9 +169,6 @@ function setupButtons(options) {
window.open('/', '_blank');
});
$('#thanks-to').click(function () {
alertSystem.alert("Special thanks to", $(require('./thanks.html')));
});
$('#changes').click(function () {
alertSystem.alert("Changelog", $(require('./changelog.html')));
});
@@ -311,7 +310,7 @@ function start() {
});
// Which buttons act as a linkable popup
var linkablePopups = ['#thanks-to', '#changes', '#cookies', '#setting', '#privacy'];
var linkablePopups = ['#sponsors', '#changes', '#cookies', '#setting', '#privacy'];
var hashPart = linkablePopups.indexOf(window.location.hash) > -1 ? window.location.hash : null;
if (hashPart) {
window.location.hash = "";
@@ -440,6 +439,25 @@ function start() {
$('[name="editor-btn-toolbar"]').addClass("d-none");
}
window.onSponsorClick = function (sponsor) {
analytics.proxy('send', {
hitType: 'event',
eventCategory: 'Sponsors',
eventAction: 'click',
eventLabel: sponsor.url,
transport: 'beacon'
});
window.open(sponsor.url);
};
$('#sponsorsPopup').on('shown.bs.modal', function () {
analytics.proxy('send', {
hitType: 'event',
eventCategory: 'Sponsors',
eventAction: 'open'
});
});
sizeRoot();
lastState = JSON.stringify(layout.toConfig());
}

View File

@@ -1,271 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<style>
.thanks-container {
padding: 2px 2px 10px 2px;
margin: 0;
list-style: none;
display: flex;
align-items: center;
flex-flow: row wrap;
justify-content: space-around;
overflow-y: auto;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */
}
.thanks-container > li {
border: 2px solid #1b330e;
box-shadow: 5px 5px 5px #004400;
border-radius: 5px;
background: #55a625; /* Old browsers */
background: -moz-linear-gradient(-45deg, #55a625 0%, #52bf00 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(-45deg, #55a625 0%, #52bf00 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(135deg, #55a625 0%, #52bf00 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
padding: 4px;
min-width: 100px;
margin-top: 10px;
margin-right: 10px;
text-align: center;
font-size: 1.5em;
}
.thanks-container > li:hover {
border: 2px solid #3b6f1e;
background: #02c500; /* Old browsers */
background: -moz-linear-gradient(-45deg, #02c500 0%, #52bf00 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(-45deg, #02c500 0%, #52bf00 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(135deg, #02c500 0%, #52bf00 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
}
.thanks-container.legend {
font-size: 2em;
line-height: 1;
font-weight: bold;
}
.thanks-container.legend > li {
height: 70px;
padding: 8px;
}
</style>
<body>
<h3>Legendary <a href="https://www.patreon.com/mattgodbolt" target="_blank" rel="noreferrer noopener">Patreon</a> Supporters</h3>
<p>These amazing people have pledged at the highest level of support. Huge thanks to these fine folks:</p>
<ul class="thanks-container legend">
<li><a href="https://twitter.com/olafurw" target="_blank" rel="noreferrer noopener">Ólafur Waage</a></li>
<li><a href="https://aras-p.info/" target="_blank" rel="noreferrer noopener">Aras Pranckevičius</a></li>
<li><a href="https://stefan-hagen.website/" target="_blank" rel="noreferrer noopener">Stefan Hagen</a></li>
<li><a href="https://www.youtube.com/channel/UCxwGBrWeIIWO9V_uLwRWCdA/videos" target="_blank" rel="noreferrer noopener">Robert Douglas</a></li>
<li><a href="javascript:;">Dylan Houlihan</a></li>
<li>Igor Zarzycki</li>
<li>TocarIP</li>
<li><a href="https://rustbeginners.github.io/awesome-rust-mentors/" target="_blank" rel="noreferrer noopener">Jane Lusby</a></li>
<li><a href="javascript:;">Corey Kosak</a></li>
<li><a href="https://cgg.mff.cuni.cz/~jaroslav/" target="_blank" rel="noreferrer noopener" title="In memory of Jaroslav Křivánek">Ondra Karlik</a></li>
</ul>
<h3><a href="https://www.patreon.com/mattgodbolt" target="_blank" rel="noreferrer noopener">Patreon</a> Supporters</h3>
<p>These amazing people have pledged their support to help the development of Compiler Explorer. Thanks to each and
every one of you!</p>
<ul class="thanks-container">
<li>Karl</li>
<li>Matthew Butler</li>
<li>Gareth Lloyd</li>
<li>Arne Mertz</li>
<li>Peter Bindels</li>
<li>Slobodan Milnovic</li>
<li>Martin</li>
<li>Sylvain Joubert</li>
<li>Nathan Bronson</li>
<li>Kaz Tros</li>
<li>Jean-François</li>
<li>Charles Wilkes</li>
<li>Kaido Kert</li>
<li>Carsten Schultz</li>
<li>Cornel Izbasa</li>
<li>Stefan Groth</li>
<li>Sorin Suciu</li>
<li>Andreas Gravgaard Andersen</li>
<li>Nathan Myers</li>
<li>Eugene Nemchenko</li>
<li>Bill Caputo</li>
<li>Christoph Siedentop</li>
<li>Dendi Suhubdy</li>
<li>Ilya F.</li>
<li>Bastian Kauschke</li>
<li>Youngsuk Kim</li>
<li>Trent Nelson</li>
<li>Guts</li>
<li>Noel Cower</li>
<li>Alina Banerjee</li>
<li>Jean-Luc Burhop</li>
<li>Detlef Grohs</li>
<li>Phil Burr</li>
<li>Mike Babb</li>
<li>Matias Christensen</li>
<li>Siddhant Nadkarni</li>
<li>Emyr Williams</li>
<li>Ed Rochenski</li>
<li>William Wold</li>
<li>Juan Gómez</li>
<li>Christopher Koschack</li>
<li>Björn Fahller</li>
<li>Michael Pearce</li>
<li>Solid Sands</li>
<li>William Woodall</li>
<li>Stefan Petersen</li>
<li>Jason Lovett</li>
<li>Tomas Dittmann</li>
<li>Cory Benfield</li>
<li>Tyler Hou</li>
<li>Austin Morton</li>
<li>William Andersen</li>
<li>Joseph Malle</li>
<li>Chris Marchetti</li>
<li>Ian Cullinan</li>
<li>Devon Richard</li>
<li>Greg Miller</li>
<li>Heinz N. Gies</li>
<li>Alison Chaiken</li>
<li>David Capello</li>
<li>Amos Wenger</li>
<li>Kacper Kolodziej</li>
<li>Tony Magro</li>
<li>Morten Brenna</li>
<li>Jake Arkinstall</li>
<li>ghochee</li>
<li>Shane Clifford</li>
<li>Eduardo Costa</li>
<li>Ryan Sims</li>
<li>Dmytro Lytovchenko</li>
<li>Wraithan McCarroll</li>
<li>Jean-Simon Lapointe</li>
<li>David C Black</li>
<li>Venkatesh Srinivas</li>
<li>Ruslan Abdikeev</li>
<li>Benjamin Demick</li>
<li>Reiner Eiteljoerge</li>
<li>Johnathan Roatch</li>
<li>John Biesnecker</li>
<li>Paul Williams</li>
<li>CB Bailey</li>
<li>Joe Doyle</li>
<li>Jason Rice</li>
<li>Rui Ueyama</li>
<li>Narut Sereewattanawoot</li>
<li>Travis Geiselbrecht</li>
<li>Chris Kennelly</li>
<li>Tom Hulton-Harrop</li>
<li>Adenilson Cavalcanti</li>
<li>Wojciech Bartnik</li>
<li>Richard Powell</li>
<li>Hayk Karapetyan</li>
<li>Colden Cullen</li>
<li>Josh Seba</li>
<li>Matt Pharr</li>
<li>Ajay Agrawal</li>
<li>Dog Junko</li>
<li>Robert Bigelow</li>
<li>Lewis Cowles</li>
<li>Yuri Kunde Schlesner</li>
<li>Glen Fernandes</li>
<li>Richard Smith</li>
<li>Keith Bennett</li>
<li>Herman Polloni</li>
<li>Simon Parker</li>
<li>Andrew McKinlay</li>
<li>Adam Badura</li>
<li>Max Langhof</li>
<li>Ben Gras</li>
<li>Alexandre Baiao</li>
<li>Daniel Nissenbaum</li>
<li>Gynvael</li>
<li>Mikhail Smirnov</li>
<li>Mike Cowan</li>
<li>paercebal</li>
<li>ThePhD</li>
<li>Michał Bartoszkiewicz</li>
<li>James Clarke</li>
<li>Kalyankumar Ramaseshan</li>
<li>Pierre-Marie Charavel</li>
<li>Brian L. Troutwine</li>
<li>-Y-</li>
<li>Graham Carl Evans</li>
<li>Frank Leon Rose</li>
<li>Nathan Burles</li>
<li>Tianyu Ge</li>
<li>Kale Blankenship</li>
<li>Erik Lundin</li>
<li>Matt Weber</li>
<li>Marcin<!-- dmz1978 --></li>
<li>Laurențiu Nicola</li>
<li>Joe Ranweiler</li>
<li>modocache</li>
<li>Shao Voon</li>
<li>Paul Groke<!-- swampmonster9 --></li>
<li>Travis Wehrman</li>
<li>Shivanker Goel</li>
<li>Hana Dusíková</li>
<li>Chris Warner</li>
<li>Evan Rowley</li>
<li>Glenn</li>
<li>Alexander Guettler</li>
<li>Alejandro Lucena</li>
<li>xyx</li>
<li>Chris Luke</li>
<li>Casey Carter</li>
<li>Adam Greig</li>
<li>Eric Perko</li>
<li>Christopher Di Bella</li>
<li>William Killian</li>
<li>Matt Hargett</li>
<li>Jeff Trull</li>
<li>John McFarlane</li>
<li>Jaewon Jung</li>
<li>Garret Kelly</li>
<li>Dan Luu</li>
<li>Tim Cool</li>
<li>Jerry Ryle</li>
<li>ileonte</li>
<li>Matt Weber</li>
<li>Simon Haegler</li>
<li>Jon Kalb</li>
<li>Reuben Scratton</li>
<li>Ga&euml;tan Barel</li>
<li>Zhihao Yuan</li>
<li>David Jones</li>
<li>relgukxilef</li>
<li>Markus Lanner</li>
<li>Igor Ivanov</li>
<li>Thomas Trummer</li>
<li>Andy Bond</li>
<li>Michael Spencer</li>
<li>Dmitry Kozhevnikov</li>
<li>David Starr</li>
<li>Nejc Vivod</li>
<li>Thomas Goyne</li>
<li>Federico Lebron</li>
<li>Fran&ccedil;ois Andrieux</li>
<li>Mark Atkinson</li>
<li>Thomas Pape</li>
<li>Robin Jubber</li>
<li>Laurynas Biveinis</li>
<li>Robert Snell</li>
<li>Michał Dominiak</li>
<li>Chris Newland</li>
<li>Miguel Escudero</li>
<li>Ian Carroll</li>
<li>Jonathan Anderson</li>
<li>Vimarsh Raina</li>
<li>Gabriel Garcia</li>
<li>Malcolm Rowe</li>
<li>Jon Raymond</li>
<li>Bene</li>
<li>Billy</li>
</ul>
</body>
</html>

138
test/sponsors-test.js Normal file
View File

@@ -0,0 +1,138 @@
// Copyright (c) 2020, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ,
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
const chai = require('chai');
chai.should();
chai.use(require('deep-equal-in-any-order'));
const sponsors = require('../lib/sponsors');
describe('Sponsors', () => {
it('should load a simple example', () => {
const sample = sponsors.loadFromString(`
---
levels:
- name: Patreon Legends
description: 'These amazing people have pledged at the highest level of support. Huge thanks to these fine folks:'
sponsors:
- name: Kitty Kat
url: https://meow.meow
- name: Aardvark
url: https://ard.vark
- name: Patreons
description: 'Thanks to all my patrons:'
sponsors:
- Lovely
- People
- Yay
`);
sample.should.not.be.null;
sample.levels.length.should.eq(2);
sample.levels[0].name.should.eq('Patreon Legends');
sample.levels[1].name.should.eq('Patreons');
});
it('should expand names to objects', () => {
const folks = sponsors.loadFromString(`
---
levels:
- name: a
description: d
sponsors:
- Just a string
- name: An object
`).levels[0].sponsors;
folks.length.should.eq(2);
folks.should.deep.contain({name: 'An object'});
folks.should.deep.contain({name: 'Just a string'});
});
it('should sort sponsors by name', () => {
const peeps = sponsors.loadFromString(`
---
levels:
- name: a
description: d
sponsors:
- D
- C
- A
- B
`).levels[0].sponsors;
peeps.should.deep.equals([
{name: 'A'},
{name: 'B'},
{name: 'C'},
{name: 'D'}
]);
});
it('should sort sponsors by priority then name', () => {
const peeps = sponsors.loadFromString(`
---
levels:
- name: a
description: d
sponsors:
- name: D
priority: 100
- name: C
priority: 50
- name: B
priority: 50
`).levels[0].sponsors;
peeps.should.deep.equals([
{name: 'D', priority: 100},
{name: 'B', priority: 50},
{name: 'C', priority: 50}
]);
});
it('should pick out the top level icons', () => {
const icons = sponsors.loadFromString(`
---
levels:
- name: a
description: d
sponsors:
- name: one
img: pick_me
topIcon: true
- name: two
img: not_me
- name: another level
description: more
sponsors:
- name: three
img: not_me_either
topIcon: false
- name: four
img: pick_me_also
topIcon: true
- name: five
topIcon: true
`).icons;
icons.should.deep.equalInAnyOrder([
{name: "one", img: "pick_me", topIcon: true},
{name: "four", img: "pick_me_also", topIcon: true}
]);
});
});

View File

@@ -49,6 +49,10 @@ block prepend content
span.community-hide(title="Hide and never show again" aria-label="Close")
button.close(type="button" aria-hidden="true") &times;
ul.navbar-nav.navbar-right
if showSponsors
li.nav-item.btn.btn-outline-primary#sponsors(data-toggle="modal" data-target="#sponsorsPopup") Sponsors
each icon in sponsors.icons
img(src=icon.img height=24)
li.nav-item
a.nav-link#share(href="javascript:;") Share
b.fas.fa-caret-down
@@ -62,8 +66,8 @@ block prepend content
span.dropdown-icon.fab.fa-github-alt
| Sponsor on GitHub
a.dropdown-item(
href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=KQWQZ7GPY2GZ6&item_name=Compiler+Explorer+development&currency_code=USD&source=url"
title="Make a one-time donation to help fund Compiler Explorer's development" target="_blank" rel="noopener")
href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=KQWQZ7GPY2GZ6&item_name=Compiler+Explorer+development&currency_code=USD&source=url"
title="Make a one-time donation to help fund Compiler Explorer's development" target="_blank" rel="noopener")
span.dropdown-icon.fab.fa-paypal
| Donate via PayPal
if githubEnabled
@@ -82,9 +86,6 @@ block prepend content
a.dropdown-item(href="https://github.com/mattgodbolt/compiler-explorer/issues" target="_blank" rel="noopener")
span.dropdown-icon.fas.fa-exclamation-circle
| Report an issue
a.dropdown-item#thanks-to(href="javascript:;")
span.dropdown-icon.fas.fa-users
| Thanks to...
a.dropdown-item(href="https://xania.org/201609/how-compiler-explorer-runs-on-amazon" target="_blank")
span.dropdown-icon.fas.fa-cloud-meatball
| How it works
@@ -114,4 +115,4 @@ block prepend content
| Privacy policy
block append footer
include popups.pug
include popups.pug

View File

@@ -65,6 +65,54 @@
button.btn.btn-light.no(type="button" data-dismiss="modal") No
button.btn.btn-light.yes(type="button" data-dismiss="modal") Yes
#sponsorsPopup.modal.fade.gl_keep(tabindex="-1" role="dialog")
.modal-dialog.modal-lg
.modal-content
.modal-header
h5.modal-title Compiler Explorer Sponsors
button.close(type="button" data-dismiss="modal" aria-hidden="true" aria-label="Close")
span(aria-hidden="true")
| &times;
.modal-body
div.d-flex.justify-content-center.mt-3
div.btn-group.btn-group
each level, index in sponsors.levels
button.btn.btn-primary(onclick='document.getElementById("sponsor_hop_' + index + '").scrollIntoView();')=level.name
.sponsor-root.mt-6
.sponsor-blurb
| Compiler Explorer is proud to be sponsored by a number of individuals and companies. We thank them for
| making this website free for all. If you'd like to help, consider becoming a&nbsp;
a(href="https://www.patreon.com/bePatron?u=3691963" title="Help Compiler Explorer - become a Patron" target="_blank" rel="noopener")
span.fab.fa-patreon Patreon
| , sponsor on&nbsp;
a(href="https://github.com/sponsors/mattgodbolt" title="Help Compiler Explorer - sponsor on GitHub" target="_blank" rel="noopener")
span.fab.fa-github-alt GitHub,
| , make a one-time donation on&nbsp;
a(href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=KQWQZ7GPY2GZ6&item_name=Compiler+Explorer+development&currency_code=USD&source=url" title="Make a one-time donation to help fund Compiler Explorer's development" target="_blank" rel="noopener")
span.fab.fa-paypal PayPal
| , or&nbsp;
a(href="mailto:matt@godbolt.org") email Matt
| &nbsp;for corporate sponsorship.
.mt-6
each level, index in sponsors.levels
.sponsor-block(class=level.class id="sponsor_hop_" + index)
h2.sponsor-name= level.name
div.sponsor-description= level.description
.sponsors
each sponsor in level.sponsors
.sponsor
button.btn-block.btn-secondary(title=sponsor.title onclick=sponsor.onclick disabled=!sponsor.url)
span.sponsor-title
if sponsor.img
img(src=sponsor.img)
= sponsor.name
if sponsor.description
.sponsor-description
= sponsor.description
.modal-footer
button.btn.btn-light(type="button" data-dismiss="modal") Close
#settings.modal.fade.gl_keep(tabindex="-1" role="dialog")
.modal-dialog.modal-lg
.modal-content