From a8c68cfcfe947c35a0fa0129da4382e161efc369 Mon Sep 17 00:00:00 2001 From: Chris Danis Date: Sun, 21 Apr 2019 14:23:33 -0400 Subject: [PATCH] add history events on any modification, and button-ify permalink --- css/decklist.css | 2 +- index.html | 2 +- js/decklist/main.js | 58 ++++++++++++++++++++++++++++++++------------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/css/decklist.css b/css/decklist.css index c86ad06..177fc90 100644 --- a/css/decklist.css +++ b/css/decklist.css @@ -135,7 +135,7 @@ h2 { text-align: center; } -#download, #upload { +#download, #upload, #permalink { margin-top: 10px; } diff --git a/index.html b/index.html index 61d9284..16410ac 100644 --- a/index.html +++ b/index.html @@ -108,7 +108,7 @@

-

+
diff --git a/js/decklist/main.js b/js/decklist/main.js index c5b7556..ec4ba2e 100644 --- a/js/decklist/main.js +++ b/js/decklist/main.js @@ -17,6 +17,7 @@ $(document).ready(function() { $('#eventdate').datepicker({ dateFormat: 'yy-mm-dd' }); // ISO-8601, woohoo $('#download').button(); $('#upload').button(); + $('#permalink').button(); $('input[type=radio]').checkboxradio({ icon: false }); @@ -36,6 +37,15 @@ $(document).ready(function() { // parse the GET parameters and set them, also generates preview (via event) parseGET(); + + // Need to populate an initial history state so the first popstate event + // has something to return to + history.replaceState(generatePermalink(true), document.title, generatePermalink()); + // and need to update our state whenever back/forward buttons are pushed. + window.onpopstate = function(event) { + parseUrlIntoGET(event.state); + parseGET(); + } }); // Blocks updates to the PDF @@ -45,7 +55,10 @@ function pdfChangeWait() { decklistChangeTimer = setTimeout(function() { const parsedInput = Decklist.parse(); validateInput(parsedInput); - $('#permalink').attr("href", generatePermalink()); + if (generatePermalink(true) !== history.state) { + console.log("pushing new state " + generatePermalink(true)); + history.pushState(generatePermalink(true), document.title, generatePermalink()); + } }, 400); // Wait 1500 milliseconds to generate a new PDF @@ -59,18 +72,26 @@ String.prototype.capitalize = function() { }; // A way to get the GET parameters, setting them in an array called $._GET +// url can be a string or a URL object (e.g. window.location) +function parseUrlIntoDict(url) { + if (url === '') return {}; + const a = new URL(url).search.substr(1).split('&'); + const b = {}; + for (let i = 0; i < a.length; ++i) + { + const p = a[i].split('='); + if (p.length !== 2) continue; + b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, ' ')); + } + return b; +} + +function parseUrlIntoGET(url) { + $._GET = parseUrlIntoDict(url); +} + (function ($) { - $._GET = (function(a) { - if (a === '') return {}; - const b = {}; - for (let i = 0; i < a.length; ++i) - { - const p = a[i].split('='); - if (p.length !== 2) continue; - b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, ' ')); - } - return b; - })(window.location.search.substr(1).split('&')); + $._GET = parseUrlIntoDict(window.location); })(jQuery); // Parse the GET attributes, locking out fields as needed @@ -975,14 +996,13 @@ function generateStandardDecklist(parsedInput) { return dl; } -function generatePermalink() { - console.log("generatePermalink"); +function generatePermalink(includeBlank = false) { rv = 'https://decklist.org/?'; const params = ['firstname', 'lastname', 'dcinumber', 'event', 'eventdate', 'eventlocation', 'deckmain', 'deckside', 'deckname', 'deckdesigner']; params.forEach(function(param) { const field = '#' + param; - if ($(field).val().length > 0) + if (includeBlank || $(field).val().length > 0) rv += param + '=' + encodeURIComponent($(field).val()) + '&'; }) @@ -1013,8 +1033,14 @@ function generateDecklistPDF(outputtype = 'dataurlstring') { if (outputtype === 'dataurlstring') { const domdl = dl.output('dataurlstring'); + // If we set the 'src' attr while the iframe is still part of the DOM, we generate + // a spurious history event. + var iframe = $('iframe'); + var container = iframe.parent(); + iframe.remove(); // Put the DOM into the live preview iframe - $('iframe').attr('src', domdl); + iframe.attr('src', domdl); + container.append(iframe); } else if (outputtype === 'raw') { const rawPDF = dl.output();