Beautify javascript (fixes #980)

This commit is contained in:
Saivann 2015-07-29 16:55:50 -04:00
parent 75a3c45628
commit d814977536
5 changed files with 654 additions and 647 deletions

View file

@ -7,201 +7,201 @@
"use strict" "use strict"
function addEvent(a, b, c) { function addEvent(a, b, c) {
// Attach event to a DOM node. // Attach event to a DOM node.
// Ex. addEvent(node,'click',function); // Ex. addEvent(node,'click',function);
return (a.addEventListener) ? a.addEventListener(b, c, false) : (a.attachEvent) ? a.attachEvent('on' + b, c) : false; return (a.addEventListener) ? a.addEventListener(b, c, false) : (a.attachEvent) ? a.attachEvent('on' + b, c) : false;
} }
function removeEvent(a, b, c) { function removeEvent(a, b, c) {
// Detach event from a DOM node. // Detach event from a DOM node.
// Ex. removeEvent(node,'click',function); // Ex. removeEvent(node,'click',function);
return (a.removeEventListener) ? a.removeEventListener(b, c, false) : (a.detachEvent) ? a.detachEvent('on' + b, c) : false; return (a.removeEventListener) ? a.removeEventListener(b, c, false) : (a.detachEvent) ? a.detachEvent('on' + b, c) : false;
} }
function cancelEvent(e) { function cancelEvent(e) {
// Cancel current event. // Cancel current event.
// Ex. cancelEvent(event); // Ex. cancelEvent(event);
if (!e) var e = window.event; if (!e) var e = window.event;
(e.preventDefault) ? e.preventDefault() : e.returnValue = false; (e.preventDefault) ? e.preventDefault(): e.returnValue = false;
} }
function getEvent(e, a) { function getEvent(e, a) {
// Return requested event property. // Return requested event property.
// Ex. var target = getEvent(event, 'target'); // Ex. var target = getEvent(event, 'target');
e = (e) ? e : window.event; e = (e) ? e : window.event;
switch (a) { switch (a) {
case 'type': case 'type':
return e.type; return e.type;
case 'target': case 'target':
return (e.target && e.target.nodeType == 3) ? e.target.parentNode : (e.target) ? e.target : e.srcElement; return (e.target && e.target.nodeType == 3) ? e.target.parentNode : (e.target) ? e.target : e.srcElement;
} }
} }
function getStyle(a, b) { function getStyle(a, b) {
// Return the value of the computed style on a DOM node. // Return the value of the computed style on a DOM node.
// Ex. getStyle(node,'padding-bottom'); // Ex. getStyle(node,'padding-bottom');
if (window.getComputedStyle) return document.defaultView.getComputedStyle(a, null).getPropertyValue(b); if (window.getComputedStyle) return document.defaultView.getComputedStyle(a, null).getPropertyValue(b);
var n = b.indexOf('-'); var n = b.indexOf('-');
if (n !== -1) b = b.substr(0, n) + b.substr(n + 1, 1).toUpperCase() + b.substr(n + 2); if (n !== -1) b = b.substr(0, n) + b.substr(n + 1, 1).toUpperCase() + b.substr(n + 2);
return a.currentStyle[b]; return a.currentStyle[b];
} }
function addClass(node, data) { function addClass(node, data) {
// Add class to node. // Add class to node.
var cl = node.className.split(' '); var cl = node.className.split(' ');
for (var i = 0, n = cl.length; i < n; i++) { for (var i = 0, n = cl.length; i < n; i++) {
if (cl[i] == data) return; if (cl[i] == data) return;
} }
cl.push(data); cl.push(data);
node.className = cl.join(' '); node.className = cl.join(' ');
} }
function removeClass(node, data) { function removeClass(node, data) {
// Remove class from node. // Remove class from node.
var ocl = node.className.split(' '); var ocl = node.className.split(' ');
var ncl = []; var ncl = [];
for (var i = 0, n = ocl.length; i < n; i++) { for (var i = 0, n = ocl.length; i < n; i++) {
if (ocl[i] != data) ncl.push(ocl[i]); if (ocl[i] != data) ncl.push(ocl[i]);
} }
node.className = ncl.join(' '); node.className = ncl.join(' ');
} }
function supportsSVG() { function supportsSVG() {
// Return true if the browser supports SVG. // Return true if the browser supports SVG.
// Ex. if(!supportsSVG()){..apply png fallback..} // Ex. if(!supportsSVG()){..apply png fallback..}
// Old FF 3.5 and Safari 3 versions have svg support, but a very poor one // Old FF 3.5 and Safari 3 versions have svg support, but a very poor one
// http://www.w3.org/TR/SVG11/feature#Image Defeat FF 3.5 only // http://www.w3.org/TR/SVG11/feature#Image Defeat FF 3.5 only
// http://www.w3.org/TR/SVG11/feature#Animation Defeat Saf 3 but also returns false in IE9 // http://www.w3.org/TR/SVG11/feature#Animation Defeat Saf 3 but also returns false in IE9
// http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute Defeat Saf 3 but also returns false in Chrome and safari4 // http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute Defeat Saf 3 but also returns false in Chrome and safari4
// http://www.w3.org/TR/SVG11/feature#Text Defeat Saf 3 but also returns false in FF and safari4 // http://www.w3.org/TR/SVG11/feature#Text Defeat Saf 3 but also returns false in FF and safari4
if (!document.createElementNS || !document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect) return false; if (!document.createElementNS || !document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect) return false;
if (!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1")) return false; if (!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1")) return false;
if (!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute", "1.1") && !document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Animation", "1.1") && !document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Text", "1.1")) return false; if (!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute", "1.1") && !document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Animation", "1.1") && !document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Text", "1.1")) return false;
return true; return true;
} }
function fallbackSVG() { function fallbackSVG() {
// Replace all images extensions from .svg to .png if browser doesn't support SVG files. // Replace all images extensions from .svg to .png if browser doesn't support SVG files.
if (supportsSVG()) return; if (supportsSVG()) return;
for (var i = 0, nd = document.getElementsByTagName('*'), n = nd.length; i < n; i++) { for (var i = 0, nd = document.getElementsByTagName('*'), n = nd.length; i < n; i++) {
if (nd[i].nodeName == 'IMG' && /.*\.svg$/.test(nd[i].src)) nd[i].src = nd[i].src.slice(0, -3) + 'png'; if (nd[i].nodeName == 'IMG' && /.*\.svg$/.test(nd[i].src)) nd[i].src = nd[i].src.slice(0, -3) + 'png';
if (/\.svg/.test(getStyle(nd[i], 'background-image'))) nd[i].style.backgroundImage = getStyle(nd[i], 'background-image').replace('.svg', '.png'); if (/\.svg/.test(getStyle(nd[i], 'background-image'))) nd[i].style.backgroundImage = getStyle(nd[i], 'background-image').replace('.svg', '.png');
if (/\.svg/.test(getStyle(nd[i], 'background'))) nd[i].style.background = getStyle(nd[i], 'background').replace('.svg', '.png'); if (/\.svg/.test(getStyle(nd[i], 'background'))) nd[i].style.background = getStyle(nd[i], 'background').replace('.svg', '.png');
} }
} }
function onTouchClick(e, callback, callbackClick) { function onTouchClick(e, callback, callbackClick) {
// Detect and handle clicks using click and touch events while preventing accidental or ghost clicks. // Detect and handle clicks using click and touch events while preventing accidental or ghost clicks.
var timeout = 1000, var timeout = 1000,
srcEvent = e, srcEvent = e,
touchEndListener = function(e) { touchEndListener = function(e) {
// Call callback if touch events match the patterns of a click. // Call callback if touch events match the patterns of a click.
removeEvent(t, 'touchend', touchEndListener); removeEvent(t, 'touchend', touchEndListener);
setClickTimeout(); setClickTimeout();
if (Math.abs(e.changedTouches[0].pageX - x) > 20 || Math.abs(e.changedTouches[0].pageY - y) > 20) return; if (Math.abs(e.changedTouches[0].pageX - x) > 20 || Math.abs(e.changedTouches[0].pageY - y) > 20) return;
callback(srcEvent); callback(srcEvent);
}, },
wrongClickListener = function(e) { wrongClickListener = function(e) {
// Cancel click events on different targets within timeframe. // Cancel click events on different targets within timeframe.
// This avoids accidental clicks when the page is scrolled or updated due to the 300ms click event delay on mobiles. // This avoids accidental clicks when the page is scrolled or updated due to the 300ms click event delay on mobiles.
removeEvent(document.body, 'click', wrongClickListener); removeEvent(document.body, 'click', wrongClickListener);
if (!clickReady() && getEvent(e, 'target') != t) cancelEvent(e); if (!clickReady() && getEvent(e, 'target') != t) cancelEvent(e);
}, },
setClickTimeout = function() { setClickTimeout = function() {
// Update timeout during which click events will be blocked. // Update timeout during which click events will be blocked.
document.body.setAttribute('data-touchtimeout', new Date().getTime() + timeout); document.body.setAttribute('data-touchtimeout', new Date().getTime() + timeout);
}, },
clickReady = function() { clickReady = function() {
// Check if timeout during click events are blocked has expired. // Check if timeout during click events are blocked has expired.
var ti = document.body.getAttribute('data-touchtimeout'); var ti = document.body.getAttribute('data-touchtimeout');
return (ti === null || ti === '' || parseInt(ti, 10) < new Date().getTime()); return (ti === null || ti === '' || parseInt(ti, 10) < new Date().getTime());
}; };
if (callbackClick === undefined) callbackClick = function() {}; if (callbackClick === undefined) callbackClick = function() {};
// Apply appropriate actions according to each event type. // Apply appropriate actions according to each event type.
switch (getEvent(e, 'type')) { switch (getEvent(e, 'type')) {
case 'touchstart': case 'touchstart':
// Save initial touchstart coordinates and listen for touchend events and accidental click events. // Save initial touchstart coordinates and listen for touchend events and accidental click events.
var x = e.changedTouches[0].pageX, var x = e.changedTouches[0].pageX,
y = e.changedTouches[0].pageY, y = e.changedTouches[0].pageY,
t = e.changedTouches[0].target; t = e.changedTouches[0].target;
setClickTimeout(); setClickTimeout();
addEvent(t, 'touchend', touchEndListener); addEvent(t, 'touchend', touchEndListener);
addEvent(document.body, 'click', wrongClickListener); addEvent(document.body, 'click', wrongClickListener);
setTimeout(function() { setTimeout(function() {
removeEvent(document.body, 'click', wrongClickListener); removeEvent(document.body, 'click', wrongClickListener);
}, timeout); }, timeout);
break; break;
case 'click': case 'click':
// Call callback on click in the absence of a recent touchstart event to prevent ghost clicks. // Call callback on click in the absence of a recent touchstart event to prevent ghost clicks.
// Always call callbackClick to let it cancel click events on links. // Always call callbackClick to let it cancel click events on links.
callbackClick(srcEvent); callbackClick(srcEvent);
if (!clickReady()) return; if (!clickReady()) return;
callback(srcEvent); callback(srcEvent);
break; break;
} }
} }
function mobileMenuShow(e) { function mobileMenuShow(e) {
// Show the mobile menu when the visitors touch the menu icon. // Show the mobile menu when the visitors touch the menu icon.
var show = function() { var show = function() {
var mm = document.getElementById('menusimple'); var mm = document.getElementById('menusimple');
var ml = document.getElementById('langselect'); var ml = document.getElementById('langselect');
mm.style.display = ml.style.display = (mm.style.display == 'block') ? '' : 'block'; mm.style.display = ml.style.display = (mm.style.display == 'block') ? '' : 'block';
addClass(mm, 'menutap'); addClass(mm, 'menutap');
cancelEvent(e); cancelEvent(e);
}; };
onTouchClick(e, show); onTouchClick(e, show);
} }
function mobileMenuHover(e) { function mobileMenuHover(e) {
// Prevent mobile menu to shrink on hover to prevent accidental clicks on other entries. // Prevent mobile menu to shrink on hover to prevent accidental clicks on other entries.
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
fn = (t.parentNode.className.indexOf('hover') === -1) ? addClass : removeClass, fn = (t.parentNode.className.indexOf('hover') === -1) ? addClass : removeClass,
initHover = function() { initHover = function() {
if (t.nodeName != 'A') return; if (t.nodeName != 'A') return;
if (fn == removeClass && !hasSubItems(t)) return; if (fn == removeClass && !hasSubItems(t)) return;
var p = t; var p = t;
while (p.parentNode.nodeName == 'UL' || p.parentNode.nodeName == 'LI') p = p.parentNode; while (p.parentNode.nodeName == 'UL' || p.parentNode.nodeName == 'LI') p = p.parentNode;
for (var i = 0, nds = p.getElementsByTagName('LI'), n = nds.length; i < n; i++) { for (var i = 0, nds = p.getElementsByTagName('LI'), n = nds.length; i < n; i++) {
if (nds[i] == t.parentNode) continue; if (nds[i] == t.parentNode) continue;
removeClass(nds[i], 'active'); removeClass(nds[i], 'active');
if (hasSubItems(nds[i])) continue; if (hasSubItems(nds[i])) continue;
removeClass(nds[i], 'hover'); removeClass(nds[i], 'hover');
} }
while (t != p) { while (t != p) {
if (t.nodeName == 'LI') { if (t.nodeName == 'LI') {
fn(t, 'hover'); fn(t, 'hover');
fn(t, 'active'); fn(t, 'active');
} }
t = t.parentNode; t = t.parentNode;
} }
}, },
hasSubItems = function(t) { hasSubItems = function(t) {
while (t.nodeName != 'LI') t = t.parentNode; while (t.nodeName != 'LI') t = t.parentNode;
return (t.getElementsByTagName('UL').length > 0); return (t.getElementsByTagName('UL').length > 0);
}, },
// Prevent clicks on parent element links in the menu. // Prevent clicks on parent element links in the menu.
filterClick = function(e) { filterClick = function(e) {
var t = getEvent(e, 'target'); var t = getEvent(e, 'target');
if (t.nodeName != 'A') return; if (t.nodeName != 'A') return;
if (hasSubItems(t)) cancelEvent(e); if (hasSubItems(t)) cancelEvent(e);
}; };
onTouchClick(e, initHover, filterClick); onTouchClick(e, initHover, filterClick);
} }
function addAnchorLinks() { function addAnchorLinks() {
// Apply anchor links icon on each title displayed on CSS hover. // Apply anchor links icon on each title displayed on CSS hover.
var nodes = []; var nodes = [];
var tags = ['H2', 'H3', 'H4', 'H5', 'H6']; var tags = ['H2', 'H3', 'H4', 'H5', 'H6'];
for (var i = 0, n = tags.length; i < n; i++) { for (var i = 0, n = tags.length; i < n; i++) {
for (var ii = 0, t = document.getElementsByTagName(tags[i]), nn = t.length; ii < nn; ii++) nodes.push(t[ii]); for (var ii = 0, t = document.getElementsByTagName(tags[i]), nn = t.length; ii < nn; ii++) nodes.push(t[ii]);
} }
for (var i = 0, n = nodes.length; i < n; i++) { for (var i = 0, n = nodes.length; i < n; i++) {
if (!nodes[i].id) continue; if (!nodes[i].id) continue;
if (nodes[i].getElementsByTagName('A').length > 0 && nodes[i].getElementsByTagName('A')[0].innerHTML == '') return; if (nodes[i].getElementsByTagName('A').length > 0 && nodes[i].getElementsByTagName('A')[0].innerHTML == '') return;
addClass(nodes[i], 'anchorAf'); addClass(nodes[i], 'anchorAf');
var anc = document.createElement('A'); var anc = document.createElement('A');
anc.href = '#' + nodes[i].id; anc.href = '#' + nodes[i].id;
nodes[i].insertBefore(anc, nodes[i].firstChild); nodes[i].insertBefore(anc, nodes[i].firstChild);
} }
} }

