mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-14 05:11:19 -04:00
Added a language switcher for snowflake.tp.o
Also modified the styling of the page to match the main tp.o page a bit more
This commit is contained in:
parent
f6517f60ce
commit
ab96817381
4 changed files with 8228 additions and 98 deletions
8088
proxy/static/bootstrap.css
vendored
Normal file
8088
proxy/static/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -9,24 +9,17 @@ body {
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
background-color: #59316B;
|
|
||||||
color: #212529;
|
color: #212529;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 0;
|
background-color: #59316B;
|
||||||
padding: 1.3rem 2.6rem;
|
padding: 0 5.2rem;
|
||||||
}
|
|
||||||
|
|
||||||
header a {
|
|
||||||
border-style: none;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
max-width: 55rem;
|
max-width: 90rem;
|
||||||
margin: 0 auto 2.6rem auto;
|
margin: 0 auto 2.6rem auto;
|
||||||
padding: 2.6rem 5.2rem;
|
padding: 2.6rem 5.2rem;
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
|
@ -77,6 +70,7 @@ h2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.diagram, .screenshot {
|
.diagram, .screenshot {
|
||||||
|
padding: 2.6rem 5.2rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,3 +82,13 @@ textarea {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 600px;
|
width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown:hover .dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
height: 350px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-right {
|
||||||
|
float: right !important;
|
||||||
|
}
|
||||||
|
|
|
@ -4,15 +4,30 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Snowflake</title>
|
<title>Snowflake</title>
|
||||||
<link rel="icon" href="https://snowflake.torproject.org/assets/favicon.ico" />
|
<link rel="icon" href="./assets/favicon.ico" />
|
||||||
<link rel="stylesheet" href="https://snowflake.torproject.org/index.css" />
|
<link rel="stylesheet" href="./bootstrap.css" />
|
||||||
|
<link rel="stylesheet" href="./index.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="no-gutters">
|
||||||
<header id="header">
|
<header id="header">
|
||||||
<a href="https://www.torproject.org/">
|
|
||||||
<img src="https://snowflake.torproject.org/tor-logo@2x.png" alt="Tor" height="50" />
|
<nav class="navbar no-background navbar-dark bg-dark p-4">
|
||||||
|
|
||||||
|
<a class="navbar-brand" href="https://www.torproject.org/">
|
||||||
|
<img src="./tor-logo@2x.png" alt="Tor" height="50" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div class="btn-group dropdown pull-right">
|
||||||
|
|
||||||
|
<button id="language-switcher" type="button" class="btn btn-dark bg-dark dropdown-toggle btn-block my-3 my-sm-0" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
en_US
|
||||||
|
</button>
|
||||||
|
<div id="supported-languages" class="dropdown-menu">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
<div class="container-fluid">
|
||||||
<section id="content">
|
<section id="content">
|
||||||
<h1>SNOWFLAKE</h1>
|
<h1>SNOWFLAKE</h1>
|
||||||
|
|
||||||
|
@ -32,7 +47,7 @@
|
||||||
<p data-msgid="__MSG_censoredUsers__">If your internet access is censored, you should download
|
<p data-msgid="__MSG_censoredUsers__">If your internet access is censored, you should download
|
||||||
<a href="https://www.torproject.org/download/">Tor Browser</a>.</p>
|
<a href="https://www.torproject.org/download/">Tor Browser</a>.</p>
|
||||||
|
|
||||||
<p class="screenshot"><img src="https://snowflake.torproject.org/screenshot.png" alt="Tor Browser screenshot" /></p>
|
<p class="screenshot"><img src="./screenshot.png" alt="Tor Browser screenshot" /></p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="extension" class="extension">
|
<section id="extension" class="extension">
|
||||||
|
@ -46,11 +61,11 @@
|
||||||
|
|
||||||
<p class="addon">
|
<p class="addon">
|
||||||
<a href="https://addons.mozilla.org/en-US/firefox/addon/torproject-snowflake/">
|
<a href="https://addons.mozilla.org/en-US/firefox/addon/torproject-snowflake/">
|
||||||
<img src="https://snowflake.torproject.org/firefox150.jpg" alt="Install in Firefox" height="100" /><br />
|
<img src="./firefox150.jpg" alt="Install in Firefox" height="100" /><br />
|
||||||
<span data-msgid="MSG_installFirefox__">Install in Firefox</span>
|
<span data-msgid="MSG_installFirefox__">Install in Firefox</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://chrome.google.com/webstore/detail/snowflake/mafpmfcccpbjnhfhjnllmmalhifmlcie">
|
<a href="https://chrome.google.com/webstore/detail/snowflake/mafpmfcccpbjnhfhjnllmmalhifmlcie">
|
||||||
<img src="https://snowflake.torproject.org/chrome150.jpg" alt="Install in Chrome" height="100" /><br />
|
<img src="./chrome150.jpg" alt="Install in Chrome" height="100" /><br />
|
||||||
<span data-msgid="__MSG_installChrome__">Install in Chrome</span>
|
<span data-msgid="__MSG_installChrome__">Install in Chrome</span>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -96,6 +111,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
/* global availableLangs */
|
||||||
|
|
||||||
class Messages {
|
class Messages {
|
||||||
constructor(json) {
|
constructor(json) {
|
||||||
this.json = json;
|
this.json = json;
|
||||||
}
|
}
|
||||||
getMessage(m, ...rest) {
|
getMessage(m, ...rest) {
|
||||||
if (this.json.hasOwnProperty(m)) {
|
if (Object.prototype.hasOwnProperty.call(this.json, m)) {
|
||||||
let message = this.json[m].message;
|
let message = this.json[m].message;
|
||||||
return message.replace(/\$(\d+)/g, (...args) => {
|
return message.replace(/\$(\d+)/g, (...args) => {
|
||||||
return rest[Number(args[1]) - 1];
|
return rest[Number(args[1]) - 1];
|
||||||
|
@ -13,11 +15,20 @@ class Messages {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultLang = "en_US";
|
var defaultLang = "en_US";
|
||||||
|
|
||||||
var getLang = function() {
|
var getLang = function() {
|
||||||
let lang = navigator.language || defaultLang;
|
let lang = navigator.language || defaultLang;
|
||||||
lang = lang.replace(/-/g, '_');
|
lang = lang.replace(/-/g, '_');
|
||||||
|
|
||||||
|
//prioritize override language
|
||||||
|
var url_string = window.location.href; //window.location.href
|
||||||
|
var url = new URL(url_string);
|
||||||
|
var override_lang = url.searchParams.get("lang");
|
||||||
|
if (override_lang != null) {
|
||||||
|
lang = override_lang;
|
||||||
|
}
|
||||||
|
|
||||||
if (availableLangs.has(lang)) {
|
if (availableLangs.has(lang)) {
|
||||||
return lang;
|
return lang;
|
||||||
}
|
}
|
||||||
|
@ -31,9 +42,10 @@ var getLang = function() {
|
||||||
var fill = function(n, func) {
|
var fill = function(n, func) {
|
||||||
switch(n.nodeType) {
|
switch(n.nodeType) {
|
||||||
case 1: // Node.ELEMENT_NODE
|
case 1: // Node.ELEMENT_NODE
|
||||||
|
{
|
||||||
const m = /^__MSG_([^_]*)__$/.exec(n.dataset.msgid);
|
const m = /^__MSG_([^_]*)__$/.exec(n.dataset.msgid);
|
||||||
if (m) {
|
if (m) {
|
||||||
val = func(m[1]);
|
var val = func(m[1]);
|
||||||
if (val != undefined) {
|
if (val != undefined) {
|
||||||
n.innerHTML = val
|
n.innerHTML = val
|
||||||
}
|
}
|
||||||
|
@ -42,8 +54,8 @@ var fill = function(n, func) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log("Fetching", `./_locales/${getLang()}/messages.json`);
|
|
||||||
|
|
||||||
fetch(`./_locales/${getLang()}/messages.json`)
|
fetch(`./_locales/${getLang()}/messages.json`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
@ -51,10 +63,20 @@ fetch(`./_locales/${getLang()}/messages.json`)
|
||||||
return res.json();
|
return res.json();
|
||||||
})
|
})
|
||||||
.then((json) => {
|
.then((json) => {
|
||||||
messages = new Messages(json);
|
var language = document.getElementById('language-switcher');
|
||||||
console.log("Filling document body");
|
language.innerText = `${getLang()}`
|
||||||
|
var messages = new Messages(json);
|
||||||
fill(document.body, (m) => {
|
fill(document.body, (m) => {
|
||||||
console.log("Filling ", m);
|
|
||||||
return messages.getMessage(m);
|
return messages.getMessage(m);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Populate language swticher list
|
||||||
|
availableLangs.forEach(function (lang) {
|
||||||
|
var languageList = document.getElementById('supported-languages');
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.setAttribute('href', '?lang='+lang);
|
||||||
|
link.setAttribute('class', "dropdown-item");
|
||||||
|
link.innerText = lang;
|
||||||
|
languageList.lastChild.after(link);
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue