UNPKG

@honeybadger-io/js

Version:

Universal (Browser & Node) JavaScript error notifier for Honeybadger.io

302 lines (260 loc) 15.4 kB
(function (window, document) { // eslint-disable-next-line quotes const TEMPLATE = `<style> #honeybadger-feedback-wrapper { display: block; outline: none; position: fixed; z-index: 999; width: 100%; height: 100%; text-align: center; top: 0; left: 0; background: rgba(0, 0, 0, 0.6); overflow: auto; } #honeybadger-feedback { font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; padding: 1em 3em 1em 2em; max-width: 400px; max-height: 80%; margin: 4% auto 0; text-align: left; background: #1a202c; color: #9CA3AF; border-radius: 5px; } #honeybadger-feedback-name, #honeybadger-feedback-email, #honeybadger-feedback-comment { width: 100%; padding: 0.5em; } #honeybadger-feedback-comment { font-family: inherit; height: 10em; } #honeybadger-feedback-error { color: #cc0000; } #honeybadger-feedback-error-detail { font-size: small; } .honeybadger-feedback-button { color: initial; padding: 0.5em 1em; cursor: pointer; } .honeybadger-feedback-button.plain { text-decoration: underline; border: none; background: none; color: #9CA3AF; } #honeybadger-feedback-close { padding-left: 0; } #honeybadger-feedback-footer { text-align: right; } #honeybadger-feedback-footer img { vertical-align: middle; } #honeybadger-feedback-link { text-decoration: underline; color: #9CA3AF; } @media screen and (max-height: 570px) { #honeybadger-feedback { max-height: none; margin-top: 0; } } @media screen and (max-height: 660px) { #honeybadger-feedback { max-width: none; } } </style> <div id="honeybadger-feedback"> <h2 id="honeybadger-feedback-heading"> Care to help us fix this? </h2> <p id="honeybadger-feedback-explanation"> Any information you can provide will help our technical team get to the bottom of this issue. </p> <div id="honeybadger-feedback-thanks" style="display:none;"> <p><strong>Thanks for the feedback!</strong></p> <input type="button" class="honeybadger-feedback-button plain" id="honeybadger-feedback-close" value="Close"> </div> <form id="honeybadger-feedback-form"> <p> <label for="honeybadger-feedback-name" id="honeybadger-feedback-label-name"> Name </label><br> <input type="text" name="name" id="honeybadger-feedback-name"> </p> <p> <label for="honeybadger-feedback-email" id="honeybadger-feedback-label-email"> Your email address </label><br> <input type="email" name="email" id="honeybadger-feedback-email" value=""> </p> <p> <label for="honeybadger-feedback-comment" id="honeybadger-feedback-label-comment"> Comment (required) </label><br> <textarea name="comment" id="honeybadger-feedback-comment" cols="50" rows="6" required></textarea> </p> <p id="honeybadger-feedback-error" style="display: none"> There was an error. Please try again later. <br/> <span id="honeybadger-feedback-error-detail"></span> </p> <p> <input type="submit" class="honeybadger-feedback-button" id="honeybadger-feedback-submit" value="Send"> <input type="button" class="honeybadger-feedback-button plain" id="honeybadger-feedback-cancel" value="Cancel"> </p> </form> <p id="honeybadger-feedback-footer"> <a id="honeybadger-feedback-link" href="https://www.honeybadger.io/" target="_blank" title="Exception, uptime, and performance monitoring for PHP."> Powered by <svg class="honeybadger-logo" height="40" viewBox="0 0 190 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"> <style> #logoText { fill: var(--bs-brand); } [data-bs-theme=dark] #logoText { fill: white; } #logoBolt, #logoBorder { fill: var(--bs-brand); } [data-bs-theme=dark] #logoBolt { fill:url(#_Linear1);fill-rule:nonzero; } </style> <path id="logoText" d="M58.59,34.57L62.786,5.798L58.115,5.798L56.398,17.497L52.161,17.497L53.878,5.798L49.207,5.798L44.978,34.57L49.649,34.57L51.527,21.799L55.764,21.799L53.886,34.57L58.59,34.57ZM67.303,28.803C71.974,28.803 73.809,26.83 74.777,19.78C75.678,13.085 74.11,10.886 69.772,10.886C65.168,10.886 63.199,13.15 62.365,20.039C61.498,26.798 63.266,28.803 67.303,28.803ZM67.77,25.504C66.602,25.504 66.302,24.372 66.936,20.006C67.537,15.479 68.104,14.153 69.438,14.153C70.606,14.153 70.84,15.22 70.239,19.683C69.639,24.114 69.071,25.504 67.77,25.504ZM81.42,12.697C82.454,11.727 83.956,10.886 85.29,10.886C87.993,10.886 88.927,12.73 88.46,15.964L86.591,28.415L82.254,28.415L84.022,16.449C84.189,15.285 83.956,14.702 83.088,14.702C82.421,14.702 81.787,15.285 81.387,15.673L79.518,28.415L75.181,28.415L77.683,11.274L81.353,11.274L81.42,12.697ZM136.677,11.274L136.176,12.536C135.442,11.468 134.341,10.886 132.973,10.886C129.804,10.886 127.868,13.409 127.067,20.103C126.266,26.733 127.801,28.803 130.304,28.803C131.805,28.803 132.973,28.092 133.84,27.089L133.874,28.415L137.878,28.415L140.413,11.274L136.677,11.274ZM134.14,24.243C133.773,24.696 133.073,25.181 132.472,25.181C131.404,25.181 131.071,24.178 131.638,20.006C132.238,15.576 132.873,14.541 133.94,14.541C134.574,14.541 135.108,14.993 135.408,15.479L134.14,24.243ZM154.727,5.798L151.39,28.415L147.42,28.415L147.386,27.089C146.519,28.124 145.318,28.803 143.85,28.803C141.347,28.803 139.779,26.733 140.614,20.103C141.414,13.409 143.316,10.886 146.519,10.886C147.754,10.886 148.721,11.404 149.422,12.212L150.391,5.798L154.727,5.798ZM145.185,20.006C144.584,24.178 144.951,25.181 146.019,25.181C146.586,25.181 147.32,24.696 147.687,24.243L148.955,15.479C148.655,14.993 148.087,14.541 147.487,14.541C146.419,14.541 145.786,15.576 145.185,20.006ZM107.145,34.563L158.879,34.563C161.976,34.563 164.601,32.283 165.035,29.215L167.572,11.274L163.835,11.274L163.435,12.568C162.768,11.63 161.633,10.886 160.399,10.886C157.029,10.886 155.194,12.73 154.259,19.909C153.359,26.442 154.827,28.447 157.463,28.447C158.797,28.447 160.032,27.865 160.866,26.895L160.733,28.124C160.375,29.66 158.797,30.879 156.204,30.879L109.231,30.879C108.618,32.327 108.021,33.499 107.315,34.363C107.259,34.431 107.203,34.498 107.145,34.563ZM159.698,24.89C158.63,24.89 158.23,23.952 158.797,19.877C159.365,15.608 160.032,14.541 161.132,14.541C161.733,14.541 162.267,14.993 162.567,15.446L161.333,23.952C160.965,24.405 160.265,24.89 159.698,24.89ZM177.647,27.283C175.88,28.318 174.044,28.803 172.443,28.803C168.706,28.803 167.004,25.569 167.738,20.071C168.606,13.473 171.075,10.886 175.312,10.886C177.948,10.886 179.583,12.245 179.583,14.638C179.583,17.839 177.782,21.332 171.909,22.4C171.909,22.575 171.919,22.703 171.928,22.82C171.935,22.918 171.942,23.008 171.942,23.111C171.975,24.437 172.676,25.148 173.844,25.148C174.645,25.148 175.579,24.89 176.914,24.275L177.647,27.283ZM174.812,14.088C173.778,14.088 172.843,15.64 172.276,19.068C174.745,18.745 175.679,16.772 175.679,15.349C175.679,14.573 175.412,14.088 174.812,14.088ZM183.133,28.415L184.901,16.675C185.769,15.899 186.736,15.479 187.703,15.479C187.971,15.479 188.204,15.479 188.471,15.511L189.339,11.339C188.871,11.016 188.471,10.886 187.971,10.886C186.703,10.886 185.602,11.889 184.801,13.312L184.734,11.274L181.331,11.274L178.795,28.415L183.133,28.415ZM99.105,27.283C97.337,28.318 95.502,28.803 93.9,28.803C90.164,28.803 88.462,25.569 89.196,20.071C90.064,13.473 92.532,10.886 96.77,10.886C99.406,10.886 101.04,12.245 101.04,14.638C101.04,17.839 99.239,21.332 93.367,22.4C93.367,22.576 93.376,22.704 93.385,22.82C93.393,22.918 93.4,23.008 93.4,23.111C93.433,24.437 94.134,25.148 95.302,25.148C96.103,25.148 97.037,24.89 98.372,24.275L99.105,27.283ZM96.269,14.088C95.235,14.088 94.301,15.64 93.734,19.068C96.203,18.745 97.137,16.772 97.137,15.349C97.137,14.573 96.87,14.088 96.269,14.088ZM119.965,28.803C123.769,28.803 125.237,25.795 126.038,18.777C126.805,12.503 125.571,10.886 122.935,10.886C121.601,10.886 120.432,11.436 119.398,12.245L120.266,6.273L115.93,6.273L112.692,28.415L116.629,28.415L117.029,27.121C117.597,28.059 118.631,28.803 119.965,28.803ZM119.131,25.181C118.531,25.181 117.897,24.857 117.63,24.243L118.931,15.446C119.431,14.929 120.098,14.541 120.733,14.541C121.734,14.541 121.934,15.543 121.5,18.939C121.1,22.982 120.432,25.181 119.131,25.181ZM105.859,23.758L109.629,11.274L114.1,11.274L107.427,28.609C105.592,33.331 104.558,34.564 101.656,34.564L60.91,34.564L61.451,30.879L96.923,30.878L100.944,30.878C102.286,30.878 103.023,29.947 103.023,28.738L101.522,11.274L106.226,11.274L105.859,23.758Z"/> <path id="logoBorder" d="M28.229,12.072L36.157,20L20,36.157L18.241,34.399L15.854,36.786L18.408,39.341C19.287,40.22 20.713,40.22 21.592,39.341L39.341,21.592C40.22,20.713 40.22,19.287 39.341,18.408L29.651,8.719L28.229,12.072ZM27.934,7.002L26.512,10.355L23.521,7.364L25.909,4.977L27.934,7.002ZM24.317,3.385L21.592,0.659C20.713,-0.22 19.287,-0.22 18.408,0.659L0.659,18.408C-0.22,19.287 -0.22,20.713 0.659,21.592L11.063,31.995L12.587,28.744L3.843,20L20,3.843L21.93,5.772L24.317,3.385ZM12.755,33.688L14.279,30.437L16.65,32.807L14.262,35.195L12.755,33.688Z"/> <g> <path id="logoBolt" d="M29.788,2.63C30.029,2.061 29.309,1.575 28.872,2.013L9.533,21.352L17.411,21.352L11.142,36.785C10.911,37.353 11.627,37.829 12.061,37.395L30.918,18.538L23.039,18.538L29.788,2.63Z"/> </g> <defs> <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.18719e-15,35.7195,-35.7195,2.18719e-15,20.2253,1.84375)"><stop offset="0" style="stop-color:white;stop-opacity:1"/><stop offset="0.46" style="stop-color:rgb(255,204,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(255,113,67);stop-opacity:1"/></linearGradient> </defs> </svg> </a> </p> </div> ` const OPTIONS_KEY = 'honeybadgerUserFeedbackOptions' const HoneybadgerUserFeedbackForm = function () {}; HoneybadgerUserFeedbackForm.prototype.build = function () { const self = this self.element = document.createElement('div') self.element.id = 'honeybadger-feedback-wrapper' self.element.innerHTML = TEMPLATE self.element.onclick = function (e) { if (e.target !== self.element) return; self.close(); } document.body.appendChild(self.element) self.form = self.element.getElementsByTagName('form')[0] self.form.addEventListener('submit', function (e) { e.preventDefault() self.submit() }) const cancelButton = document.getElementById('honeybadger-feedback-cancel') cancelButton.onclick = (e) => { e.preventDefault() self.close() } const closeButton = document.getElementById('honeybadger-feedback-close') closeButton.onclick = (e) => { e.preventDefault() self.close() } self.applyLabelsFromOptions() }; HoneybadgerUserFeedbackForm.prototype.applyLabelsFromOptions = function () { const self = this const formOptions = self.getOptions() const { messages = {}, buttons = {}, labels = {} } = formOptions for (let key in messages) { const element = document.getElementById(`honeybadger-feedback-${key}`) if (element) { element.innerText = messages[key] } } for (let key in labels) { const element = document.getElementById(`honeybadger-feedback-label-${key}`) if (element) { element.innerText = labels[key] } } for (let key in buttons) { const element = document.getElementById(`honeybadger-feedback-${key}`) if (element) { element.value = buttons[key] } } }; HoneybadgerUserFeedbackForm.prototype.close = function () { const self = this self.element.parentNode.removeChild(self.element); }; HoneybadgerUserFeedbackForm.prototype.submit = function () { const self = this if (self.loading) return self.loading = true document.getElementById('honeybadger-feedback-error').style.display = 'none' document.getElementById('honeybadger-feedback-submit').disabled = true const script = document.createElement('script') const form = document.getElementById('honeybadger-feedback-form') script.src = self.getEndpoint() + '?format=js' + `&api_key=${self.getApiKey()}` + `&token=${self.getLastNoticeId()}` + `&name=${encodeURIComponent(self.form.name.value)}` + `&email=${encodeURIComponent(self.form.email.value)}` + `&comment=${encodeURIComponent(self.form.comment.value)}` script.onerror = function () { self.loading = false // unfortunately we don't get any info here about the error (i.e. HTTP 403) self.onFormError('') // remove script so that user can try again form.removeChild(script) } form.appendChild(script); }; HoneybadgerUserFeedbackForm.prototype.onSuccess = function () { document.getElementById('honeybadger-feedback-thanks').style.display = 'block' document.getElementById('honeybadger-feedback-form').style.display = 'none' document.getElementById('honeybadger-feedback-submit').disabled = false }; HoneybadgerUserFeedbackForm.prototype.onFormError = function (message) { document.getElementById('honeybadger-feedback-error').style.display = 'block' document.getElementById('honeybadger-feedback-error-detail').innerText = message document.getElementById('honeybadger-feedback-submit').disabled = false }; HoneybadgerUserFeedbackForm.prototype.getOptions = function () { return window[OPTIONS_KEY] } HoneybadgerUserFeedbackForm.prototype.getApiKey = function () { return this.getOptions().apiKey } HoneybadgerUserFeedbackForm.prototype.getLastNoticeId = function () { return this.getOptions().noticeId } HoneybadgerUserFeedbackForm.prototype.getEndpoint = function () { return this.getOptions().endpoint } const form = new HoneybadgerUserFeedbackForm() form.build() // this function needs to be defined and will be called from the feedback script submission // eslint-disable-next-line @typescript-eslint/no-unused-vars window['honeybadgerFeedbackResponse'] = function honeybadgerFeedbackResponse(data) { form.loading = false if (data['result'] === 'OK') { form.onSuccess() return } form.onFormError(data['error'] || 'An unknown error occurred.') } })(window, document)