@cloudcannon/suite
Version:
A suite of gulp tools to manage static sites on CloudCannon
647 lines (634 loc) • 23 kB
HTML
<head>
<title>I18n Key Overview</title>
<style>
body {
padding: 0;
margin: 0;
display: flex;
font-family: sans-serif;
background-color: #222;
}
.menu-hide .sidebar {
left: -20vw;
transition: left 0.3s ease, overflow 0.3s ease 0.3s, width 0.3s ease 0.3s, flex 0.3s ease 0.3s;
}
.sidebar {
max-width: 20vw;
flex: 1;
background-color: #eee;
height: calc(100vh - 50px);
margin-top: 50px;
position: relative;
left: 0;
transition: left 0.3s ease 0.3s, overflow 0.3s ease, width 0.3s ease, flex 0.3s ease;
}
#keylist {
width: 100%;
height: 100%;
padding: 0;
overflow-y: scroll;
height: calc(100% - 50px);
margin-top: 50px;
box-sizing: border-box;
}
#keylist > a {
width: 100%;
}
.sidebar #filter {
width: 100%;
padding: 0 10px;
font-size: 18px;
height: 48px;
line-height: 48px;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
}
.sidebar a {
text-decoration: none;
color: #444;
}
.sidebar a.hide {
display: none;
}
.sidebar a:hover div {
background-color: #ddd;
}
.sidebar a:hover div.main {
background-color: transparent;
}
.sidebar div {
display: flex;
flex-wrap: wrap;
padding: 10px 10px;
}
.sidebar div.main {
border-top: solid 1px #444;
border-bottom: solid 1px #444;
}
.sidebar div.main > p.urls span {
background-color: #ff9d42;
color: #444;
}
.sidebar div > p {
margin: 0;
color: #444;
padding: 0 2px;
}
.sidebar div > p.urls {
flex: 1;
text-align: right;
font-size: 10px;
align-self: center;
}
.sidebar div > p.urls span {
display: inline-block;
background-color: #444;
padding: 0 10px;
white-space: nowrap;
height: 20px;
line-height: 20px;
border-radius: 50px;
color: white;
font-weight: bold;
letter-spacing: 0.5px;
}
.sidebar div ul {
width: 100%;
height: 0;
margin: 0;
overflow: hidden;
transition: all 0.5s ease;
padding: 0;
list-style-type: none;
}
.sidebar div.main ul {
height: auto;
margin: 1em 0 0 0;
}
.sidebar div ul li {
padding: 3px 0 3px 5px;
margin-left: 15px;
}
.sidebar div ul li:hover {
background-color: #ddd;
}
.sidebar div ul a.main span {
color: #444;
background-color: #ff9d42;
}
.sidebar div ul li span {
display: inline-block;
background-color: #444;
padding: 0 7px;
margin: 0 0 0 5px;
min-width: 16px;
text-align: center;
white-space: nowrap;
height: 20px;
line-height: 20px;
border-radius: 50px;
color: white;
font-weight: bold;
font-size: 10px;
letter-spacing: 0.5px;
}
.menu-hide .sidebar:after {
left: calc(50% - 15px);
}
.sidebar:after {
content: "";
display: block;
position: fixed;
top: calc(50% - 15px);
left: calc(60% - 15px);
width: 30px;
height: 30px;
border: solid 3px transparent;
border-left: solid 3px white;
z-index: 0;
border-radius: 50%;
animation: spin 500ms linear infinite forwards;
}
@keyframes spin {
0% {
transform: rotateZ(0deg)
}
100% {
transform: rotateZ(360deg)
}
}
.menu-hide .rpanel {
left: 0;
min-width: 100vw;
}
.rpanel {
position: absolute;
left: 20vw;
flex: 4;
height: calc(100vh - 50px);
padding-top: 50px;
overflow-y: scroll;
scroll-behavior: smooth;
transition: all 0.3s ease;
background-color: #444;
min-width: 0;
}
.rpanel.fade {
opacity: 0;
}
#invisibles {
display: flex;
flex-wrap: wrap;
background-color: #222;
}
#invisibles h2 {
color: white;
width: 100%;
text-transform: uppercase;
margin: 10px;
font-size: 16px;
}
#invisibles div {
flex: 0 0 250px;
color: white;
margin: 10px;
cursor: pointer;
border: solid 1px #555;
border-radius: 10px;
padding-top: 10px;
transition: all 0.3s ease;
}
#invisibles div:hover {
border: solid 1px #ccc;
}
#invisibles div.main {
color: #ff9d42;
border: solid 1px #ff9d42;
}
#invisibles div span {
display: inline-block;
padding-left: 10px;
}
#invisibles div span.tag {
display: inline-block;
background-color: #444;
padding: 0 7px;
margin: 0 0 0 5px;
min-width: 16px;
text-align: center;
white-space: nowrap;
height: 20px;
line-height: 20px;
border-radius: 50px;
color: white;
font-weight: bold;
font-size: 10px;
letter-spacing: 0.5px;
vertical-align: bottom;
}
#invisibles div.main span.tag {
color: #444;
background-color: #ff9d42;
}
#invisibles div span.content {
display: block;
margin-top: 10px;
padding: 10px;
border-top: solid 1px #555;
}
.wrap {
position: relative;
}
img {
width: 100%;
position: relative;
z-index: 1;
opacity: 0.6;
}
#fgimg {
position: absolute;
top: 0;
left: 0;
z-index: 2;
opacity: 1;
transition: 0.5s ease;
}
#highlights {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index:3;
}
#highlights div {
position: absolute;
color: transparent;
display: block;
border: solid 0px;
margin: 0;
cursor: pointer;
transition: all 0.5s ease;
overflow: visible;
}
#highlights.showBorders div {
border: solid 2px #ff800a;
margin: -2px;
}
#highlights div.main {
border: solid 4px #ff800a;
margin: -4px;
}
#highlights div span {
display:none;
}
#highlights div.main span {
display: block;
color: #444;
background-color: #ff800a;
position: absolute;
left: -4px;
top: -20px;
height: 20px;
white-space: nowrap;
padding: 0 10px;
line-height: 20px;
font-family: sans-serif;
z-index: 5;
}
#highlights div.main:hover span {
left: -4px;
top: -20px;
}
#highlights div:hover span {
display: block;
color: #444;
background-color: #ff800a;
position: absolute;
left: -2px;
top: -20px;
height: 20px;
white-space: nowrap;
padding: 0 10px;
line-height: 20px;
font-family: sans-serif;
z-index: 5;
}
#menubar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
padding: 0 10px;
color: white;
margin: 0;
box-sizing: border-box;
background-color: #222;
z-index: 10;
}
#urlBar {
display: inline-block;
vertical-align: top;
height: 50px;
line-height: 50px;
margin: 0 20px;
}
#urlBar span {
color: #ff9d42;
display: inline-block;
margin: 0 5px;
}
#menuButton {
width: 32px;
height: 100%;
display: inline-block;
}
#menuButton div {
width: 24px;
height: 4px;
background-color: white;
margin-top: 23px;
margin-left: 4px;
position: relative;
}
#menuButton div:before {
content: "";
display: block;
width: 24px;
height: 4px;
background-color: white;
position: absolute;
top: -10px;
left: 4px;
}
#menuButton div:after {
content: "";
display: block;
width: 24px;
height: 4px;
background-color: white;
position: absolute;
bottom: -10px;
right: 4px;
}
</style>
</head>
<body id="body" class="menu-hide">
<div id="menubar">
<a id="menuButton" href="javascript:void(0)"><div></div></a>
<p id="urlBar">/</p>
</div>
<div class="sidebar" id="lpanel">
<input id="filter" placeholder="Filter"/>
<div id="keylist">
</div>
</div>
<div class="rpanel" id="rpanel">
<div id="invisibles"></div>
<div class="wrap">
<img id="img" src="index.png">
<img id="fgimg" src="index.png">
<div id="highlights"></div>
</div>
</div>
<script>
var body = document.getElementById("body");
var img = document.getElementById("img");
var fgimg = document.getElementById("fgimg");
var box = document.getElementById("highlights");
var lpanel = document.getElementById("lpanel");
var keylist = document.getElementById("keylist");
var rpanel = document.getElementById("rpanel");
var filter = document.getElementById("filter");
var urlBar = document.getElementById("urlBar");
var menuButton = document.getElementById("menuButton");
var invisibles = document.getElementById("invisibles");
var hideTimer;
var currentUrl = "";
box.addEventListener("mousemove", function() {
box.classList.add("showBorders");
clearTimeout(hideTimer);
hideTimer = setTimeout(function() {
box.classList.remove("showBorders");
}, 2000);
});
menuButton.addEventListener("mouseup", function() {
if (body.classList.contains("menu-hide")) {
body.classList.remove("menu-hide");
} else {
body.classList.add("menu-hide");
}
});
filter.addEventListener("keyup", updateList);
filter.addEventListener("change", updateList);
function updateList() {
if (!filter.value) {
document.querySelectorAll('.sidebar a').forEach(function(element){
element.classList.remove("hide");
});
return;
}
document.querySelectorAll('.sidebar a').forEach(function(element){
element.classList.add("hide");
});
document.querySelectorAll('[href*="'+filter.value+'"]').forEach(function(element){
element.classList.remove("hide");
});
}
var keytag = window.location.hash.substring(1);
var tagmap = {};
fetchJSONFile('map.json', function(data){
tagmap = data;
var sortedTagmap = Object.keys(tagmap).sort(function(a,b){
if(a < b) return -1;
if(a > b) return 1;
return 0;
});
for (var i = 0; i < sortedTagmap.length; i++) {
var tagtextnode = CR("P", sortedTagmap[i]);
var urlcountnode = CR("P", null, ["urls"]);
var urlcountnodespan = CR("SPAN", tagmap[sortedTagmap[i]].pages.length + " URLS");
urlcountnode.appendChild(urlcountnodespan);
var awrap = CR("A");
var mainnode = CR("DIV", null, null, "to-"+sortedTagmap[i]);
mainnode.appendChild(tagtextnode);
mainnode.appendChild(urlcountnode);
var listnode = CR("UL");
var nodeonpagecount = {};
for (var j = 0; j < tagmap[sortedTagmap[i]].pages.length; j++) {
var nodelisting = tagmap[sortedTagmap[i]].pages[j];
nodeonpagecount[nodelisting.url] = nodeonpagecount[nodelisting.url] || 0;
var listelementnode = CR("LI", "/"+nodelisting.url);
var tagtypenode = CR("SPAN", nodelisting.type);
var innerawrap = CR("A");
innerawrap.href = "#"+sortedTagmap[i];
innerawrap.setAttribute('data-tag', sortedTagmap[i]);
innerawrap.setAttribute('data-index', nodeonpagecount[nodelisting.url]);
innerawrap.setAttribute('data-url', nodelisting.url);
listelementnode.appendChild(tagtypenode);
innerawrap.appendChild(listelementnode);
listnode.appendChild(innerawrap);
innerawrap.addEventListener("mouseup", function() {
console.log("Loading tag in inner wrap");
loadtag(this.href.split("#")[1], this.getAttribute("data-url"), this.getAttribute("data-index"), false);
this.classList.add("main");
});
nodeonpagecount[nodelisting.url] = nodeonpagecount[nodelisting.url] + 1;
}
mainnode.appendChild(listnode);
awrap.appendChild(mainnode);
awrap.href = "#"+sortedTagmap[i];
awrap.addEventListener("mouseup", function() {
if (this.childNodes[0].classList.contains("main")) {
return;
}
console.log("Loading tag in main wrap");
loadtag(this.href.split("#")[1], currentUrl);
});
keylist.appendChild(awrap);
}
});
function loadtag(tagname, url, index, scrolllist) {
if (!tagmap[tagname]) return;
index = index || 0;
url = url || "";
if (url != currentUrl) return initialise(url, {tagname:tagname, url:url, index:index, scrolllist:scrolllist});
urlBar.innerHTML = "Viewing <span>"+ tagname +"</span> on <span>/"+url+"</span>";
document.querySelectorAll('.main').forEach(function(element){
element.classList.remove("main");
});
document.getElementById("to-"+tagname).classList.add("main");
var tag = document.querySelectorAll('#rpanel [data-i18n="'+tagname+'"][data-index="'+index+'"]')[0];
if (tag) tag.scrollIntoView({behavior: "smooth", block: "center"});
if (scrolllist) {
document.getElementById("to-"+tagname).scrollIntoView({behavior: "smooth", block: "center"});
}
var granulartag = document.querySelectorAll('#lpanel [data-tag="'+tagname+'"][data-url="'+currentUrl+'"][data-index="'+index+'"]')[0];
console.log(granulartag);
if (granulartag) {
granulartag.classList.add("main");
} else {
var nextpageurl = document.querySelectorAll('#lpanel [data-tag="'+tagname+'"][data-index="'+index+'"]')[0].getAttribute("data-url");
return loadtag(tagname, nextpageurl, index, scrolllist);
}
if (tag) tag.classList.add("main");
if (tag) fgimg.style.clipPath = "inset("+tag.getAttribute("data-top")+"% "+(100-tag.getAttribute("data-right"))+"% "+(100-tag.getAttribute("data-bottom"))+"% "+tag.getAttribute("data-left")+"%)"
if (tag.classList.contains("invisible")) fgimg.style.clipPath = "inset(0% 0% 0% 0%)";
}
function initialise(url, opts, internal) {
if (!internal) {
rpanel.classList.add("fade");
setTimeout(function() {
initialise(url, opts, true);
}, 400);
return;
}
var newimg = img.cloneNode(true);
newimg.src = url+"index.png";
newimg.addEventListener('load', initloaded);
img.parentNode.replaceChild(newimg, img);
img = newimg;
fgimg.src = url+"index.png";
function initloaded() {
rpanel.classList.remove("fade");
fetchJSONFile(url+"index.json", function(data){
box.innerHTML = "";
invisibles.innerHTML = "<h2>Invisible Tags</h2>";
var width = img.offsetWidth;
var ratio = width / 1920;
var height = img.offsetHeight;
var origHeight = height / ratio;
var nodeonpagecount = {};
for (var i = 0; i < data.length; i++) {
nodeonpagecount[data[i].i18n] = nodeonpagecount[data[i].i18n] || 0;
var node = CR("DIV");
var spannode = CR("SPAN", data[i].i18n);
node.appendChild(spannode);
var leftpc = ((data[i].left/1920)*100).toFixed(4);
var rightpc = ((data[i].right/1920)*100).toFixed(4);
var toppc = ((data[i].top/origHeight)*100).toFixed(4);
var botpc = ((data[i].bottom/origHeight)*100).toFixed(4);
node.style.left = leftpc+"%";
node.style.top = toppc+"%";
var iwidth = data[i].right - data[i].left;
var iheight = data[i].bottom - data[i].top;
node.setAttribute('data-i18n', data[i].i18n);
node.setAttribute('data-index', nodeonpagecount[data[i].i18n]);
node.setAttribute('data-left', leftpc);
node.setAttribute('data-right', rightpc);
node.setAttribute('data-top', toppc);
node.setAttribute('data-bottom', botpc);
node.addEventListener("mouseup", function() {
window.location.hash = this.getAttribute("data-i18n");
loadtag(this.getAttribute("data-i18n"), currentUrl, this.getAttribute("data-index"), true);
});
var nowidth = (((iwidth/1920)*100).toFixed(4) == 0 || ((iheight/origHeight)*100).toFixed(4) == 0);
var toohigh = botpc < 0;
var tooleft = rightpc < 0;
var tooright = leftpc > 100;
var toolow = toppc > 100;
if (nowidth || toohigh || toolow || tooleft | tooright) {
var tagnode = CR("SPAN", data[i].type, ["tag"]);
node.appendChild(tagnode);
var contentnode = CR("SPAN", '"'+data[i].content+'"', ["content"]);
node.appendChild(contentnode);
node.classList.add("invisible");
invisibles.appendChild(node);
} else {
node.style.width = ((iwidth/1920)*100).toFixed(4)+"%";
node.style.height = ((iheight/origHeight)*100).toFixed(4)+"%";
box.appendChild(node);
}
nodeonpagecount[data[i].i18n] = nodeonpagecount[data[i].i18n] + 1;
}
currentUrl = url;
if (opts) {
console.log("Loading tag in JSON");
loadtag(opts.tagname, opts.url, opts.index, opts.scrolllist);
}
if (keytag) {
loadtag(keytag, currentUrl);
setTimeout(function() {
document.getElementById("to-"+keytag).scrollIntoView({behavior: "smooth", block: "center"});
keytag = "";
}, 1000);
}
});
}
}
initialise("");
function CR(tag, text, classnames, id) {
var node = document.createElement(tag);
if (text) {
var textnode = document.createTextNode(text);
node.appendChild(textnode);
}
if (classnames) {
for (var i = 0; i < classnames.length; i++) {
node.classList.add(classnames[i]);
}
}
if (id) {
node.id = id;
}
return node;
}
function fetchJSONFile(path, callback) {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200 || httpRequest.status === 0) {
var data = JSON.parse(httpRequest.responseText);
if (callback) callback(data);
}
}
};
httpRequest.open('GET', path);
httpRequest.send();
}
</script>
</body>