var app = new Vue({ el: '#app', data: { urlParams: {}, book: {} }, methods: { urlParse: function() { var match, pl = /\+/g, // Regex for replacing addition symbol with a space search = /([^&=]+)=?([^&]*)/g, decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, query = window.location.search.substring(1); while (match = search.exec(query)) this.urlParams[decode(match[1])] = decode(match[2]); }, sendQuery: function(url, error, success) { var xmh = new XMLHttpRequest(); var v; xmh.onreadystatechange = function() { v = xmh.responseText; if (xmh.readyState === 4 && xmh.status === 200) { var res; try { res = JSON.parse(v); } catch (err) { if (null !== error) error(err.name, err.message); } if (null !== success) success(res); } else if (xmh.readyState === 4) { if (null !== error) error(xmh.status, v); } }; xmh.open('GET', url, true); xmh.send(null); }, stdError: function(code, resp) { console.log('ERROR ' + code + ': ' + resp); }, formatBytes: function(bytes) { if(bytes == 0) return '0'; var k = 1024; // or 1024 for binary var sizes = ['Octets', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'Yo']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }, bookCover: function(book) { return '/calibre/' + encodeURI(book.path) + '/cover.jpg'; }, bookLink: function(book, data) { return '/calibre/' + encodeURI(book.path) + '/' + encodeURI(data.name) + '.' + data.format.toLowerCase(); }, bookSuccess: function(resp) { this.book = resp; document.title = this.book.title +' | Bouquins'; }, loadBook: function() { if (this.urlParams.id) this.sendQuery('cgi-bin/bouquins/books/' + this.urlParams.id, this.stdError, this.bookSuccess); } }, created: function() { this.urlParse(); }, mounted: function() { this.loadBook(); } })