Make a prod copy of fedmenu.

This commit is contained in:
Ralph Bean 2015-04-23 19:27:54 +00:00
parent 923b88e699
commit 0ff70c1fd3
7 changed files with 520 additions and 0 deletions

View file

@ -0,0 +1,212 @@
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local('Montserrat-Regular'), url(../fonts/montserrat.ttf) format('truetype');
}
.fedmenu-bottom-left {
position: fixed;
bottom: 10px;
left: 10px;
}
.fedmenu-bottom-right {
position: fixed;
bottom: 10px;
right: 10px;
}
.fedmenu-bottom-left:hover .fedmenu-bottom-left.fedmenu-active {
bottom: 2px;
left: 2px;
}
.fedmenu-bottom-right:hover .fedmenu-bottom-right.fedmenu-active {
bottom: 2px;
right 2px;
}
#fedmenu-tray {
width: 48px;
z-index: 101;
}
.fedmenu-button {
margin-left: auto;
margin-right: auto;
margin-top: 0px;
margin-bottom: 0px;
padding-bottom: 8px;
width: 32px;
height: 32px;
-webkit-filter: drop-shadow(4px 4px 4px #222);
filter: drop-shadow(4px 4px 4px #222);
/* Awesome */
transition-property: width, height, bottom, left, background-size, filter, margin-top, margin-bottom, padding-bottom;
transition-duration: 0.10s;
transition-timing-function: linear;
}
.fedmenu-button:hover, .fedmenu-button.fedmenu-active {
margin-top: -8px;
margin-bottom: -8px;
padding-bottom: -8px;
width: 48px;
height: 48px;
-webkit-filter: drop-shadow(4px 4px 6px #222);
filter: drop-shadow(4px 4px 6px #222);
}
.fedmenu-button div.img {
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
}
#fedmenu-main-button div.img { background-image: url("../img/logo.png"); }
#fedmenu-user-button div.img { border-radius: 50%; /* Make avatars into a circle */ }
#fedmenu-wrapper {
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
z-index: 98;
display: none;
}
#fedmenu-wrapper.fedmenu-active,.fedmenu-exit {
cursor: pointer;
}
.fedmenu-exit {
float: right;
width: 26px;
height: 26px;
text-align: center;
line-height: 28px;
font-family: sans-serif;
font-size: 16pt;
color: #FFF;
background-color: #db3279;
border-radius: 50%;
-webkit-filter: drop-shadow(4px 4px 4px #222);
filter: drop-shadow(4px 4px 4px #222);
/* Awesome */
transition-property: width, height, margin, line-height, font-size;
transition-duration: 0.10s;
transition-timing-function: linear;
}
.fedmenu-exit:hover {
margin-top: -6px;
margin-right: -6px;
width: 38px;
height: 38px;
line-height: 40px;
font-size: 22pt;
-webkit-filter: drop-shadow(4px 4px 6px #222);
filter: drop-shadow(4px 4px 6px #222);
}
#fedmenu-wrapper.fedmenu-active {
display: block;
background-color: rgba(0,0,0,0.3);
-webkit-box-shadow: inset 0 0 400px rgba(0,0,0,1);
box-shadow: inset 0 0 400px rgba(0,0,0,1);
}
.fedmenu-content {
position: fixed;
top: 100%;
/* Vary these two parameters for responsive-ness */
left: 30%;
width: 40%;
background: url('../img/panda-wave.png') no-repeat right bottom;
background-color: #FFF;
margin-bottom: 20px;
padding: 19px;
border: 0px none;
-webkit-box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.23);
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.23);
z-index: 100;
}
.fedmenu-content.fedmenu-active {
top: 15%;
transition-property: top;
transition-duration: 0.4s;
transition-delay: 0.3s;
transition-timing-function: ease-out;
}
.fedmenu-content > h1 {
font-family: Montserrat;
font-weight: bold;
border-bottom: 2px solid;
color: #294172;
}
.fedmenu-panel {
font-family: Montserrat;
display: inline-block;
vertical-align: top;
font-size: 8pt;
padding: 15px;
}
.fedmenu-panel ul {
margin-top: 10px;
padding-left: 0px;
}
.fedmenu-panel li {
list-style: none;
margin-left: 0px;
}
.fedmenu-panel a,
.fedmenu-panel a:hover {
color: #3C6EB4;
}
.fedmenu-header {
display: inline;
font-weight: bold;
font-size: 12pt;
color: #294172;
border-bottom: 1px solid;
}
/* Responsive stuff... */
@media all and (max-width: 1450px) { .fedmenu-content { left: 25%; width: 50%; }}
@media all and (max-width: 1200px) { .fedmenu-content { left: 20%; width: 60%; }}
@media all and (max-width: 1000px) { .fedmenu-content { left: 15%; width: 70%; }}
@media all and (max-width: 860px) { .fedmenu-content { left: 10%; width: 80%; }}
@media all and (max-width: 740px) { .fedmenu-content { left: 5%; width: 85%; }}
@media all and (max-width: 600px) { .fedmenu-content { left: 0%; width:100%; }}
@media all and (max-width: 800px) { .fedmenu-content.fedmenu-active { top: 10%; }}
@media all and (max-width: 700px) { .fedmenu-content.fedmenu-active { top: 10%; }}
@media all and (max-width: 600px) { .fedmenu-content.fedmenu-active { top: 5%; }}
@media all and (max-width: 500px) {
.fedmenu-content.fedmenu-active { top: 0%; }
.fedmenu-content > h1 { font-size: 80%; padding: 5px }
.fedmenu-panel .fedmenu-header { font-size: 90%; }
.fedmenu-panel { padding: 7px; font-size: 5pt; }
.fedmenu-content {
padding: 9px;
background-image: none;
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -0,0 +1,156 @@
var fedmenu = function(options) { $(document).ready(function() {
var defaults = {
'url': 'https://apps.fedoraproject.org/js/data.js',
'mimeType': undefined, // Only needed for local development
'position': 'bottom-left',
'user': null,
'package': null,
}
// Our options object is called 'o' for shorthand
var o = $.extend({}, defaults, options || {});
var buttons = "";
if (o['user'] != null) buttons += '<div id="fedmenu-user-button" class="fedmenu-button"><div class="img"></div></div>';
if (o['package'] != null) buttons += '<div id="fedmenu-package-button" class="fedmenu-button"><div class="img"></div></div>';
buttons += '<div id="fedmenu-main-button" class="fedmenu-button"><div class="img"></div></div>';
var script = $("script[src$='fedmenu.js']").attr('src');
var base = script.slice(0, -13);
$('body').append('<link href="' + base + 'css/fedmenu.css" rel="stylesheet">');
$('body').append(
'<div id="fedmenu-tray" class="fedmenu-' + o.position + '">' +
buttons + '</div>');
$('body').append('<div id="fedmenu-wrapper"></div>');
$('body').append('<div id="fedmenu-main-content" class="fedmenu-content"></div>');
$('#fedmenu-main-content').append("<span class='fedmenu-exit'>&#x274C;</span>");
$('#fedmenu-main-content').append("<h1>Fedora Infrastructure Apps</h1>");
if (o['user'] != null) {
var imgurl = libravatar.url(o['user']);
$('#fedmenu-user-button .img').css('background-image', 'url("' + imgurl + '")');
$('body').append('<div id="fedmenu-user-content" class="fedmenu-content"></div>');
$('#fedmenu-user-content').append("<span class='fedmenu-exit'>&#x274C;</span>");
$('#fedmenu-user-content').append("<h1>View " + o['user'] + " in other apps</h1>");
}
if (o['package'] != null) {
/* This icon is not always going to exist, so we should put in an
* apache rule that redirects to a default icon if this file
* isn't there. */
var imgurl = 'https://apps.fedoraproject.org/packages/images/icons/' + o['package'] + '.png';
$('#fedmenu-package-button .img').css('background-image', 'url("' + imgurl + '")');
$('body').append('<div id="fedmenu-package-content" class="fedmenu-content"></div>');
$('#fedmenu-package-content').append("<span class='fedmenu-exit'>&#x274C;</span>");
$('#fedmenu-package-content').append("<h1>View the " + o['package'] + " package elsewhere</h1>");
}
// Define three functions used to generate the content of the menu panes
var make_main_content_html = function(i, node) {
var html = "<div class='fedmenu-panel'><div class='fedmenu-header'>" +
node.name + "</div><ul>";
$.each(node.children, function(j, leaf) {
html = html +
"<li><a target='_blank' href='" + leaf.data.url + "'>" +
$("<p>" + leaf.name + "</p>").text() +
"</a></li>";
});
html = html + "</ul></div>";
$("#fedmenu-main-content").append(html);
};
var make_user_content_html = function(i, node) {
var html = "<div class='fedmenu-panel'><div class='fedmenu-header'>" +
node.name + "</div><ul>";
var found = false;
$.each(node.children, function(j, leaf) {
if (leaf.data.user_url != undefined) {
found = true;
var url = leaf.data.user_url.replace('{user}', o['user'])
html = html +
"<li><a target='_blank' href='" + url + "'>" +
$("<p>" + leaf.name + "</p>").text() +
"</a></li>";
}
});
if (found) {
html = html + "</ul></div>";
$("#fedmenu-user-content").append(html);
}
};
var make_package_content_html = function(i, node) {
var html = "<div class='fedmenu-panel'><div class='fedmenu-header'>" +
node.name + "</div><ul>";
var found = false;
$.each(node.children, function(j, leaf) {
if (leaf.data.package_url != undefined) {
found = true;
var url = leaf.data.package_url.replace('{package}', o['package'])
html = html +
"<li><a target='_blank' href='" + url + "'>" +
$("<p>" + leaf.name + "</p>").text() +
"</a></li>";
}
});
if (found) {
html = html + "</ul></div>";
$("#fedmenu-package-content").append(html);
}
};
$.ajax({
url: o.url,
mimeType: o.mimeType,
dataType: 'script',
error: function(err) {
console.log('Error getting ' + o.url);
console.log(err);
},
success: function(script) {
$.each(json.children, make_main_content_html);
if (o['user'] != null)
$.each(json.children, make_user_content_html);
if (o['package'] != null)
$.each(json.children, make_package_content_html);
},
});
var selector = function(t) {
return "#fedmenu-wrapper," +
"#fedmenu-" + t + "-button," +
"#fedmenu-" + t + "-content";
};
var activate = function(t) { $(selector(t)).addClass('fedmenu-active'); };
var deactivate = function(t) { $(selector(t)).removeClass('fedmenu-active'); };
var click_factory = function(t) { return function() {
if ($(this).hasClass('fedmenu-active'))
deactivate(t);
else
// Deactivate any others that may be active before starting anew.
deactivate('main'); deactivate('user'); deactivate('package');
activate(t);
};};
$("#fedmenu-main-button").click(click_factory('main'));
$("#fedmenu-user-button").click(click_factory('user'));
$("#fedmenu-package-button").click(click_factory('package'));
$("#fedmenu-wrapper,.fedmenu-exit").click(function() {
deactivate('main');
deactivate('user');
deactivate('package');
});
$(document).keydown(function(event) {
if (event.key == 'Esc'){
deactivate('main');
deactivate('user');
deactivate('package');
}
});
}); };

View file

@ -0,0 +1,148 @@
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* Libravatar retrieval for Fedora FAS usernames */
/* (c) Ralph Bean 2015 / MIT License */
/* Original SHA-256 implementation in JavaScript */
/* (c) Chris Veness 2002-2014 / MIT Licence */
/* */
/* - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html */
/* http://csrc.nist.gov/groups/ST/toolkit/examples.html */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
'use strict';
var sha256 = {};
var libravatar = {};
/**
* Generates SHA-256 hash of string.
*
* @param {string} msg - String to be hashed
* @returns {string} Hash of msg as hex character string
*/
sha256.hash = function(msg) {
// convert string to UTF-8, as SHA only deals with byte-streams
msg = msg.utf8Encode();
// constants [§4.2.2]
var K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ];
// initial hash value [§5.3.1]
var H = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
// PREPROCESSING
msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [§5.1.1]
// convert string msg into 512-bit/16-integer blocks arrays of ints [§5.2.1]
var l = msg.length/4 + 2; // length (in 32-bit integers) of msg + 1 + appended length
var N = Math.ceil(l/16); // number of 16-integer-blocks required to hold 'l' ints
var M = new Array(N);
for (var i=0; i<N; i++) {
M[i] = new Array(16);
for (var j=0; j<16; j++) { // encode 4 chars per integer, big-endian encoding
M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
(msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
} // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
}
// add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]
// note: most significant word would be (len-1)*8 >>> 32, but since JS converts
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14]);
M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
// HASH COMPUTATION [§6.1.2]
var W = new Array(64); var a, b, c, d, e, f, g, h;
for (var i=0; i<N; i++) {
// 1 - prepare message schedule 'W'
for (var t=0; t<16; t++) W[t] = M[i][t];
for (var t=16; t<64; t++) W[t] = (sha256.SmallSigma1(W[t-2]) + W[t-7] + sha256.SmallSigma0(W[t-15]) + W[t-16]) & 0xffffffff;
// 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value
a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7];
// 3 - main loop (note 'addition modulo 2^32')
for (var t=0; t<64; t++) {
var T1 = h + sha256.BigSigma1(e) + sha256.Ch(e, f, g) + K[t] + W[t];
var T2 = sha256.BigSigma0(a) + sha256.Maj(a, b, c);
h = g;
g = f;
f = e;
e = (d + T1) & 0xffffffff;
d = c;
c = b;
b = a;
a = (T1 + T2) & 0xffffffff;
}
// 4 - compute the new intermediate hash value (note 'addition modulo 2^32')
H[0] = (H[0]+a) & 0xffffffff;
H[1] = (H[1]+b) & 0xffffffff;
H[2] = (H[2]+c) & 0xffffffff;
H[3] = (H[3]+d) & 0xffffffff;
H[4] = (H[4]+e) & 0xffffffff;
H[5] = (H[5]+f) & 0xffffffff;
H[6] = (H[6]+g) & 0xffffffff;
H[7] = (H[7]+h) & 0xffffffff;
}
return sha256.toHexStr(H[0]) + sha256.toHexStr(H[1]) + sha256.toHexStr(H[2]) + sha256.toHexStr(H[3]) +
sha256.toHexStr(H[4]) + sha256.toHexStr(H[5]) + sha256.toHexStr(H[6]) + sha256.toHexStr(H[7]);
};
sha256.ROTR = function(n, x) {
return (x >>> n) | (x << (32-n));
};
sha256.BigSigma0 = function(x) { return sha256.ROTR(2, x) ^ sha256.ROTR(13, x) ^ sha256.ROTR(22, x); };
sha256.BigSigma1 = function(x) { return sha256.ROTR(6, x) ^ sha256.ROTR(11, x) ^ sha256.ROTR(25, x); };
sha256.SmallSigma0 = function(x) { return sha256.ROTR(7, x) ^ sha256.ROTR(18, x) ^ (x>>>3); };
sha256.SmallSigma1 = function(x) { return sha256.ROTR(17, x) ^ sha256.ROTR(19, x) ^ (x>>>10); };
sha256.Ch = function(x, y, z) { return (x & y) ^ (~x & z); };
sha256.Maj = function(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); };
sha256.toHexStr = function(n) {
// note can't use toString(16) as it is implementation-dependant,
// and in IE returns signed numbers when used on full words
var s="", v;
for (var i=7; i>=0; i--) { v = (n>>>(i*4)) & 0xf; s += v.toString(16); }
return s;
};
if (typeof String.prototype.utf8Encode == 'undefined') {
String.prototype.utf8Encode = function() {
return unescape( encodeURIComponent( this ) );
};
}
if (typeof String.prototype.utf8Decode == 'undefined') {
String.prototype.utf8Decode = function() {
try {
return decodeURIComponent( escape( this ) );
} catch (e) {
return this; // invalid UTF-8? return as-is
}
};
}
/* This is all that we need the sha256 code for... */
libravatar.url = function(username, s, d) {
if (s === undefined) s = 64;
if (d === undefined) d = 'retro';
var openid = 'http://' + username + '.id.fedoraproject.org/'
var hash = sha256.hash(openid);
return 'https://seccdn.libravatar.org/avatar/' + hash + '?s=' + s + '&d=' + d;
}

File diff suppressed because one or more lines are too long