From 02bd0288f23bb0e80a94a4a5058733f6ee28f7d5 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 28 Aug 2020 14:27:14 -0400 Subject: [PATCH] Do not check session unless already logged in --- frontEndSrc/js/events.js | 42 --------------------------------- frontEndSrc/js/index.js | 1 + frontEndSrc/js/session-check.js | 41 ++++++++++++++++++++++++++++++++ public/es/anon.js | 42 --------------------------------- public/es/scripts.js | 20 +++++++--------- public/js/anon.min.js | 5 ++-- public/js/anon.min.js.map | 2 +- public/js/scripts.min.js | 31 ++++++++++++------------ public/js/scripts.min.js.map | 2 +- 9 files changed, 71 insertions(+), 115 deletions(-) create mode 100644 frontEndSrc/js/session-check.js diff --git a/frontEndSrc/js/events.js b/frontEndSrc/js/events.js index d24239ec..2a8adfab 100644 --- a/frontEndSrc/js/events.js +++ b/frontEndSrc/js/events.js @@ -108,45 +108,3 @@ function filterMedia (event) { _.show('table.media-wrap tbody tr'); } } - -// ---------------------------------------------------------------------------- -// Other event setup -// ---------------------------------------------------------------------------- -(() => { - // Var is intentional - var hidden = null; - var visibilityChange = null; - - if (typeof document.hidden !== "undefined") { - hidden = "hidden"; - visibilityChange = "visibilitychange"; - } else if (typeof document.msHidden !== "undefined") { - hidden = "msHidden"; - visibilityChange = "msvisibilitychange"; - } else if (typeof document.webkitHidden !== "undefined") { - hidden = "webkitHidden"; - visibilityChange = "webkitvisibilitychange"; - } - - function handleVisibilityChange() { - // Check the user's session to see if they are currently logged-in - // when the page becomes visible - if ( ! document[hidden]) { - _.get('/heartbeat', (beat) => { - const status = JSON.parse(beat) - - // If the session is expired, immediately reload so that - // you can't attempt to do an action that requires authentication - if (status.hasAuth !== true) { - location.reload(); - } - }); - } - } - - if (hidden === null) { - console.info('Page visibility API not supported, JS session check will not work'); - } else { - document.addEventListener(visibilityChange, handleVisibilityChange, false); - } -})(); diff --git a/frontEndSrc/js/index.js b/frontEndSrc/js/index.js index 6cad73e4..9fd34d36 100644 --- a/frontEndSrc/js/index.js +++ b/frontEndSrc/js/index.js @@ -1,4 +1,5 @@ import './anon.js'; +import './session-check.js'; import './anime.js'; import './manga.js'; diff --git a/frontEndSrc/js/session-check.js b/frontEndSrc/js/session-check.js new file mode 100644 index 00000000..6777ed5e --- /dev/null +++ b/frontEndSrc/js/session-check.js @@ -0,0 +1,41 @@ +import _ from './anime-client.js'; + +(() => { + // Var is intentional + var hidden = null; + var visibilityChange = null; + + if (typeof document.hidden !== "undefined") { + hidden = "hidden"; + visibilityChange = "visibilitychange"; + } else if (typeof document.msHidden !== "undefined") { + hidden = "msHidden"; + visibilityChange = "msvisibilitychange"; + } else if (typeof document.webkitHidden !== "undefined") { + hidden = "webkitHidden"; + visibilityChange = "webkitvisibilitychange"; + } + + function handleVisibilityChange() { + // Check the user's session to see if they are currently logged-in + // when the page becomes visible + if ( ! document[hidden]) { + _.get('/heartbeat', (beat) => { + const status = JSON.parse(beat) + + // If the session is expired, immediately reload so that + // you can't attempt to do an action that requires authentication + if (status.hasAuth !== true) { + document.removeEventListener(visibilityChange, handleVisibilityChange, false); + location.reload(); + } + }); + } + } + + if (hidden === null) { + console.info('Page visibility API not supported, JS session check will not work'); + } else { + document.addEventListener(visibilityChange, handleVisibilityChange, false); + } +})(); \ No newline at end of file diff --git a/public/es/anon.js b/public/es/anon.js index 4e6ae6f5..2a208588 100644 --- a/public/es/anon.js +++ b/public/es/anon.js @@ -454,48 +454,6 @@ function filterMedia (event) { } } -// ---------------------------------------------------------------------------- -// Other event setup -// ---------------------------------------------------------------------------- -(() => { - // Var is intentional - var hidden = null; - var visibilityChange = null; - - if (typeof document.hidden !== "undefined") { - hidden = "hidden"; - visibilityChange = "visibilitychange"; - } else if (typeof document.msHidden !== "undefined") { - hidden = "msHidden"; - visibilityChange = "msvisibilitychange"; - } else if (typeof document.webkitHidden !== "undefined") { - hidden = "webkitHidden"; - visibilityChange = "webkitvisibilitychange"; - } - - function handleVisibilityChange() { - // Check the user's session to see if they are currently logged-in - // when the page becomes visible - if ( ! document[hidden]) { - AnimeClient.get('/heartbeat', (beat) => { - const status = JSON.parse(beat); - - // If the session is expired, immediately reload so that - // you can't attempt to do an action that requires authentication - if (status.hasAuth !== true) { - location.reload(); - } - }); - } - } - - if (hidden === null) { - console.info('Page visibility API not supported, JS session check will not work'); - } else { - document.addEventListener(visibilityChange, handleVisibilityChange, false); - } -})(); - if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(reg => { console.log('Service worker registered', reg.scope); diff --git a/public/es/scripts.js b/public/es/scripts.js index 96ea1f5f..2d2cbd5a 100644 --- a/public/es/scripts.js +++ b/public/es/scripts.js @@ -454,9 +454,14 @@ function filterMedia (event) { } } -// ---------------------------------------------------------------------------- -// Other event setup -// ---------------------------------------------------------------------------- +if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('/sw.js').then(reg => { + console.log('Service worker registered', reg.scope); + }).catch(error => { + console.error('Failed to register service worker', error); + }); +} + (() => { // Var is intentional var hidden = null; @@ -483,6 +488,7 @@ function filterMedia (event) { // If the session is expired, immediately reload so that // you can't attempt to do an action that requires authentication if (status.hasAuth !== true) { + document.removeEventListener(visibilityChange, handleVisibilityChange, false); location.reload(); } }); @@ -496,14 +502,6 @@ function filterMedia (event) { } })(); -if ('serviceWorker' in navigator) { - navigator.serviceWorker.register('/sw.js').then(reg => { - console.log('Service worker registered', reg.scope); - }).catch(error => { - console.error('Failed to register service worker', error); - }); -} - // Click on hidden MAL checkbox so // that MAL id is passed AnimeClient.on('main', 'change', '.big-check', (e) => { diff --git a/public/js/anon.min.js b/public/js/anon.min.js index 2cb4064d..d20e8d77 100644 --- a/public/js/anon.min.js +++ b/public/js/anon.min.js @@ -9,7 +9,6 @@ element){listener.call(element,e);e.stopPropagation()}})})}AnimeClient.on=functi "GET")request.send(null);else request.send(config.data);return request};AnimeClient.get=function(url,data,callback){callback=callback===undefined?null:callback;if(callback===null){callback=data;data={}}return AnimeClient.ajax(url,{data:data,success:callback})};AnimeClient.on("header","click",".message",hide);AnimeClient.on("form.js-delete","submit",confirmDelete);AnimeClient.on(".js-clear-cache","click",clearAPICache);AnimeClient.on(".vertical-tabs input","change",scrollToSection);AnimeClient.on(".media-filter", "input",filterMedia);function hide(event){AnimeClient.hide(event.target)}function confirmDelete(event){var proceed=confirm("Are you ABSOLUTELY SURE you want to delete this item?");if(proceed===false){event.preventDefault();event.stopPropagation()}}function clearAPICache(){AnimeClient.get("/cache_purge",function(){AnimeClient.showMessage("success","Successfully purged api cache")})}function scrollToSection(event){var el=event.currentTarget.parentElement;var rect=el.getBoundingClientRect();var top= rect.top+window.pageYOffset;window.scrollTo({top:top,behavior:"smooth"})}function filterMedia(event){var rawFilter=event.target.value;var filter=new RegExp(rawFilter,"i");if(rawFilter!==""){AnimeClient.$("article.media").forEach(function(article){var titleLink=AnimeClient.$(".name a",article)[0];var title=String(titleLink.textContent).trim();if(!filter.test(title))AnimeClient.hide(article);else AnimeClient.show(article)});AnimeClient.$("table.media-wrap tbody tr").forEach(function(tr){var titleCell= -AnimeClient.$("td.align-left",tr)[0];var titleLink=AnimeClient.$("a",titleCell)[0];var linkTitle=String(titleLink.textContent).trim();var textTitle=String(titleCell.textContent).trim();if(!(filter.test(linkTitle)||filter.test(textTitle)))AnimeClient.hide(tr);else AnimeClient.show(tr)})}else{AnimeClient.show("article.media");AnimeClient.show("table.media-wrap tbody tr")}}(function(){var hidden=null;var visibilityChange=null;if(typeof document.hidden!=="undefined"){hidden="hidden";visibilityChange= -"visibilitychange"}else if(typeof document.msHidden!=="undefined"){hidden="msHidden";visibilityChange="msvisibilitychange"}else if(typeof document.webkitHidden!=="undefined"){hidden="webkitHidden";visibilityChange="webkitvisibilitychange"}function handleVisibilityChange(){if(!document[hidden])AnimeClient.get("/heartbeat",function(beat){var status=JSON.parse(beat);if(status.hasAuth!==true)location.reload()})}if(hidden===null)console.info("Page visibility API not supported, JS session check will not work"); -else document.addEventListener(visibilityChange,handleVisibilityChange,false)})();if("serviceWorker"in navigator)navigator.serviceWorker.register("/sw.js").then(function(reg){console.log("Service worker registered",reg.scope)})["catch"](function(error){console.error("Failed to register service worker",error)})})() +AnimeClient.$("td.align-left",tr)[0];var titleLink=AnimeClient.$("a",titleCell)[0];var linkTitle=String(titleLink.textContent).trim();var textTitle=String(titleCell.textContent).trim();if(!(filter.test(linkTitle)||filter.test(textTitle)))AnimeClient.hide(tr);else AnimeClient.show(tr)})}else{AnimeClient.show("article.media");AnimeClient.show("table.media-wrap tbody tr")}}if("serviceWorker"in navigator)navigator.serviceWorker.register("/sw.js").then(function(reg){console.log("Service worker registered", +reg.scope)})["catch"](function(error){console.error("Failed to register service worker",error)})})() //# sourceMappingURL=anon.min.js.map diff --git a/public/js/anon.min.js.map b/public/js/anon.min.js.map index 1f7188a7..96a93182 100644 --- a/public/js/anon.min.js.map +++ b/public/js/anon.min.js.map @@ -1 +1 @@ -{"version":3,"file":"anon.min.js.map","sources":["../../frontEndSrc/js/anime-client.js","../../frontEndSrc/js/events.js","../../frontEndSrc/js/anon.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n\n// ----------------------------------------------------------------------------\n// Other event setup\n// ----------------------------------------------------------------------------\n(() => {\n\t// Var is intentional\n\tvar hidden = null;\n\tvar visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();\n","import './events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n"],"names":["selector","m","querySelectorAll","elm","document","ownerDocument","i","matches","length","item","noop","$","context","nodeType","elements","match","push","getElementById","split","slice","apply","hasElement","AnimeClient","scrollToTop","el","scrollIntoView","hide","sel","Array","isArray","forEach","setAttribute","show","removeAttribute","showMessage","type","message","template","undefined","remove","insertAdjacentHTML","closestParent","current","parentSelector","Element","prototype","closest","documentElement","parentElement","url","path","uri","location","host","charAt","throttle","interval","fn","scope","wait","args","setTimeout","addEvent","event","listener","evt","addEventListener","delegateEvent","target","e","element","call","stopPropagation","on","AnimeClient.on","ajaxSerialize","data","pairs","Object","keys","name","value","toString","encodeURIComponent","join","ajax","AnimeClient.ajax","config","dataType","success","mimeType","error","defaultConfig","request","XMLHttpRequest","method","String","toUpperCase","open","onreadystatechange","request.onreadystatechange","readyState","responseText","responseType","JSON","parse","status","response","stringify","setRequestHeader","send","get","AnimeClient.get","callback","confirmDelete","clearAPICache","scrollToSection","filterMedia","_","proceed","preventDefault","window","scrollTo","top","behavior","rawFilter","article","filter","test","title","tr","titleCell","linkTitle","textTitle","hidden","visibilityChange","msHidden","webkitHidden","handleVisibilityChange","beat","hasAuth","reload","console","info","navigator","serviceWorker","register","then","reg","log","catch"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"anon.min.js.map","sources":["../../frontEndSrc/js/anime-client.js","../../frontEndSrc/js/events.js","../../frontEndSrc/js/anon.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n","import './events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n"],"names":["selector","m","querySelectorAll","elm","document","ownerDocument","i","matches","length","item","noop","$","context","nodeType","elements","match","push","getElementById","split","slice","apply","hasElement","AnimeClient","scrollToTop","el","scrollIntoView","hide","sel","Array","isArray","forEach","setAttribute","show","removeAttribute","showMessage","type","message","template","undefined","remove","insertAdjacentHTML","closestParent","current","parentSelector","Element","prototype","closest","documentElement","parentElement","url","path","uri","location","host","charAt","throttle","interval","fn","scope","wait","args","setTimeout","addEvent","event","listener","evt","addEventListener","delegateEvent","target","e","element","call","stopPropagation","on","AnimeClient.on","ajaxSerialize","data","pairs","Object","keys","name","value","toString","encodeURIComponent","join","ajax","AnimeClient.ajax","config","dataType","success","mimeType","error","defaultConfig","request","XMLHttpRequest","method","String","toUpperCase","open","onreadystatechange","request.onreadystatechange","readyState","responseText","responseType","JSON","parse","status","response","stringify","setRequestHeader","send","get","AnimeClient.get","callback","confirmDelete","clearAPICache","scrollToSection","filterMedia","_","proceed","preventDefault","window","scrollTo","top","behavior","rawFilter","article","filter","test","title","tr","titleCell","linkTitle","textTitle","navigator","serviceWorker","register","then","reg","console","log","catch"],"mappings":"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"} \ No newline at end of file diff --git a/public/js/scripts.min.js b/public/js/scripts.min.js index f2316f8e..d0f36ccc 100644 --- a/public/js/scripts.min.js +++ b/public/js/scripts.min.js @@ -9,19 +9,20 @@ element){listener.call(element,e);e.stopPropagation()}})})}AnimeClient.on=functi "GET")request.send(null);else request.send(config.data);return request};AnimeClient.get=function(url,data,callback){callback=callback===undefined?null:callback;if(callback===null){callback=data;data={}}return AnimeClient.ajax(url,{data:data,success:callback})};AnimeClient.on("header","click",".message",hide);AnimeClient.on("form.js-delete","submit",confirmDelete);AnimeClient.on(".js-clear-cache","click",clearAPICache);AnimeClient.on(".vertical-tabs input","change",scrollToSection);AnimeClient.on(".media-filter", "input",filterMedia);function hide(event){AnimeClient.hide(event.target)}function confirmDelete(event){var proceed=confirm("Are you ABSOLUTELY SURE you want to delete this item?");if(proceed===false){event.preventDefault();event.stopPropagation()}}function clearAPICache(){AnimeClient.get("/cache_purge",function(){AnimeClient.showMessage("success","Successfully purged api cache")})}function scrollToSection(event){var el=event.currentTarget.parentElement;var rect=el.getBoundingClientRect();var top= rect.top+window.pageYOffset;window.scrollTo({top:top,behavior:"smooth"})}function filterMedia(event){var rawFilter=event.target.value;var filter=new RegExp(rawFilter,"i");if(rawFilter!==""){AnimeClient.$("article.media").forEach(function(article){var titleLink=AnimeClient.$(".name a",article)[0];var title=String(titleLink.textContent).trim();if(!filter.test(title))AnimeClient.hide(article);else AnimeClient.show(article)});AnimeClient.$("table.media-wrap tbody tr").forEach(function(tr){var titleCell= -AnimeClient.$("td.align-left",tr)[0];var titleLink=AnimeClient.$("a",titleCell)[0];var linkTitle=String(titleLink.textContent).trim();var textTitle=String(titleCell.textContent).trim();if(!(filter.test(linkTitle)||filter.test(textTitle)))AnimeClient.hide(tr);else AnimeClient.show(tr)})}else{AnimeClient.show("article.media");AnimeClient.show("table.media-wrap tbody tr")}}(function(){var hidden=null;var visibilityChange=null;if(typeof document.hidden!=="undefined"){hidden="hidden";visibilityChange= -"visibilitychange"}else if(typeof document.msHidden!=="undefined"){hidden="msHidden";visibilityChange="msvisibilitychange"}else if(typeof document.webkitHidden!=="undefined"){hidden="webkitHidden";visibilityChange="webkitvisibilitychange"}function handleVisibilityChange(){if(!document[hidden])AnimeClient.get("/heartbeat",function(beat){var status=JSON.parse(beat);if(status.hasAuth!==true)location.reload()})}if(hidden===null)console.info("Page visibility API not supported, JS session check will not work"); -else document.addEventListener(visibilityChange,handleVisibilityChange,false)})();if("serviceWorker"in navigator)navigator.serviceWorker.register("/sw.js").then(function(reg){console.log("Service worker registered",reg.scope)})["catch"](function(error){console.error("Failed to register service worker",error)});AnimeClient.on("main","change",".big-check",function(e){var id=e.target.id;document.getElementById("mal_"+id).checked=true});function renderAnimeSearchResults(data){var results=[];data.forEach(function(x){var item= -x.attributes;var titles=item.titles.join("
");results.push('\n\t\t\t\n\t\t')}); -return results.join("")}function renderMangaSearchResults(data){var results=[];data.forEach(function(x){var item=x.attributes;var titles=item.titles.join("
");results.push('\n\t\t\t\n\t\t')});return results.join("")}var search=function(query){AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderAnimeSearchResults(searchResults.data)})};if(AnimeClient.hasElement(".anime #search")){var prevRequest= -null;AnimeClient.on("#search","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query)}))}AnimeClient.on("body.anime.list","click",".plus-one",function(e){var parentSel=AnimeClient.closestParent(e.target,"article");var watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;var totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent, -10);var title=AnimeClient.$(".name a",parentSel)[0].textContent;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,data:{progress:watchedCount+1}};if(isNaN(watchedCount)||watchedCount===0)data.data.status="current";if(!isNaN(watchedCount)&&watchedCount+1===totalCount)data.data.status="completed";AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data:data,dataType:"json",type:"POST",success:function(res){var resData=JSON.parse(res);if(resData.errors){AnimeClient.hide("#loading-shadow"); -AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop();return}if(resData.data.status==="COMPLETED")AnimeClient.hide(parentSel);AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("success","Successfully updated "+title);AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;AnimeClient.scrollToTop()},error:function(){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop()}})}); -var search$1=function(query){AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/manga/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderMangaSearchResults(searchResults.data)})};if(AnimeClient.hasElement(".manga #search")){var prevRequest$1=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value); -if(query==="")return;if(prevRequest$1!==null)prevRequest$1.abort();prevRequest$1=search$1(query)}))}AnimeClient.on(".manga.list","click",".edit-buttons button",function(e){var thisSel=e.target;var parentSel=AnimeClient.closestParent(e.target,"article");var type=thisSel.classList.contains("plus-one-chapter")?"chapter":"volume";var completed=parseInt(AnimeClient.$("."+type+"s_read",parentSel)[0].textContent,10)||0;var total=parseInt(AnimeClient.$("."+type+"_count",parentSel)[0].textContent,10);var mangaName= -AnimeClient.$(".name",parentSel)[0].textContent;if(isNaN(completed))completed=0;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,data:{progress:completed}};if(isNaN(completed)||completed===0)data.data.status="current";if(!isNaN(completed)&&completed+1===total)data.data.status="completed";data.data.progress=++completed;AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data:data,dataType:"json",type:"POST",mimeType:"application/json",success:function(){if(data.data.status=== -"completed")AnimeClient.hide(parentSel);AnimeClient.hide("#loading-shadow");AnimeClient.$("."+type+"s_read",parentSel)[0].textContent=completed;AnimeClient.showMessage("success","Successfully updated "+mangaName);AnimeClient.scrollToTop()},error:function(){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+mangaName);AnimeClient.scrollToTop()}})})})() +AnimeClient.$("td.align-left",tr)[0];var titleLink=AnimeClient.$("a",titleCell)[0];var linkTitle=String(titleLink.textContent).trim();var textTitle=String(titleCell.textContent).trim();if(!(filter.test(linkTitle)||filter.test(textTitle)))AnimeClient.hide(tr);else AnimeClient.show(tr)})}else{AnimeClient.show("article.media");AnimeClient.show("table.media-wrap tbody tr")}}if("serviceWorker"in navigator)navigator.serviceWorker.register("/sw.js").then(function(reg){console.log("Service worker registered", +reg.scope)})["catch"](function(error){console.error("Failed to register service worker",error)});(function(){var hidden=null;var visibilityChange=null;if(typeof document.hidden!=="undefined"){hidden="hidden";visibilityChange="visibilitychange"}else if(typeof document.msHidden!=="undefined"){hidden="msHidden";visibilityChange="msvisibilitychange"}else if(typeof document.webkitHidden!=="undefined"){hidden="webkitHidden";visibilityChange="webkitvisibilitychange"}function handleVisibilityChange(){if(!document[hidden])AnimeClient.get("/heartbeat", +function(beat){var status=JSON.parse(beat);if(status.hasAuth!==true){document.removeEventListener(visibilityChange,handleVisibilityChange,false);location.reload()}})}if(hidden===null)console.info("Page visibility API not supported, JS session check will not work");else document.addEventListener(visibilityChange,handleVisibilityChange,false)})();AnimeClient.on("main","change",".big-check",function(e){var id=e.target.id;document.getElementById("mal_"+id).checked=true});function renderAnimeSearchResults(data){var results= +[];data.forEach(function(x){var item=x.attributes;var titles=item.titles.join("
");results.push('\n\t\t\t\n\t\t')});return results.join("")}function renderMangaSearchResults(data){var results=[];data.forEach(function(x){var item=x.attributes;var titles=item.titles.join("
");results.push('\n\t\t\t\n\t\t')});return results.join("")}var search=function(query){AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query:query},function(searchResults, +status){searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderAnimeSearchResults(searchResults.data)})};if(AnimeClient.hasElement(".anime #search")){var prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query)}))}AnimeClient.on("body.anime.list","click",".plus-one", +function(e){var parentSel=AnimeClient.closestParent(e.target,"article");var watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;var totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent,10);var title=AnimeClient.$(".name a",parentSel)[0].textContent;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,data:{progress:watchedCount+1}};if(isNaN(watchedCount)||watchedCount===0)data.data.status="current";if(!isNaN(watchedCount)&& +watchedCount+1===totalCount)data.data.status="completed";AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data:data,dataType:"json",type:"POST",success:function(res){var resData=JSON.parse(res);if(resData.errors){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop();return}if(resData.data.status==="COMPLETED")AnimeClient.hide(parentSel);AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("success", +"Successfully updated "+title);AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;AnimeClient.scrollToTop()},error:function(){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop()}})});var search$1=function(query){AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/manga/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader"); +AnimeClient.$("#series-list")[0].innerHTML=renderMangaSearchResults(searchResults.data)})};if(AnimeClient.hasElement(".manga #search")){var prevRequest$1=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest$1!==null)prevRequest$1.abort();prevRequest$1=search$1(query)}))}AnimeClient.on(".manga.list","click",".edit-buttons button",function(e){var thisSel=e.target;var parentSel=AnimeClient.closestParent(e.target, +"article");var type=thisSel.classList.contains("plus-one-chapter")?"chapter":"volume";var completed=parseInt(AnimeClient.$("."+type+"s_read",parentSel)[0].textContent,10)||0;var total=parseInt(AnimeClient.$("."+type+"_count",parentSel)[0].textContent,10);var mangaName=AnimeClient.$(".name",parentSel)[0].textContent;if(isNaN(completed))completed=0;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,data:{progress:completed}};if(isNaN(completed)||completed===0)data.data.status="current"; +if(!isNaN(completed)&&completed+1===total)data.data.status="completed";data.data.progress=++completed;AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data:data,dataType:"json",type:"POST",mimeType:"application/json",success:function(){if(data.data.status==="completed")AnimeClient.hide(parentSel);AnimeClient.hide("#loading-shadow");AnimeClient.$("."+type+"s_read",parentSel)[0].textContent=completed;AnimeClient.showMessage("success","Successfully updated "+ +mangaName);AnimeClient.scrollToTop()},error:function(){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+mangaName);AnimeClient.scrollToTop()}})})})() //# sourceMappingURL=scripts.min.js.map diff --git a/public/js/scripts.min.js.map b/public/js/scripts.min.js.map index ca06159e..64720c50 100644 --- a/public/js/scripts.min.js.map +++ b/public/js/scripts.min.js.map @@ -1 +1 @@ -{"version":3,"file":"scripts.min.js.map","sources":["../../frontEndSrc/js/anime-client.js","../../frontEndSrc/js/events.js","../../frontEndSrc/js/anon.js","../../frontEndSrc/js/template-helpers.js","../../frontEndSrc/js/anime.js","../../frontEndSrc/js/manga.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n\n// ----------------------------------------------------------------------------\n// Other event setup\n// ----------------------------------------------------------------------------\n(() => {\n\t// Var is intentional\n\tvar hidden = null;\n\tvar visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();\n","import './events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n","import _ from './anime-client.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n});\n\nexport function renderAnimeSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.join('
');\n\n\t\tresults.push(`\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`);\n\t});\n\n\treturn results.join('');\n}\n\nexport function renderMangaSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.join('
');\n\n\t\tresults.push(`\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`);\n\t});\n\n\treturn results.join('');\n}","import _ from './anime-client.js'\nimport { renderAnimeSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t// Show the loader\n\t_.show('.cssload-loader');\n\n\t// Do the api search\n\treturn _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.hide('.cssload-loader');\n\n\t\t// Show the results\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.anime #search')) {\n\tlet prevRequest = null;\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus-one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t_.show('#loading-shadow');\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\tconst resData = JSON.parse(res);\n\n\t\t\tif (resData.errors) {\n\t\t\t\t_.hide('#loading-shadow');\n\t\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t\t_.scrollToTop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (resData.data.status === 'COMPLETED') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide('#loading-shadow');\n\n\t\t\t_.showMessage('success', `Successfully updated ${title}`);\n\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide('#loading-shadow');\n\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});","import _ from './anime-client.js'\nimport { renderMangaSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t_.show('.cssload-loader');\n\treturn _.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.hide('.cssload-loader');\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\tlet prevRequest = null\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit-buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet mangaName = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show('#loading-shadow');\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: () => {\n\t\t\tif (data.data.status === 'completed') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide('#loading-shadow');\n\n\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = completed;\n\t\t\t_.showMessage('success', `Successfully updated ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide('#loading-shadow');\n\t\t\t_.showMessage('error', `Failed to update ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});"],"names":["selector","m","querySelectorAll","elm","document","ownerDocument","i","matches","length","item","noop","$","context","nodeType","elements","match","push","getElementById","split","slice","apply","hasElement","AnimeClient","scrollToTop","el","scrollIntoView","hide","sel","Array","isArray","forEach","setAttribute","show","removeAttribute","showMessage","type","message","template","undefined","remove","insertAdjacentHTML","closestParent","current","parentSelector","Element","prototype","closest","documentElement","parentElement","url","path","uri","location","host","charAt","throttle","interval","fn","scope","wait","args","setTimeout","addEvent","event","listener","evt","addEventListener","delegateEvent","target","e","element","call","stopPropagation","on","AnimeClient.on","ajaxSerialize","data","pairs","Object","keys","name","value","toString","encodeURIComponent","join","ajax","AnimeClient.ajax","config","dataType","success","mimeType","error","defaultConfig","request","XMLHttpRequest","method","String","toUpperCase","open","onreadystatechange","request.onreadystatechange","readyState","responseText","responseType","JSON","parse","status","response","stringify","setRequestHeader","send","get","AnimeClient.get","callback","confirmDelete","clearAPICache","scrollToSection","filterMedia","_","proceed","preventDefault","window","scrollTo","top","behavior","rawFilter","article","filter","test","title","tr","titleCell","linkTitle","textTitle","hidden","visibilityChange","msHidden","webkitHidden","handleVisibilityChange","beat","hasAuth","reload","console","info","navigator","serviceWorker","register","then","reg","log","catch","id","checked","renderAnimeSearchResults","x","results","slug","mal_id","canonicalTitle","titles","renderMangaSearchResults","query","searchResults","prevRequest","abort","search","parentSel","watchedCount","parseInt","totalCount","dataset","kitsuId","malId","progress","isNaN","res","resData","errors","thisSel","classList","contains","completed","total","mangaName"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"scripts.min.js.map","sources":["../../frontEndSrc/js/anime-client.js","../../frontEndSrc/js/events.js","../../frontEndSrc/js/anon.js","../../frontEndSrc/js/session-check.js","../../frontEndSrc/js/template-helpers.js","../../frontEndSrc/js/anime.js","../../frontEndSrc/js/manga.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n","import './events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n","import _ from './anime-client.js';\n\n(() => {\n\t// Var is intentional\n\tvar hidden = null;\n\tvar visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tdocument.removeEventListener(visibilityChange, handleVisibilityChange, false);\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();","import _ from './anime-client.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n});\n\nexport function renderAnimeSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.join('
');\n\n\t\tresults.push(`\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`);\n\t});\n\n\treturn results.join('');\n}\n\nexport function renderMangaSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.join('
');\n\n\t\tresults.push(`\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`);\n\t});\n\n\treturn results.join('');\n}","import _ from './anime-client.js'\nimport { renderAnimeSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t// Show the loader\n\t_.show('.cssload-loader');\n\n\t// Do the api search\n\treturn _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.hide('.cssload-loader');\n\n\t\t// Show the results\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.anime #search')) {\n\tlet prevRequest = null;\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus-one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t_.show('#loading-shadow');\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\tconst resData = JSON.parse(res);\n\n\t\t\tif (resData.errors) {\n\t\t\t\t_.hide('#loading-shadow');\n\t\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t\t_.scrollToTop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (resData.data.status === 'COMPLETED') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide('#loading-shadow');\n\n\t\t\t_.showMessage('success', `Successfully updated ${title}`);\n\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide('#loading-shadow');\n\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});","import _ from './anime-client.js'\nimport { renderMangaSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t_.show('.cssload-loader');\n\treturn _.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.hide('.cssload-loader');\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\tlet prevRequest = null\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit-buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet mangaName = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show('#loading-shadow');\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: () => {\n\t\t\tif (data.data.status === 'completed') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide('#loading-shadow');\n\n\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = completed;\n\t\t\t_.showMessage('success', `Successfully updated ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide('#loading-shadow');\n\t\t\t_.showMessage('error', `Failed to update ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});"],"names":["selector","m","querySelectorAll","elm","document","ownerDocument","i","matches","length","item","noop","$","context","nodeType","elements","match","push","getElementById","split","slice","apply","hasElement","AnimeClient","scrollToTop","el","scrollIntoView","hide","sel","Array","isArray","forEach","setAttribute","show","removeAttribute","showMessage","type","message","template","undefined","remove","insertAdjacentHTML","closestParent","current","parentSelector","Element","prototype","closest","documentElement","parentElement","url","path","uri","location","host","charAt","throttle","interval","fn","scope","wait","args","setTimeout","addEvent","event","listener","evt","addEventListener","delegateEvent","target","e","element","call","stopPropagation","on","AnimeClient.on","ajaxSerialize","data","pairs","Object","keys","name","value","toString","encodeURIComponent","join","ajax","AnimeClient.ajax","config","dataType","success","mimeType","error","defaultConfig","request","XMLHttpRequest","method","String","toUpperCase","open","onreadystatechange","request.onreadystatechange","readyState","responseText","responseType","JSON","parse","status","response","stringify","setRequestHeader","send","get","AnimeClient.get","callback","confirmDelete","clearAPICache","scrollToSection","filterMedia","_","proceed","preventDefault","window","scrollTo","top","behavior","rawFilter","article","filter","test","title","tr","titleCell","linkTitle","textTitle","navigator","serviceWorker","register","then","reg","console","log","catch","hidden","visibilityChange","msHidden","webkitHidden","handleVisibilityChange","beat","hasAuth","removeEventListener","reload","info","id","checked","renderAnimeSearchResults","x","results","slug","mal_id","canonicalTitle","titles","renderMangaSearchResults","query","searchResults","prevRequest","abort","search","parentSel","watchedCount","parseInt","totalCount","dataset","kitsuId","malId","progress","isNaN","res","resData","errors","thisSel","classList","contains","completed","total","mangaName"],"mappings":"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"} \ No newline at end of file