/** * Our main Javascript file. */ (function() { /** * Return true if we have a function that returns cryptographically random * values. False otherwise. */ function i_can_has_good_crypto() { if (window.crypto && window.crypto.getRandomValues) { return(true); } return(false); } // End of i_can_has_good_crypto() /** * Roll a die. * * @return integer A random number between 1 and 6, inclusive. */ function die_roll() { var retval; if (i_can_has_good_crypto()) { var a = new Uint32Array(1); window.crypto.getRandomValues(a); retval = (a[0] % 6) + 1; } else { // // Fall back to something way less secure. The user has already // been warned. // retval = Math.floor(Math.random() * 6) + 1; } return(retval); } // End of die_roll() /** * Roll a die 5 times. * * @return array an Array of 5 dice rolls */ function roll_dice() { var retval = new Array(); retval.push(die_roll()); retval.push(die_roll()); retval.push(die_roll()); retval.push(die_roll()); retval.push(die_roll()); return(retval); } /** * Look up a word from our wordlist. * * @param object wordlist Our hash table of dice rolls and their corresponding words. * @param integer index * * @return string The word from the dicelist */ function get_word(wordlist, index) { var retval = wordlist[index]; return(retval); } // // Handler to mark the clicked number of dice button as active. // jQuery(".dice_button").on("click", function(e) { jQuery(".dice_button").removeClass("active"); jQuery(e.target).addClass("active"); }); /** * This function displays each dice roll. * * @param array rows Array of rows of dice rolls that we had. * @param object cb Our callback to fire when done * */ function display_row(rows, cb) { var fadein_duration = 250; var fadeout_delay = 750; if (rows.length) { // // Grab a row, and hide each of the dice and the word in it. // var row = rows.shift(); var html = row.hide().appendTo(".results"); html.find(".dice_element").each(function(i, value) { jQuery(value).hide(); }); // // Now show the row, and loop through each element, fading in // the dice and the word in sequence. // html.show(fadein_duration, function() { jQuery(this).find(".dice_element").each(function(i, value) { var delay = i * 100; setTimeout(function() { jQuery(value).show(); }, delay); }); // // Now fade out the entire row, and call ourselves again // so we can repeat with the next row. // jQuery(this).delay(fadeout_delay) .fadeOut(fadeout_delay, function() { display_row(rows, cb); }); }); } else { // // All done with displaying rows, fire our callback and get outta here. // cb(); } } // End of display_row() /** * Display the actual results. * * @param cb object Optional callback to fire when done */ function display_results(cb) { jQuery(".results_words_key").hide().clone().appendTo(".results"); jQuery(".results_words_value").hide().clone().appendTo(".results"); jQuery(".results").append("
"); jQuery(".results_phrase_key").hide().clone().appendTo(".results"); jQuery(".results_phrase_value").hide().clone().appendTo(".results"); jQuery(".results .results_words_key").fadeIn(500, function() { jQuery(".results .results_words_value").fadeIn(500, function() { jQuery(".results .results_phrase_key").fadeIn(500, function() { jQuery(".results .results_phrase_value").fadeIn(500, function() { if (cb) { cb(); } }); }); }); }); } // End of display_results() /** * Return the width of the browser window. */ function get_width() { return(jQuery(window).width()); } /** * Return true if we are running on a mobile screen. */ function is_mobile() { if (get_width() <= 480) { return(true); } return(false); } // End of is_mobile() // // Handler when the "Roll Dice" button is clicked. It gets the // passphrase and updates the HTML with it. // jQuery("#roll_dice").on("click", function(e) { var target_height = 200; if (is_mobile()) { target_height = 400; } jQuery(".results").animate({height: target_height}, 400); // // If we're running on an iPhone or similar, scroll down so that we can // see the dice rolls and passphrase. // if (is_mobile()) { var aTag = $("a[name='roll_dice_button']"); $("html,body").animate({scrollTop: aTag.offset().top}, "slow"); } // // Remove any old results // jQuery(".results").empty(); // // Make our dice rolls // var num_dice = jQuery(".dice_button.active").html(); var passphrase = new Array(); var rolls = new Array(); for (var i=0; i