View file

@ -38,36 +38,36 @@ category: "{{category_name}}"
// code adapted from http://jqueryui.com/autocomplete/#categories // code adapted from http://jqueryui.com/autocomplete/#categories
// MIT license: https://jquery.org/license/ // MIT license: https://jquery.org/license/
$.widget( "custom.catcomplete", $.ui.autocomplete, { $.widget("custom.catcomplete", $.ui.autocomplete, {
_create: function() { _create: function() {
this._super(); this._super();
this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" ); this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
}, },
_renderMenu: function( ul, items ) { _renderMenu: function(ul, items) {
var that = this, var that = this,
currentCategory = ""; currentCategory = "";
$.each( items, function( index, item ) { $.each(items, function(index, item) {
var li; var li;
if ( item.category != currentCategory ) { if (item.category != currentCategory) {
ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" ); ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
currentCategory = item.category; currentCategory = item.category;
} }
li = that._renderItemData( ul, item ); li = that._renderItemData(ul, item);
if ( item.category ) { if (item.category) {
li.attr( "aria-label", item.category + " : " + item.label ); li.attr("aria-label", item.category + " : " + item.label);
} }
}); });
} }
}); });
$(function() { $(function() {
$( "#glossary_term" ).catcomplete({ $("#glossary_term").catcomplete({
source: search_data, source: search_data,
delay: 0, delay: 0,
minLength: 2, minLength: 2,
autoFocus: true, autoFocus: true,
select: function( event, ui ) { select: function(event, ui) {
location.href = ui.item.uri; location.href = ui.item.uri;
} }
}); });
}); });
{% endraw %} {% endraw %}

