{"version":3,"file":"./modules/feedback.bundle.js","mappings":"iMAEqBA,EAAQ,WACzB,SAAAA,EAAYC,IAAWC,EAAAA,EAAAA,GAAA,KAAAF,GACnBG,KAAKF,UAAYA,EAGjBE,KAAKC,aAAe,CAChBC,QAAS,IACTC,SAAU,IACVC,SAAU,KAGdJ,KAAKK,QAAU,IACnB,CAoOC,OApOAC,EAAAA,EAAAA,GAAAT,EAAA,EAAAU,IAAA,OAAAC,MAED,WACIR,KAAKS,eACLT,KAAKU,mBACT,GAAC,CAAAH,IAAA,eAAAC,MAED,WACI,OAAQR,KAAKW,cACT,KAAKX,KAAKC,aAAaC,QAEnBF,KAAKF,UAAUc,iBAAiB,UAAUC,SAAQ,SAAAC,GAC9CA,EAAOC,gBAAgB,WAC3B,IACA,MACJ,KAAKf,KAAKC,aAAaE,SAEnBH,KAAKF,UAAUkB,cAAc,mBAAmBC,UAAUC,IAAI,YAC9DlB,KAAKF,UAAUkB,cAAc,mBAAmBC,UAAUE,OAAO,YACjEnB,KAAKF,UAAUc,iBAAiB,UAAUC,SAAQ,SAAAC,GAC9CA,EAAOM,aAAa,WAAY,WACpC,IACA,MACJ,KAAKpB,KAAKC,aAAaG,SAEnBJ,KAAKF,UAAUkB,cAAc,4BAA4BC,UAAUC,IAAI,YACvElB,KAAKF,UAAUkB,cAAc,mBAAmBC,UAAUE,OAAO,YACjEnB,KAAKF,UAAUc,iBAAiB,UAAUC,SAAQ,SAAAC,GAC9CA,EAAOM,aAAa,WAAY,WACpC,IAGZ,GAAC,CAAAb,IAAA,oBAAAC,MAED,WAAoB,IAAAa,EAAA,KAChBrB,KAAKF,UAAUc,iBAAiB,mBAAmBC,SAAQ,SAAAC,GACvDA,EAAOQ,iBAAiB,SAAS,SAAAC,GAC7BA,EAAEC,iBACGV,EAAOW,aAAa,cACjBX,EAAOY,QAAQC,QAAUN,EAAKpB,aAAaE,SAC3CkB,EAAKO,KAAK,YACHd,EAAOY,QAAQC,QAAUN,EAAKpB,aAAaG,UAClDiB,EAAKQ,cAGjB,GACJ,IAEA,IAAMC,EAAa9B,KAAKF,UAAUkB,cAAc,yBAC5Cc,GACAA,EAAWR,iBAAiB,SAAS,SAAAC,GACjCA,EAAEC,iBACFH,EAAKO,KAAK,WACd,IAGJG,SAASC,KAAKV,iBAAiB,gBAAgB,WAC3CD,EAAKZ,cACT,GACJ,GAAC,CAAAF,IAAA,OAAAC,MAED,SAAKmB,GACD,IAAIM,GAAQ,EACRC,EAAe,KACfC,GAAU,EACRC,EAAcpC,KAAKF,UAAUkB,cAAc,YAC3CqB,EAAWD,EAAYpB,cAAc,YA6B3C,IA5Be,IAAXW,GAA6B,YAAVA,GAAwBA,GAAU3B,KAAKC,aAAaE,UACvEH,KAAKsC,UAAUtC,KAAKC,aAAaE,UACjC8B,GAAQ,EACRC,EAAe,WACXG,IACAF,GAAU,GAGVC,GACAA,EAAYhB,aAAa,gBAAiB,WAE5B,IAAXO,GAA8B,YAAVA,GAAwBA,GAAU3B,KAAKC,aAAaG,WAC/EJ,KAAKsC,UAAUtC,KAAKC,aAAaG,UACjC6B,GAAQ,EACRC,EAAe,WACXG,IACAA,EAASjB,aAAa,YAAY,GAE9BiB,EAAS7B,MAAM+B,OAAOC,SACtBL,EAAUE,EAAS7B,MAAM+B,SAI7BH,GACAA,EAAYhB,aAAa,gBAAiB,UAI9Ca,EAAO,CACP,IAAIQ,EAAQ,IAAIC,YAAY,eAAgB,CACxCC,OAAQT,IAGZH,SAASC,KAAKY,cAAcH,GAE5B,IAAMI,EAAQ7C,KAAKF,UAAUkB,cAAc,UACrC8B,EAAUD,EAAM7B,cAAc,YAC9B+B,EAAQF,EAAM7B,cAAc,UAC5BgC,EAASH,EAAM7B,cAAc,WACV6B,EAAM7B,cAAc,qBAE5BI,aAAa,gBAAiB,SAC/C0B,EAAQ1B,aAAa,gBAAiB,QAEtC6B,IAAIC,IAAIC,aACJC,OAAOC,SAASC,SAChBpB,EACAC,GACFoB,MAAK,WACCP,GACAA,EAAO5B,aAAa,gBAAiB,OAE7C,IAAE,OAAO,WACL2B,EAAM3B,aAAa,gBAAiB,OACxC,IAAE,SAAS,WACP0B,EAAQ1B,aAAa,gBAAiB,QAC1C,GACJ,CACJ,GAEA,CAAAb,IAAA,cAAAC,MACA,WACI,IACMgD,EADQxD,KAAKF,UAAUkB,cAAc,UACZA,cAAc,qBAEvCyC,EAAmBzD,KAAKF,UAAUkB,cAAc,YAClDyC,IACAD,EAAiBpC,aAAa,gBAAiB,QAC/CqC,EAAiBrC,aAAa,gBAAiB,QAE/CqC,EAAiBzC,cAAc,YAAY0C,QAEnD,GAAC,CAAAnD,IAAA,YAAAC,MAED,SAAUmB,GACN,IAAIgC,EAAM3D,KAAK4D,UAAUR,OAAOC,SAASC,UAErCO,EAAa,YAAHC,OAAeH,GAC7BI,IAAAA,IAAWF,EAAY,CACnBjC,KAAMD,EACNqC,MAAO,IAAIC,MAAQC,eACpB,CACCC,QAAS,KAEjB,GAAC,CAAA5D,IAAA,aAAAC,MAED,WAEI,IAAImD,EAAM3D,KAAK4D,UAAUR,OAAOC,SAASC,UAErCO,EAAa,YAAHC,OAAeH,GACzBS,EAASL,IAAAA,IAAWF,GAKxB,GAJIO,IACAA,EAASC,KAAKC,MAAMP,IAAAA,IAAWF,KAG9BO,EAEE,IAAIA,EAAOxC,KAAM,CAIpB,IAAI2C,EAAWxC,SAASf,cAAc,0CACtC,IAAKuD,EACD,OAAOH,EAAOxC,KAGlB,IAAI4C,EAAexE,KAAKyE,WAAWF,EAASG,SACxCC,EAAa,IAAIV,KAAKG,EAAOJ,MAEjC,OAAIQ,GAAgBG,GAAcH,EAAeG,EACtC3E,KAAKC,aAAaC,QAGtBkE,EAAOxC,IAClB,CAEI,OAAO5B,KAAKC,aAAaC,OAC7B,CArBI,OAAOF,KAAKC,aAAaC,OAsBjC,GAAC,CAAAK,IAAA,YAAAC,MAED,SAAUmD,GAUN,OARwB,IADxBA,EAAMA,EAAIiB,QAAQ,MAAO,KAAKC,eACtBC,QAAQ,OACZnB,EAAMA,EAAIoB,OAAO,EAAGpB,EAAInB,OAAS,IAGV,KAAvBmB,EAAIA,EAAInB,OAAS,KACjBmB,EAAMA,EAAIoB,OAAO,EAAGpB,EAAInB,OAAS,IAG9BmB,CACX,GAEA,CAAApD,IAAA,aAAAC,MAKA,SAAWwE,GACP,IAAIhB,EAAOgB,EAASC,MAAM,KAAK,GAC3BC,EAAOF,EAASC,MAAM,KAAK,GAE3BE,EAAInB,EAAKiB,MAAM,KAAK,GACpBG,EAAIpB,EAAKiB,MAAM,KAAK,GACpBI,EAAIrB,EAAKiB,MAAM,KAAK,GACpBK,EAAIJ,EAAKD,MAAM,KAAK,GACpBM,EAAIL,EAAKD,MAAM,KAAK,GACpBO,EAAIN,EAAKD,MAAM,KAAK,GAExB,OAAO,IAAIhB,KAAK,GAADH,OAAIuB,EAAC,KAAAvB,OAAIsB,EAAC,KAAAtB,OAAIqB,EAAC,KAAArB,OAAIwB,EAAC,KAAAxB,OAAIyB,EAAC,KAAAzB,OAAI0B,GAChD,GAAC,CAAAjF,IAAA,cAAAC,MAED,WACI,IAAImD,EAAM3D,KAAK4D,UAAUR,OAAOC,SAASC,UAErCO,EAAa,YAAHC,OAAeH,GACzBI,IAAAA,IAAWF,KACXE,IAAAA,OAAcF,GACd7D,KAAKS,eAEb,KAACZ,CAAA,CAhPwB,GCAR4F,EAAkB,WACnC,SAAAA,KAAc1F,EAAAA,EAAAA,GAAA,KAAA0F,GACXzF,KAAK0F,UAAY,GACjB1F,KAAK2F,SAAW,wBAEhB3F,KAAK4F,MACR,CAQC,OARAtF,EAAAA,EAAAA,GAAAmF,EAAA,EAAAlF,IAAA,OAAAC,MAED,WAAO,IAAAa,EAAA,KACHU,SAASnB,iBAAiBZ,KAAK2F,UAAU9E,SAAQ,SAAAf,GAC7C,IAAI+F,EAAW,IAAIhG,EAASC,GAC5BuB,EAAKqE,UAAUI,KAAKD,GACpBA,EAASD,MACb,GACJ,KAACH,CAAA,CAdkC,E","sources":["webpack://stl-2021/./scripts/controllers/feedback/Feedback.js","webpack://stl-2021/./scripts/controllers/feedback/controller.js"],"sourcesContent":["import Cookie from 'js-cookie';\r\n\r\nexport default class Feedback {\r\n constructor(container) {\r\n this.container = container;\r\n\r\n // Statuses\r\n this.voteStatuses = {\r\n unvoted: 'U',\r\n positive: 'P',\r\n negative: 'N',\r\n };\r\n\r\n this.apiCall = null;\r\n }\r\n\r\n init() {\r\n this.updateStatus();\r\n this.setEventListeners();\r\n }\r\n\r\n updateStatus() {\r\n switch (this.voteStatus()) {\r\n case this.voteStatuses.unvoted:\r\n // Enable both buttons\r\n this.container.querySelectorAll('button').forEach(button => {\r\n button.removeAttribute('disabled');\r\n });\r\n break;\r\n case this.voteStatuses.positive:\r\n // Mark positive, unmark negative\r\n this.container.querySelector('button.positive').classList.add('selected');\r\n this.container.querySelector('button.negative').classList.remove('selected');\r\n this.container.querySelectorAll('button').forEach(button => {\r\n button.setAttribute('disabled', 'disabled');\r\n });\r\n break;\r\n case this.voteStatuses.negative:\r\n // Mark negative, unmark positive\r\n this.container.querySelector('.options button.negative').classList.add('selected');\r\n this.container.querySelector('button.positive').classList.remove('selected');\r\n this.container.querySelectorAll('button').forEach(button => {\r\n button.setAttribute('disabled', 'disabled');\r\n });\r\n break;\r\n }\r\n }\r\n\r\n setEventListeners() {\r\n this.container.querySelectorAll('.options button').forEach(button => {\r\n button.addEventListener('click', e => {\r\n e.preventDefault();\r\n if (!button.hasAttribute('disabled')) {\r\n if (button.dataset.choice == this.voteStatuses.positive) {\r\n this.vote('positive');\r\n } else if (button.dataset.choice == this.voteStatuses.negative) {\r\n this.askFeedback();\r\n }\r\n }\r\n });\r\n });\r\n\r\n const sendButton = this.container.querySelector('.comment .send button');\r\n if (sendButton) {\r\n sendButton.addEventListener('click', e => {\r\n e.preventDefault();\r\n this.vote('negative');\r\n });\r\n }\r\n\r\n document.body.addEventListener('feedbackVote', () => {\r\n this.updateStatus();\r\n });\r\n }\r\n\r\n vote(choice) {\r\n let voted = false;\r\n let selectedVote = null; // Is sent to API\r\n let comment = false;\r\n const commentArea = this.container.querySelector('.comment');\r\n const textarea = commentArea.querySelector('textarea');\r\n if (choice === true || choice == 'positive' || choice == this.voteStatuses.positive) {\r\n this.setCookie(this.voteStatuses.positive);\r\n voted = true;\r\n selectedVote = 'Positive';\r\n if (textarea) {\r\n comment = false;\r\n }\r\n\r\n if (commentArea) {\r\n commentArea.setAttribute('aria-expanded', 'false');\r\n }\r\n } else if (choice === false || choice == 'negative' || choice == this.voteStatuses.negative) {\r\n this.setCookie(this.voteStatuses.negative);\r\n voted = true;\r\n selectedVote = 'Negative';\r\n if (textarea) {\r\n textarea.setAttribute('disabled', true);\r\n\r\n if (textarea.value.trim().length) {\r\n comment = textarea.value.trim();\r\n }\r\n }\r\n\r\n if (commentArea) {\r\n commentArea.setAttribute('aria-expanded', 'false');\r\n }\r\n }\r\n\r\n if (voted) {\r\n let event = new CustomEvent('feedbackVote', {\r\n detail: selectedVote,\r\n });\r\n\r\n document.body.dispatchEvent(event);\r\n\r\n const texts = this.container.querySelector('.texts');\r\n const sending = texts.querySelector('.sending');\r\n const error = texts.querySelector('.error');\r\n const result = texts.querySelector('.result');\r\n const negativeFeedback = texts.querySelector('.negativeFeedback');\r\n\r\n negativeFeedback.setAttribute('aria-expanded', 'false');\r\n sending.setAttribute('aria-expanded', 'true');\r\n\r\n app.api.postFeedback(\r\n window.location.pathname,\r\n selectedVote,\r\n comment,\r\n ).then(() => {\r\n if (result) {\r\n result.setAttribute('aria-expanded', 'true');\r\n }\r\n }).catch(() => {\r\n error.setAttribute('aria-expanded', 'true');\r\n }).finally(() => {\r\n sending.setAttribute('aria-expanded', 'false');\r\n });\r\n }\r\n }\r\n\r\n // Triggered when user selected the negative option. Only send vote *after* the user pressed the send button for this.\r\n askFeedback() {\r\n const texts = this.container.querySelector('.texts');\r\n const negativeFeedback = texts.querySelector('.negativeFeedback');\r\n\r\n const commentContainer = this.container.querySelector('.comment');\r\n if (commentContainer) {\r\n negativeFeedback.setAttribute('aria-expanded', 'true');\r\n commentContainer.setAttribute('aria-expanded', 'true');\r\n\r\n commentContainer.querySelector('textarea').focus();\r\n }\r\n }\r\n\r\n setCookie(choice) {\r\n let url = this.formatUrl(window.location.pathname);\r\n \r\n let cookieName = `feedback_${url}`;\r\n Cookie.set(cookieName, {\r\n vote: choice,\r\n date: (new Date()).toISOString(),\r\n }, {\r\n expires: 365,\r\n });\r\n }\r\n\r\n voteStatus() {\r\n // Create string from url name, format accordingly\r\n let url = this.formatUrl(window.location.pathname);\r\n \r\n let cookieName = `feedback_${url}`;\r\n let cookie = Cookie.get(cookieName);\r\n if (cookie) {\r\n cookie = JSON.parse(Cookie.get(cookieName));\r\n }\r\n\r\n if (!cookie) {\r\n return this.voteStatuses.unvoted;\r\n } else if (cookie.vote) {\r\n // User is allowed to vote again if the page has been modified since voting\r\n\r\n // Try to find a modified datetime for the article\r\n let modified = document.querySelector(`meta[property=\"article:modified_time\"]`);\r\n if (!modified) {\r\n return cookie.vote;\r\n }\r\n\r\n let modifiedDate = this.formatDate(modified.content);\r\n let cookieDate = new Date(cookie.date);\r\n\r\n if (modifiedDate && cookieDate && modifiedDate > cookieDate) {\r\n return this.voteStatuses.unvoted;\r\n }\r\n\r\n return cookie.vote;\r\n } else {\r\n // Cookie's either broken or incorrectly set, assume unvoted\r\n return this.voteStatuses.unvoted;\r\n }\r\n }\r\n\r\n formatUrl(url) {\r\n url = url.replace(/\\//g, '_').toLowerCase();\r\n if (url.indexOf('_') == 0) {\r\n url = url.substr(1, url.length - 1);\r\n }\r\n\r\n if (url[url.length - 1] == '_') {\r\n url = url.substr(0, url.length - 1);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Are we really parsing a date manually? Yes we are\r\n * @param {String} datetime \r\n * @returns {Date}\r\n */\r\n formatDate(datetime) {\r\n let date = datetime.split(' ')[0];\r\n let time = datetime.split(' ')[1];\r\n\r\n let D = date.split('-')[0];\r\n let M = date.split('-')[1];\r\n let Y = date.split('-')[2];\r\n let h = time.split(':')[0];\r\n let m = time.split(':')[1];\r\n let s = time.split(':')[2];\r\n\r\n return new Date(`${Y}-${M}-${D} ${h}:${m}:${s}`);\r\n }\r\n\r\n clearCookie() {\r\n let url = this.formatUrl(window.location.pathname);\r\n \r\n let cookieName = `feedback_${url}`;\r\n if (Cookie.get(cookieName)) {\r\n Cookie.remove(cookieName);\r\n this.updateStatus();\r\n }\r\n }\r\n}","import Feedback from './Feedback';\r\n\r\nexport default class FeedbackController {\r\n constructor() {\r\n this.instances = [];\r\n this.selector = 'section.feedbackBlock';\r\n\r\n this.init();\r\n }\r\n\r\n init() {\r\n document.querySelectorAll(this.selector).forEach(container => {\r\n let feedback = new Feedback(container);\r\n this.instances.push(feedback);\r\n feedback.init();\r\n });\r\n }\r\n}"],"names":["Feedback","container","_classCallCheck","this","voteStatuses","unvoted","positive","negative","apiCall","_createClass","key","value","updateStatus","setEventListeners","voteStatus","querySelectorAll","forEach","button","removeAttribute","querySelector","classList","add","remove","setAttribute","_this","addEventListener","e","preventDefault","hasAttribute","dataset","choice","vote","askFeedback","sendButton","document","body","voted","selectedVote","comment","commentArea","textarea","setCookie","trim","length","event","CustomEvent","detail","dispatchEvent","texts","sending","error","result","app","api","postFeedback","window","location","pathname","then","negativeFeedback","commentContainer","focus","url","formatUrl","cookieName","concat","Cookie","date","Date","toISOString","expires","cookie","JSON","parse","modified","modifiedDate","formatDate","content","cookieDate","replace","toLowerCase","indexOf","substr","datetime","split","time","D","M","Y","h","m","s","FeedbackController","instances","selector","init","feedback","push"],"sourceRoot":""}