1/** 2 * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> 3 * @license GNU General Public License version 2 or later; see LICENSE.txt 4 */ 5window.customElements.define('joomla-hidden-mail', class extends HTMLElement { 6 constructor() { 7 super(); 8 this.newElement = ''; 9 this.base = ''; 10 } 11 12 /** 13 * Lifecycle 14 */ 15 disconnectedCallback() { 16 this.innerHTML = ''; 17 } 18 19 /** 20 * Lifecycle 21 */ 22 connectedCallback() { 23 this.base = `${this.getAttribute('base')}/`; 24 if (this.getAttribute('is-link') === '1') { 25 this.newElement = document.createElement('a'); 26 this.newElement.setAttribute('href', `mailto:${this.constructor.b64DecodeUnicode(this.getAttribute('first'))}@${this.constructor.b64DecodeUnicode(this.getAttribute('last'))}`); 27 28 // Get all of the original element attributes, and pass them to the link 29 [].slice.call(this.attributes).forEach((attribute, index) => { 30 const { 31 nodeName 32 } = this.attributes.item(index); 33 if (nodeName) { 34 // We do care for some attributes 35 if (['is-link', 'is-email', 'first', 'last', 'text'].indexOf(nodeName) === -1) { 36 const { 37 nodeValue 38 } = this.attributes.item(index); 39 this.newElement.setAttribute(nodeName, nodeValue); 40 } 41 } 42 }); 43 } else { 44 this.newElement = document.createElement('span'); 45 } 46 if (this.getAttribute('text')) { 47 let innerStr = this.constructor.b64DecodeUnicode(this.getAttribute('text')); 48 innerStr = innerStr.replace('src="images/', `src="${this.base}images/`).replace('src="media/', `src="${this.base}media/`); 49 this.newElement.innerHTML = Joomla.sanitizeHtml(innerStr); 50 } else { 51 this.newElement.innerText = `${window.atob(this.getAttribute('first'))}@${window.atob(this.getAttribute('last'))}`; 52 } 53 54 // Remove class and style Attributes 55 this.removeAttribute('class'); 56 this.removeAttribute('style'); 57 58 // Remove the noscript message 59 this.innerText = ''; 60 61 // Display the new element 62 this.appendChild(this.newElement); 63 } 64 static b64DecodeUnicode(str) { 65 return decodeURIComponent(Array.prototype.map.call(atob(str), c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`).join('')); 66 } 67});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.