View file

@ -7,18 +7,25 @@ layout: null
"use strict" "use strict"
var zoom=2; var zoom = 2;
var minzoom=1; var minzoom = 1;
if(isMobile())var zoom=minzoom=0; if (isMobile()) var zoom = minzoom = 0;
var map = L.map('eventmap',{ 'zoom': zoom, 'minZoom': minzoom, 'center': [20.00, 10.00]}); var map = L.map('eventmap', {
'zoom': zoom,
'minZoom': minzoom,
'center': [20.00, 10.00]
});
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Data &copy; by <a href="http://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>.', attribution: 'Data &copy; by <a href="http://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>.',
maxZoom: 18 maxZoom: 18
}).addTo(map); }).addTo(map);
var markers = new L.MarkerClusterGroup({showCoverageOnHover: false, maxClusterRadius: 40}); var markers = new L.MarkerClusterGroup({
for (var i=0, nds=document.getElementById('eventdata').getElementsByTagName('DIV'), n=nds.length; i < n; i++) { showCoverageOnHover: false,
L.marker([parseFloat(nds[i].getAttribute('data-lat')), parseFloat(nds[i].getAttribute('data-lon'))]).bindPopup(nds[i].innerHTML).addTo(markers); maxClusterRadius: 40
});
for (var i = 0, nds = document.getElementById('eventdata').getElementsByTagName('DIV'), n = nds.length; i < n; i++) {
L.marker([parseFloat(nds[i].getAttribute('data-lat')), parseFloat(nds[i].getAttribute('data-lon'))]).bindPopup(nds[i].innerHTML).addTo(markers);
} }
map.addLayer(markers); map.addLayer(markers);

View file

@ -3,44 +3,44 @@
"use strict" "use strict"
function pngfix(){ function pngfix() {
//Allows IE6 to render transparent png //Allows IE6 to render transparent png
var arVersion = navigator.appVersion.split("MSIE") var arVersion = navigator.appVersion.split("MSIE")
var version = parseFloat(arVersion[1]) var version = parseFloat(arVersion[1])
if ((version >= 5.5) && (document.body.filters)) if ((version >= 5.5) && (document.body.filters))
{ {
for(var i=0; i<document.images.length; i++) for (var i = 0; i < document.images.length; i++)
{ {
var img = document.images[i] var img = document.images[i]
var imgName = img.src.toUpperCase() var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == "PNG") if (imgName.substring(imgName.length - 3, imgName.length) == "PNG")
{ {
//Workaround to skip github icons //Workaround to skip github icons
if(img.src.indexOf('gravatar.com')!==-1)continue; if (img.src.indexOf('gravatar.com') !== -1) continue;
var imgID = (img.id) ? "id='" + img.id + "' " : "" var imgID = (img.id) ? "id='" + img.id + "' " : ""
var imgClass = (img.className) ? "class='" + img.className + " ieimg' " : "class='ieimg' " var imgClass = (img.className) ? "class='" + img.className + " ieimg' " : "class='ieimg' "
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' " var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
var imgStyle = "display:inline-block;" + img.style.cssText var imgStyle = "display:inline-block;" + img.style.cssText
var imgWidth = img.width; var imgWidth = img.width;
var imgHeight = img.height; var imgHeight = img.height;
//Workaround for hidden img to prevent 0px width and height //Workaround for hidden img to prevent 0px width and height
if(img.src.indexOf('/img/clients/')!==-1){imgWidth='72';imgHeight='72';} if (img.src.indexOf('/img/clients/') !== -1) {
if (img.align == "left") imgStyle = "float:left;" + imgStyle imgWidth = '72';
if (img.align == "right") imgStyle = "float:right;" + imgStyle imgHeight = '72';
if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle }
var strNewHTML = "<span " + imgID + imgClass + imgTitle if (img.align == "left") imgStyle = "float:left;" + imgStyle
+ " style=\"" + "width:" + imgWidth + "px; height:" + imgHeight + "px;" + imgStyle + ";" if (img.align == "right") imgStyle = "float:right;" + imgStyle
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader" if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
+ "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" var strNewHTML = "<span " + imgID + imgClass + imgTitle + " style=\"" + "width:" + imgWidth + "px; height:" + imgHeight + "px;" + imgStyle + ";" + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader" + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
img.outerHTML = strNewHTML img.outerHTML = strNewHTML
i = i-1 i = i - 1
} }
} }
} }
} }
//Let other scripts know browser is IE6-7 //Let other scripts know browser is IE6-7
var legacyIE=true; var legacyIE = true;
//Render all transparent pngs //Render all transparent pngs
window.onload=pngfix; window.onload = pngfix;

View file

@ -7,316 +7,316 @@
"use strict" "use strict"
function getWidth(a) { function getWidth(a) {
// Return the integer value of the computed width of a DOM node. // Return the integer value of the computed width of a DOM node.
// Ex. getWidth(node); // Ex. getWidth(node);
var w = getStyle(a, 'width'); var w = getStyle(a, 'width');
if (w.indexOf('px') !== -1) return parseInt(w.replace('px', '')); if (w.indexOf('px') !== -1) return parseInt(w.replace('px', ''));
var p = [getStyle(a, 'padding-top'), getStyle(a, 'padding-right'), getStyle(a, 'padding-bottom'), getStyle(a, 'padding-left')]; var p = [getStyle(a, 'padding-top'), getStyle(a, 'padding-right'), getStyle(a, 'padding-bottom'), getStyle(a, 'padding-left')];
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
p[i] = (p[i].indexOf('px') !== -1) ? parseInt(p[i]) : 0; p[i] = (p[i].indexOf('px') !== -1) ? parseInt(p[i]) : 0;
} }
return Math.max(0, a.offsetWidth - p[1] - p[3]); return Math.max(0, a.offsetWidth - p[1] - p[3]);
} }
function getHeight(a) { function getHeight(a) {
// Return the integer value of the computed height of a DOM node. // Return the integer value of the computed height of a DOM node.
// Ex. getHeight(node); // Ex. getHeight(node);
var h = getStyle(a, 'height'); var h = getStyle(a, 'height');
if (h.indexOf('px') !== -1) return parseInt(h.replace('px', '')); if (h.indexOf('px') !== -1) return parseInt(h.replace('px', ''));
var p = [getStyle(a, 'padding-top'), getStyle(a, 'padding-right'), getStyle(a, 'padding-bottom'), getStyle(a, 'padding-left')]; var p = [getStyle(a, 'padding-top'), getStyle(a, 'padding-right'), getStyle(a, 'padding-bottom'), getStyle(a, 'padding-left')];
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
p[i] = (p[i].indexOf('px') !== -1) ? parseInt(p[i]) : 0; p[i] = (p[i].indexOf('px') !== -1) ? parseInt(p[i]) : 0;
} }
return Math.max(0, a.offsetHeight - p[0] - p[2]); return Math.max(0, a.offsetHeight - p[0] - p[2]);
} }
function getLeft(a) { function getLeft(a) {
// Return the integer value of the computed distance between given node and the browser window. // Return the integer value of the computed distance between given node and the browser window.
// Ex. getLeft(node); // Ex. getLeft(node);
var b = a.offsetLeft; var b = a.offsetLeft;
while (a.offsetParent) { while (a.offsetParent) {
a = a.offsetParent; a = a.offsetParent;
b += a.offsetLeft; b += a.offsetLeft;
} }
return b; return b;
} }
function getTop (a) { function getTop(a) {
// Return the integer value of the computed distance between given node and the browser window. // Return the integer value of the computed distance between given node and the browser window.
// Ex. getTop(node); // Ex. getTop(node);
var b = a.offsetTop; var b = a.offsetTop;
while (a.offsetParent) { while (a.offsetParent) {
a = a.offsetParent; a = a.offsetParent;
b += a.offsetTop; b += a.offsetTop;
} }
return b; return b;
} }
function getPageYOffset() { function getPageYOffset() {
// Return the integer value for the vertical position of the scroll bar. // Return the integer value for the vertical position of the scroll bar.
return window.pageYOffset || document.documentElement.scrollTop; return window.pageYOffset || document.documentElement.scrollTop;
} }
function getPageXOffset() { function getPageXOffset() {
// Return the integer value for the horizontal position of the scroll bar. // Return the integer value for the horizontal position of the scroll bar.
return window.pageXOffset || document.documentElement.scrollLeft; return window.pageXOffset || document.documentElement.scrollLeft;
} }
function getWindowY() { function getWindowY() {
// Return the integer value for the browser window height. // Return the integer value for the browser window height.
return window.innerHeight || document.documentElement.clientHeight; return window.innerHeight || document.documentElement.clientHeight;
} }
function getWindowX() { function getWindowX() {
// Return the integer value for the browser window width. // Return the integer value for the browser window width.
return window.innerWidth || document.documentElement.clientWidth; return window.innerWidth || document.documentElement.clientWidth;
} }
function isMobile() { function isMobile() {
// Return true if the mobile CSS stylesheet is used. // Return true if the mobile CSS stylesheet is used.
if (getStyle(document.getElementById('detectmobile'), 'display') != 'none') return true; if (getStyle(document.getElementById('detectmobile'), 'display') != 'none') return true;
return false; return false;
} }
function scrollToNode(t) { function scrollToNode(t) {
// Scroll to any node on the page. // Scroll to any node on the page.
if (document.body.getAttribute('data-scrollstatus') != null) { if (document.body.getAttribute('data-scrollstatus') != null) {
clearInterval(document.body.getAttribute('data-scrollstatus')); clearInterval(document.body.getAttribute('data-scrollstatus'));
document.body.removeAttribute('data-scrollstatus'); document.body.removeAttribute('data-scrollstatus');
} }
var delay = 800; var delay = 800;
var py = getPageYOffset(); var py = getPageYOffset();
var fy = getTop(t) var fy = getTop(t)
var dy = fy - py; var dy = fy - py;
var x = getPageXOffset(); var x = getPageXOffset();
var oti = new Date().getTime(); var oti = new Date().getTime();
document.body.setAttribute('data-scrollstatus', setInterval(function() { document.body.setAttribute('data-scrollstatus', setInterval(function() {
var nti = new Date().getTime() - oti; var nti = new Date().getTime() - oti;
if (nti >= delay) { if (nti >= delay) {
window.scrollTo(x, fy); window.scrollTo(x, fy);
clearInterval(document.body.getAttribute('data-scrollstatus')); clearInterval(document.body.getAttribute('data-scrollstatus'));
document.body.removeAttribute('data-scrollstatus'); document.body.removeAttribute('data-scrollstatus');
return; return;
} }
var p = nti / delay; var p = nti / delay;
p = p * (1 + (0.5 * (1 - p))); p = p * (1 + (0.5 * (1 - p)));
window.scrollTo(x, (py + (dy * p)).toFixed(0)); window.scrollTo(x, (py + (dy * p)).toFixed(0));
}, 10)); }, 10));
} }
function supportCSS(id) { function supportCSS(id) {
// Return true if the browser supports given CSS feature. // Return true if the browser supports given CSS feature.
var domPrefixes = 'Webkit Moz ms O'.split(' '); var domPrefixes = 'Webkit Moz ms O'.split(' ');
var nd = document.createElement('DIV'); var nd = document.createElement('DIV');
id = id.toLowerCase(); id = id.toLowerCase();
if (nd.style[id] !== undefined) return true; if (nd.style[id] !== undefined) return true;
idc = id.charAt(0).toUpperCase() + id.substr(1); idc = id.charAt(0).toUpperCase() + id.substr(1);
for (var i = 0, n = domPrefixes.length; i < n; i++) { for (var i = 0, n = domPrefixes.length; i < n; i++) {
if (nd.style[domPrefixes[i] + idc] !== undefined) return true; if (nd.style[domPrefixes[i] + idc] !== undefined) return true;
} }
return false; return false;
} }
function loadYoutubeVideo(e) { function loadYoutubeVideo(e) {
// Load Youtube video on target node on click. // Load Youtube video on target node on click.
function init(e) { function init(e) {
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
nd = document.createElement('IFRAME'); nd = document.createElement('IFRAME');
while (t.getAttribute('data-youtubeurl') === null || t.getAttribute('data-youtubeurl') === '') t = t.parentNode; while (t.getAttribute('data-youtubeurl') === null || t.getAttribute('data-youtubeurl') === '') t = t.parentNode;
nd.src = t.getAttribute('data-youtubeurl'); nd.src = t.getAttribute('data-youtubeurl');
nd.setAttribute('frameborder', 0); nd.setAttribute('frameborder', 0);
nd.setAttribute('allowfullscreen', true); nd.setAttribute('allowfullscreen', true);
t.innerHTML = ''; t.innerHTML = '';
t.appendChild(nd); t.appendChild(nd);
t.onclick = ''; t.onclick = '';
} }
onTouchClick(e, init); onTouchClick(e, init);
} }
function expandBox(t) { function expandBox(t) {
// Expand or shrink box. // Expand or shrink box.
var phe = getHeight(t); var phe = getHeight(t);
t.style.transition = t.style.MozTransition = t.style.WebkitTransition = 'all 0s ease 0s'; t.style.transition = t.style.MozTransition = t.style.WebkitTransition = 'all 0s ease 0s';
if (t.className.indexOf('expanded') === -1) addClass(t, 'expanded'); if (t.className.indexOf('expanded') === -1) addClass(t, 'expanded');
else removeClass(t, 'expanded'); else removeClass(t, 'expanded');
t.style.height = ''; t.style.height = '';
var nhe = getHeight(t); var nhe = getHeight(t);
t.style.height = phe + 'px'; t.style.height = phe + 'px';
// Async call to prevent transition from applying on last style.height statement. // Async call to prevent transition from applying on last style.height statement.
setTimeout(function() { setTimeout(function() {
t.style.transition = t.style.MozTransition = t.style.WebkitTransition = ''; t.style.transition = t.style.MozTransition = t.style.WebkitTransition = '';
t.style.height = nhe + 'px'; t.style.height = nhe + 'px';
}, 20); }, 20);
} }
function boxShow(e) { function boxShow(e) {
// Display the box content when the user click a box on the "Secure your wallet" page. // Display the box content when the user click a box on the "Secure your wallet" page.
function init(e) { function init(e) {
var t = getEvent(e, 'target'); var t = getEvent(e, 'target');
while (t.nodeName != 'DIV') t = t.parentNode; while (t.nodeName != 'DIV') t = t.parentNode;
expandBox(t); expandBox(t);
cancelEvent(e); cancelEvent(e);
} }
onTouchClick(e, init); onTouchClick(e, init);
} }
function faqShow(e) { function faqShow(e) {
// Display the content of a question in the FAQ at user request. // Display the content of a question in the FAQ at user request.
function init(e) { function init(e) {
var t = getEvent(e, 'target'); var t = getEvent(e, 'target');
while (t.nodeType != 1 || t.nodeName != 'DIV') t = t.nextSibling; while (t.nodeType != 1 || t.nodeName != 'DIV') t = t.nextSibling;
expandBox(t); expandBox(t);
cancelEvent(e); cancelEvent(e);
} }
onTouchClick(e, init); onTouchClick(e, init);
} }
function materialShow(e) { function materialShow(e) {
// Display more materials on the "Press center" page at user request. // Display more materials on the "Press center" page at user request.
function init(e) { function init(e) {
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
p = t; p = t;
while (p.nodeType != 1 || p.nodeName != 'DIV') p = p.parentNode; while (p.nodeType != 1 || p.nodeName != 'DIV') p = p.parentNode;
expandBox(p); expandBox(p);
cancelEvent(e); cancelEvent(e);
} }
onTouchClick(e, init); onTouchClick(e, init);
} }
function librariesShow(e) { function librariesShow(e) {
// Display more open source projects on the "Development" page at user request. // Display more open source projects on the "Development" page at user request.
function init(e) { function init(e) {
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
p = t; p = t;
while (p.nodeType != 1 || p.nodeName != 'UL') p = p.parentNode; while (p.nodeType != 1 || p.nodeName != 'UL') p = p.parentNode;
expandBox(p); expandBox(p);
cancelEvent(e); cancelEvent(e);
} }
onTouchClick(e, init); onTouchClick(e, init);
} }
function freenodeShow(e) { function freenodeShow(e) {
// Display freenode chat window on the "Development" page at user request. // Display freenode chat window on the "Development" page at user request.
document.getElementById('chatbox').innerHTML = '<iframe style=width:98%;min-width:400px;height:600px src="http://webchat.freenode.net/?channels=bitcoin-dev" />'; document.getElementById('chatbox').innerHTML = '<iframe style=width:98%;min-width:400px;height:600px src="http://webchat.freenode.net/?channels=bitcoin-dev" />';
cancelEvent(e); cancelEvent(e);
} }
function updateToc() { function updateToc() {
// Update table of content active entry and browser url on scroll. // Update table of content active entry and browser url on scroll.
var pageoffset; var pageoffset;
var windowy; var windowy;
var toc; var toc;
var fallback; var fallback;
var first; var first;
var last; var last;
var closer; var closer;
var init = function() { var init = function() {
setenv(); setenv();
updatehistory(); updatehistory();
updatetoc(); updatetoc();
} }
// Set variables. // Set variables.
var setenv = function() { var setenv = function() {
pageoffset = getPageYOffset(); pageoffset = getPageYOffset();
windowy = getWindowY(); windowy = getWindowY();
toc = document.getElementById('toc'); toc = document.getElementById('toc');
fallback = document.getElementsByTagName('H2')[0]; fallback = document.getElementsByTagName('H2')[0];
first = [fallback, getTop(fallback)]; first = [fallback, getTop(fallback)];
last = [fallback, getTop(fallback)]; last = [fallback, getTop(fallback)];
closer = [fallback, getTop(fallback)]; closer = [fallback, getTop(fallback)];
// Find all titles in toc. // Find all titles in toc.
var nodes = []; var nodes = [];
var tags = ['H2', 'H3', 'H4', 'H5', 'H6']; var tags = ['H2', 'H3', 'H4', 'H5', 'H6'];
for (var i = 0, n = tags.length; i < n; i++) { for (var i = 0, n = tags.length; i < n; i++) {
for (var ii = 0, t = document.getElementsByTagName(tags[i]), nn = t.length; ii < nn; ii++) { for (var ii = 0, t = document.getElementsByTagName(tags[i]), nn = t.length; ii < nn; ii++) {
if (t[ii].className.indexOf('no_toc')!==-1) continue; if (t[ii].className.indexOf('no_toc') !== -1) continue;
nodes.push(t[ii]); nodes.push(t[ii]);
} }
} }
// Find first title, last title and closer title. // Find first title, last title and closer title.
for (var i = 0, n = nodes.length; i < n; i++) { for (var i = 0, n = nodes.length; i < n; i++) {
if (!nodes[i].id) continue; if (!nodes[i].id) continue;
var top = getTop(nodes[i]); var top = getTop(nodes[i]);
if (top < first[1]) first = [nodes[i], top]; if (top < first[1]) first = [nodes[i], top];
if (top > last[1]) last = [nodes[i], top]; if (top > last[1]) last = [nodes[i], top];
if (top < pageoffset + 10 && top > closer[1]) closer = [nodes[i], top]; if (top < pageoffset + 10 && top > closer[1]) closer = [nodes[i], top];
} }
// Set closer title to first or last title if at the top or bottom of the page. // Set closer title to first or last title if at the top or bottom of the page.
if (pageoffset < first[1]) closer = [first[0], first[1]]; if (pageoffset < first[1]) closer = [first[0], first[1]];
if (windowy + pageoffset >= getHeight(document.body)) closer = [last[0], last[1]]; if (windowy + pageoffset >= getHeight(document.body)) closer = [last[0], last[1]];
} }
// Update toc position and set active toc entry. // Update toc position and set active toc entry.
var updatetoc = function() { var updatetoc = function() {
// Set bottom and top to fit within window and not overflow its parent node. // Set bottom and top to fit within window and not overflow its parent node.
var div = toc.getElementsByTagName('DIV')[0]; var div = toc.getElementsByTagName('DIV')[0];
if (pageoffset > getTop(toc)) { if (pageoffset > getTop(toc)) {
addClass(div, 'scroll'); addClass(div, 'scroll');
div.style.top = '20px'; div.style.top = '20px';
div.style.bottom = Math.max((pageoffset + windowy) - (getHeight(toc.parentNode) + getTop(toc.parentNode)), 20) + 'px'; div.style.bottom = Math.max((pageoffset + windowy) - (getHeight(toc.parentNode) + getTop(toc.parentNode)), 20) + 'px';
} else removeClass(div, 'scroll'); } else removeClass(div, 'scroll');
// Remove .active class from toc and find new active toc entry. // Remove .active class from toc and find new active toc entry.
var a = false; var a = false;
for (var i = 0, t = toc.getElementsByTagName('*'), n = t.length; i < n; i++) { for (var i = 0, t = toc.getElementsByTagName('*'), n = t.length; i < n; i++) {
removeClass(t[i], 'active'); removeClass(t[i], 'active');
if (t[i].nodeName == 'A' && t[i].getAttribute('href') == '#' + closer[0].id) a = t[i]; if (t[i].nodeName == 'A' && t[i].getAttribute('href') == '#' + closer[0].id) a = t[i];
} }
if (a === false) return; if (a === false) return;
// Set .active class on new active toc entry. // Set .active class on new active toc entry.
var nd = a; var nd = a;
while (nd.parentNode.nodeName == 'LI' || nd.parentNode.nodeName == 'UL') { while (nd.parentNode.nodeName == 'LI' || nd.parentNode.nodeName == 'UL') {
addClass(nd, 'active'); addClass(nd, 'active');
nd = nd.parentNode; nd = nd.parentNode;
} }
// Auto-scroll in toc to keep active toc entry visible. // Auto-scroll in toc to keep active toc entry visible.
var nd = a; var nd = a;
var otop = nd.offsetTop; var otop = nd.offsetTop;
while (nd.offsetParent != div && nd.offsetParent) { while (nd.offsetParent != div && nd.offsetParent) {
nd = nd.offsetParent; nd = nd.offsetParent;
otop += nd.offsetTop; otop += nd.offsetTop;
} }
var bdiff = getHeight(a) + otop - div.scrollTop - getHeight(div); var bdiff = getHeight(a) + otop - div.scrollTop - getHeight(div);
var tdiff = getHeight(a) - otop + div.scrollTop; var tdiff = getHeight(a) - otop + div.scrollTop;
if (tdiff > 0 || bdiff > 0) div.scrollTop -= tdiff; if (tdiff > 0 || bdiff > 0) div.scrollTop -= tdiff;
} }
// Update browser url. // Update browser url.
var updatehistory = function() { var updatehistory = function() {
// Don't call window.history if not supported. // Don't call window.history if not supported.
if (!window.history || !window.history.replaceState) return; if (!window.history || !window.history.replaceState) return;
// Don't update window url when it doesn't need to be updated. // Don't update window url when it doesn't need to be updated.
if (new RegExp('#' + closer[0].id + '$').test(window.location.href.toString())) return; if (new RegExp('#' + closer[0].id + '$').test(window.location.href.toString())) return;
// Don't update window url when the window is over the first title in the page. // Don't update window url when the window is over the first title in the page.
if (pageoffset < first[1]) return; if (pageoffset < first[1]) return;
// Don't update window url when page is not loaded, or user just clicked a url. // Don't update window url when page is not loaded, or user just clicked a url.
if (!toc.hasAttribute('data-timestamp') || toc.getAttribute('data-timestamp') > new Date().getTime() - 1000) return; if (!toc.hasAttribute('data-timestamp') || toc.getAttribute('data-timestamp') > new Date().getTime() - 1000) return;
window.history.replaceState(null, null, '#' + closer[0].id); window.history.replaceState(null, null, '#' + closer[0].id);
} }
// Update the toc when the page stops scrolling. // Update the toc when the page stops scrolling.
var evtimeout = function() { var evtimeout = function() {
toc = document.getElementById('toc'); toc = document.getElementById('toc');
clearTimeout(toc.getAttribute('data-timeout')); clearTimeout(toc.getAttribute('data-timeout'));
toc.setAttribute('data-timeout', setTimeout(init, 1)); toc.setAttribute('data-timeout', setTimeout(init, 1));
} }
// Reset timestamp on page load and each time the user clicks a url. // Reset timestamp on page load and each time the user clicks a url.
var evtimestamp = function() { var evtimestamp = function() {
toc = document.getElementById('toc'); toc = document.getElementById('toc');
document.getElementById('toc').setAttribute('data-timestamp', new Date().getTime()); document.getElementById('toc').setAttribute('data-timestamp', new Date().getTime());
} }
addEvent(window, 'scroll', evtimeout); addEvent(window, 'scroll', evtimeout);
addEvent(window, 'popstate', evtimestamp); addEvent(window, 'popstate', evtimestamp);
addEvent(window, 'load', evtimestamp); addEvent(window, 'load', evtimestamp);
init(); init();
} }
function updateIssue(e) { function updateIssue(e) {
// Update GitHub issue link pre-filled with current page location. // Update GitHub issue link pre-filled with current page location.
var t = getEvent(e, 'target'); var t = getEvent(e, 'target');
t.href = 'https://github.com/bitcoin-dot-org/bitcoin.org/issues/new?body=' + encodeURIComponent('Location: ' + window.location.href.toString() + "\n\n"); t.href = 'https://github.com/bitcoin-dot-org/bitcoin.org/issues/new?body=' + encodeURIComponent('Location: ' + window.location.href.toString() + "\n\n");
} }
function updateSource(e){ function updateSource(e) {
// Update GitHub source file link pre-filled with current page location. // Update GitHub source file link pre-filled with current page location.
if (!document.getElementsByClassName) return; if (!document.getElementsByClassName) return;
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
nodes = document.getElementsByClassName('sourcefile'), nodes = document.getElementsByClassName('sourcefile'),
pageoffset = Math.max(0, getPageYOffset() + 100), pageoffset = Math.max(0, getPageYOffset() + 100),
windowy = getWindowY(), windowy = getWindowY(),
@ -324,230 +324,230 @@ var t = getEvent(e, 'target'),
first = [fallback, getTop(fallback)], first = [fallback, getTop(fallback)],
last = [fallback, getTop(fallback)], last = [fallback, getTop(fallback)],
closer = [fallback, getTop(fallback)]; closer = [fallback, getTop(fallback)];
// Find first, last and closer node. // Find first, last and closer node.
for (var i = 0, n = nodes.length; i < n; i++) { for (var i = 0, n = nodes.length; i < n; i++) {
var top = getTop(nodes[i]); var top = getTop(nodes[i]);
if (top < first[1]) first = [nodes[i], top]; if (top < first[1]) first = [nodes[i], top];
if (top > last[1]) last = [nodes[i], top]; if (top > last[1]) last = [nodes[i], top];
if (top < pageoffset + 10 && top > closer[1]) closer = [nodes[i], top]; if (top < pageoffset + 10 && top > closer[1]) closer = [nodes[i], top];
} }
// Set closer title to first or last title if at the top or bottom of the page. // Set closer title to first or last title if at the top or bottom of the page.
if (pageoffset < first[1]) closer = [first[0], first[1]]; if (pageoffset < first[1]) closer = [first[0], first[1]];
if (windowy + pageoffset >= getHeight(document.body)) closer = [last[0], last[1]]; if (windowy + pageoffset >= getHeight(document.body)) closer = [last[0], last[1]];
// Set updated url to source file. // Set updated url to source file.
t.href = 'https://github.com/bitcoin-dot-org/bitcoin.org/edit/master/' + closer[0].getAttribute('data-sourcefile'); t.href = 'https://github.com/bitcoin-dot-org/bitcoin.org/edit/master/' + closer[0].getAttribute('data-sourcefile');
} }
function disclaimerClose(e) { function disclaimerClose(e) {
// Auto close temporary disclaimer in devel-docs. // Auto close temporary disclaimer in devel-docs.
if (e) cancelEvent(e); if (e) cancelEvent(e);
var t = document.getElementById('develdocdisclaimer') var t = document.getElementById('develdocdisclaimer')
t.parentNode.removeChild(t); t.parentNode.removeChild(t);
if (typeof(Storage) === 'undefined') return; if (typeof(Storage) === 'undefined') return;
sessionStorage.setItem('develdocdisclaimerclose', '1'); sessionStorage.setItem('develdocdisclaimerclose', '1');
} }
function disclaimerAutoClose() { function disclaimerAutoClose() {
// Auto close temporary disclaimer in devel-docs if session says so. // Auto close temporary disclaimer in devel-docs if session says so.
if (typeof(Storage) === 'undefined') return; if (typeof(Storage) === 'undefined') return;
if (sessionStorage.getItem('develdocdisclaimerclose') === '1') disclaimerClose(); if (sessionStorage.getItem('develdocdisclaimerclose') === '1') disclaimerClose();
} }
function walletMenuListener(e) { function walletMenuListener(e) {
// Listen for events on the wallet menu. // Listen for events on the wallet menu.
var walletSelectPlatform = function(e) { var walletSelectPlatform = function(e) {
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
p = t; p = t;
if (t.nodeName != 'A') return; if (t.nodeName != 'A') return;
while (p.parentNode.nodeName == 'UL' || p.parentNode.nodeName == 'LI') p = p.parentNode; while (p.parentNode.nodeName == 'UL' || p.parentNode.nodeName == 'LI') p = p.parentNode;
for (var i = 0, nds = p.getElementsByTagName('LI'), n = nds.length; i < n; i++) removeClass(nds[i], 'active'); for (var i = 0, nds = p.getElementsByTagName('LI'), n = nds.length; i < n; i++) removeClass(nds[i], 'active');
var tt = t; var tt = t;
while (tt != p) { while (tt != p) {
if (tt.nodeName == 'LI') addClass(tt, 'active'); if (tt.nodeName == 'LI') addClass(tt, 'active');
tt = tt.parentNode; tt = tt.parentNode;
} }
walletShowPlatform(t.getAttribute('data-walletcompat')); walletShowPlatform(t.getAttribute('data-walletcompat'));
if (isMobile() && !hasSubItems(t)) scrollToNode(document.getElementById('wallets')); if (isMobile() && !hasSubItems(t)) scrollToNode(document.getElementById('wallets'));
}, },
hasSubItems = function(t) { hasSubItems = function(t) {
while (t.nodeName != 'LI') t = t.parentNode; while (t.nodeName != 'LI') t = t.parentNode;
return (t.getElementsByTagName('UL').length > 0); return (t.getElementsByTagName('UL').length > 0);
}; };
// Pre-process events and call appropriate function. // Pre-process events and call appropriate function.
onTouchClick(e, walletSelectPlatform); onTouchClick(e, walletSelectPlatform);
} }
function walletListener(e) { function walletListener(e) {
// Listen for events on wallets. // Listen for events on wallets.
var t = getEvent(e, 'target'), var t = getEvent(e, 'target'),
walletShow = function() { walletShow = function() {
// Show wallet on click on mobile or desktop. // Show wallet on click on mobile or desktop.
if (t.id == 'wallets') return; if (t.id == 'wallets') return;
while (t.parentNode && t.parentNode.id != 'wallets') t = t.parentNode; while (t.parentNode && t.parentNode.id != 'wallets') t = t.parentNode;
if (!t.parentNode) return; if (!t.parentNode) return;
if (isMobile()) { if (isMobile()) {
var p = document.getElementById('walletsmobile'); var p = document.getElementById('walletsmobile');
t = t.cloneNode(true); t = t.cloneNode(true);
p.innerHTML = ''; p.innerHTML = '';
p.appendChild(t); p.appendChild(t);
scrollToNode(p); scrollToNode(p);
} else { } else {
addClass(t, 'active'); addClass(t, 'active');
addEvent(document.body, 'click', walletListener); addEvent(document.body, 'click', walletListener);
} }
}, },
walletHide = function() { walletHide = function() {
// Disable wallet when the mouse clicks elsewhere. // Disable wallet when the mouse clicks elsewhere.
for (var i = 0, wallets = document.getElementById('wallets').childNodes, n = wallets.length; i < n; i++) { for (var i = 0, wallets = document.getElementById('wallets').childNodes, n = wallets.length; i < n; i++) {
if (wallets[i].nodeType != 1) continue; if (wallets[i].nodeType != 1) continue;
removeClass(wallets[i], 'active'); removeClass(wallets[i], 'active');
} }
removeEvent(document.body, 'click', walletListener); removeEvent(document.body, 'click', walletListener);
}; };
// Call appropriate function on click. // Call appropriate function on click.
onTouchClick(e, function() { onTouchClick(e, function() {
walletHide(); walletHide();
walletShow(); walletShow();
}); });
} }
function walletScoreListener(e) { function walletScoreListener(e) {
// Listen for events on wallet scores and display them on tap. // Listen for events on wallet scores and display them on tap.
var init = function(e) { var init = function(e) {
var t = getEvent(e, 'target'); var t = getEvent(e, 'target');
while (!t.parentNode.parentNode.parentNode.id) t = t.parentNode; while (!t.parentNode.parentNode.parentNode.id) t = t.parentNode;
(t.className.indexOf('hover') === -1) ? addClass(t, 'hover') : removeClass(t, 'hover'); (t.className.indexOf('hover') === -1) ? addClass(t, 'hover'): removeClass(t, 'hover');
}; };
onTouchClick(e, init); onTouchClick(e, init);
} }
function walletShowPlatform(platform) { function walletShowPlatform(platform) {
// Show wallets for given platform in the menu. // Show wallets for given platform in the menu.
var t = null, var t = null,
fallback = '', fallback = '',
walletMenu = document.getElementById('walletmenu'), walletMenu = document.getElementById('walletmenu'),
getMenuState = function() { getMenuState = function() {
// Find active node in the menu for given platform and fallback category if in a submenu. // Find active node in the menu for given platform and fallback category if in a submenu.
for (var i = 0, nds = walletMenu.getElementsByTagName('A'), n = nds.length; i < n; i++) { for (var i = 0, nds = walletMenu.getElementsByTagName('A'), n = nds.length; i < n; i++) {
if (nds[i].getAttribute('data-walletcompat') != platform) continue; if (nds[i].getAttribute('data-walletcompat') != platform) continue;
if (nds[i].getAttribute('data-active') == 1) return false; if (nds[i].getAttribute('data-active') == 1) return false;
t = nds[i]; t = nds[i];
var p = nds[i].parentNode.parentNode.parentNode; var p = nds[i].parentNode.parentNode.parentNode;
if (p.nodeName == 'LI') fallback = p.getElementsByTagName('A')[0].getAttribute('data-walletcompat'); if (p.nodeName == 'LI') fallback = p.getElementsByTagName('A')[0].getAttribute('data-walletcompat');
break; break;
} }
return true; return true;
}, },
updateMenu = function() { updateMenu = function() {
// Set active nodes in the menu for the new platform. // Set active nodes in the menu for the new platform.
addClass(walletMenu.getElementsByTagName('UL')[0], 'menutap'); addClass(walletMenu.getElementsByTagName('UL')[0], 'menutap');
for (var i = 0, nds = walletMenu.getElementsByTagName('A'), n = nds.length; i < n; i++) { for (var i = 0, nds = walletMenu.getElementsByTagName('A'), n = nds.length; i < n; i++) {
nds[i].removeAttribute('data-active'); nds[i].removeAttribute('data-active');
removeClass(nds[i].parentNode, 'active'); removeClass(nds[i].parentNode, 'active');
} }
if (platform != 'default') { if (platform != 'default') {
t.setAttribute('data-active', '1'); t.setAttribute('data-active', '1');
addClass(t.parentNode, 'active'); addClass(t.parentNode, 'active');
var p = t.parentNode.parentNode.parentNode; var p = t.parentNode.parentNode.parentNode;
if (p.nodeName == 'LI') addClass(p, 'active'); if (p.nodeName == 'LI') addClass(p, 'active');
} }
}, },
updateWallets = function() { updateWallets = function() {
// Replace wallets by those for given platform and rotate them. // Replace wallets by those for given platform and rotate them.
var p = document.getElementById('wallets'); var p = document.getElementById('wallets');
var lasttimeout = p.getAttribute('data-timeout'); var lasttimeout = p.getAttribute('data-timeout');
var timeout = (lasttimeout !== null && lasttimeout !== '' && supportCSS('transition')) ? 200 : 1; var timeout = (lasttimeout !== null && lasttimeout !== '' && supportCSS('transition')) ? 200 : 1;
addClass(p, 'disabled'); addClass(p, 'disabled');
addClass(p, 'nohover'); addClass(p, 'nohover');
clearTimeout(lasttimeout); clearTimeout(lasttimeout);
p.setAttribute('data-timeout', setTimeout(function() { p.setAttribute('data-timeout', setTimeout(function() {
p.innerHTML = ''; p.innerHTML = '';
var platforms = (platform == 'default') ? ['desktop', 'mobile'] : [platform]; var platforms = (platform == 'default') ? ['desktop', 'mobile'] : [platform];
for (var i = 0, nds = document.getElementById('walletsswitch').childNodes, n = nds.length; i < n; i++) { for (var i = 0, nds = document.getElementById('walletsswitch').childNodes, n = nds.length; i < n; i++) {
if (nds[i].nodeType != 1) continue; if (nds[i].nodeType != 1) continue;
var id = nds[i].id.split('-')[1]; var id = nds[i].id.split('-')[1];
if (document.getElementById('wallet-' + id)) continue; if (document.getElementById('wallet-' + id)) continue;
var nd = null; var nd = null;
for (var ii = 0, nn = platforms.length; ii < nn; ii++) { for (var ii = 0, nn = platforms.length; ii < nn; ii++) {
var wp = document.getElementById('wallet-' + id + '-' + platforms[ii]); var wp = document.getElementById('wallet-' + id + '-' + platforms[ii]);
if (wp) var nd = wp; if (wp) var nd = wp;
} }
if (nd === null) { if (nd === null) {
var wf = document.getElementById('wallet-' + id + '-' + fallback); var wf = document.getElementById('wallet-' + id + '-' + fallback);
if (wf && wf.getAttribute('data-walletcompat').indexOf(platform) !== -1) var nd = wf; if (wf && wf.getAttribute('data-walletcompat').indexOf(platform) !== -1) var nd = wf;
} }
if (nd === null) continue; if (nd === null) continue;
nd = nd.cloneNode(true); nd = nd.cloneNode(true);
nd.id = 'wallet-' + id; nd.id = 'wallet-' + id;
p.appendChild(nd); p.appendChild(nd);
} }
walletRotate(); walletRotate();
removeClass(p, 'disabled'); removeClass(p, 'disabled');
document.getElementById('walletsmobile').innerHTML = ''; document.getElementById('walletsmobile').innerHTML = '';
}, timeout)); }, timeout));
}; };
if(!getMenuState()) return; if (!getMenuState()) return;
updateMenu(); updateMenu();
updateWallets(); updateWallets();
} }
function walletRotate() { function walletRotate() {
// Rotate wallets once a day. // Rotate wallets once a day.
var ar = { var ar = {
1: [], 1: [],
2: [], 2: [],
3: [], 3: [],
4: [] 4: []
} }
for (var i = 0, nds = document.getElementById('wallets').childNodes, n = nds.length; i < n; i++) { for (var i = 0, nds = document.getElementById('wallets').childNodes, n = nds.length; i < n; i++) {
if (nds[i].nodeType != 1) continue; if (nds[i].nodeType != 1) continue;
ar[parseInt(nds[i].getAttribute('data-walletlevel'))].push(nds[i]); ar[parseInt(nds[i].getAttribute('data-walletlevel'))].push(nds[i]);
} }
var sum = Math.floor(new Date() / 86400000); var sum = Math.floor(new Date() / 86400000);
for (var k in ar) { for (var k in ar) {
if (ar[k].length == 0) continue; if (ar[k].length == 0) continue;
var pre = ar[k][ar[k].length - 1].nextSibling; var pre = ar[k][ar[k].length - 1].nextSibling;
for (i = 0, n = sum % ar[k].length; i < n; i++) ar[k][i].parentNode.insertBefore(ar[k][i], pre); for (i = 0, n = sum % ar[k].length; i < n; i++) ar[k][i].parentNode.insertBefore(ar[k][i], pre);
} }
} }
function makeEditable(e) { function makeEditable(e) {
// An easter egg that makes the page editable when user click on the page and hold their mouse button for one second. // An easter egg that makes the page editable when user click on the page and hold their mouse button for one second.
// This trick allows translators and writers to preview their work. // This trick allows translators and writers to preview their work.
if (!e) var e = window.event; if (!e) var e = window.event;
switch (getEvent(e, 'type')) { switch (getEvent(e, 'type')) {
case 'mousedown': case 'mousedown':
if ((e.which && e.which == 3) || (e.button && e.button == 2)) return; if ((e.which && e.which == 3) || (e.button && e.button == 2)) return;
var t = getEvent(e, 'target'); var t = getEvent(e, 'target');
while (t.parentNode) { while (t.parentNode) {
if (getStyle(t, 'overflow') == 'auto' || getStyle(t, 'overflow-y') == 'auto' || getStyle(t, 'overflow-x') == 'auto') return; if (getStyle(t, 'overflow') == 'auto' || getStyle(t, 'overflow-y') == 'auto' || getStyle(t, 'overflow-x') == 'auto') return;
t = t.parentNode; t = t.parentNode;
} }
addEvent(document.body, 'mouseup', makeEditable); addEvent(document.body, 'mouseup', makeEditable);
addEvent(document.body, 'mousemove', makeEditable); addEvent(document.body, 'mousemove', makeEditable);
document.body.setAttribute('timeoutEdit', setTimeout(function() { document.body.setAttribute('timeoutEdit', setTimeout(function() {
removeEvent(document.body, 'mouseup', makeEditable); removeEvent(document.body, 'mouseup', makeEditable);
removeEvent(document.body, 'mousemove', makeEditable); removeEvent(document.body, 'mousemove', makeEditable);
var c = document.getElementById('content'); var c = document.getElementById('content');
c.contentEditable = true; c.contentEditable = true;
c.style.borderColor = '#bfbfbf'; c.style.borderColor = '#bfbfbf';
setTimeout(function() { setTimeout(function() {
c.style.borderColor = ''; c.style.borderColor = '';
}, 200); }, 200);
}, 1000)); }, 1000));
break; break;
case 'mouseup': case 'mouseup':
case 'mousemove': case 'mousemove':
removeEvent(document.body, 'mouseup', makeEditable); removeEvent(document.body, 'mouseup', makeEditable);
removeEvent(document.body, 'mousemove', makeEditable); removeEvent(document.body, 'mousemove', makeEditable);
clearTimeout(document.body.getAttribute('timeoutEdit')); clearTimeout(document.body.getAttribute('timeoutEdit'));
break; break;
} }
} }
// Add makeEditable event listener // Add makeEditable event listener
var xint = setInterval(function() { var xint = setInterval(function() {
if (!document.body) return; if (!document.body) return;
addEvent(document.body, 'mousedown', makeEditable); addEvent(document.body, 'mousedown', makeEditable);
clearInterval(xint); clearInterval(xint);
}, 200); }, 200);