Fix URL not replaced with link node (fixes #258), beautify text via regex without rendering it, and fix execution order
This commit is contained in:
		
							parent
							
								
									76e08927de
								
							
						
					
					
						commit
						99b0c6ff01
					
				|  | @ -2035,12 +2035,22 @@ class ReceiveTextDialog extends Dialog { | ||||||
|         window.blop.play(); |         window.blop.play(); | ||||||
|         this._receiveTextQueue.push({text: text, peerId: peerId}); |         this._receiveTextQueue.push({text: text, peerId: peerId}); | ||||||
|         this._setDocumentTitleMessages(); |         this._setDocumentTitleMessages(); | ||||||
|  |         changeFavicon("images/favicon-96x96-notification.png"); | ||||||
|  | 
 | ||||||
|         if (this.isShown()) return; |         if (this.isShown()) return; | ||||||
|  | 
 | ||||||
|         this._dequeueRequests(); |         this._dequeueRequests(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     _dequeueRequests() { |     _dequeueRequests() { | ||||||
|         if (!this._receiveTextQueue.length) return; |         if (!this._receiveTextQueue.length) { | ||||||
|  |             this.$text.innerHTML = ""; | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this._setDocumentTitleMessages(); | ||||||
|  |         changeFavicon("images/favicon-96x96-notification.png"); | ||||||
|  | 
 | ||||||
|         let {text, peerId} = this._receiveTextQueue.shift(); |         let {text, peerId} = this._receiveTextQueue.shift(); | ||||||
|         this._showReceiveTextDialog(text, peerId); |         this._showReceiveTextDialog(text, peerId); | ||||||
|     } |     } | ||||||
|  | @ -2051,41 +2061,68 @@ class ReceiveTextDialog extends Dialog { | ||||||
|         this.$displayName.classList.add($(peerId).ui._badgeClassName()); |         this.$displayName.classList.add($(peerId).ui._badgeClassName()); | ||||||
| 
 | 
 | ||||||
|         this.$text.innerText = text; |         this.$text.innerText = text; | ||||||
|         this.$text.classList.remove('text-center'); |  | ||||||
| 
 | 
 | ||||||
|         // Beautify text if text is short
 |         // Beautify text if text is not too long
 | ||||||
|         if (text.length < 2000) { |         if (this.$text.innerText.length <= 300000) { | ||||||
|             // replace URLs with actual links
 |             // Hacky workaround to replace URLs with link nodes in all cases
 | ||||||
|             this.$text.innerHTML = this.$text.innerHTML |             // 1. Use text variable, find all valid URLs via regex and replace URLs with placeholder
 | ||||||
|                 .replace(/(^|<br>|\s|")((https?:\/\/|www.)(([a-z]|[A-Z]|[0-9]|[\-_~:\/?#\[\]@!$&'()*+,;=%]){2,}\.)(([a-z]|[A-Z]|[0-9]|[\-_~:\/?#\[\]@!$&'()*+,;=%.]){2,}))/g, |             // 2. Use html variable, find placeholders with regex and replace them with link nodes
 | ||||||
|                 (match, whitespace, url) => { | 
 | ||||||
|  |             let $textShadow = document.createElement('div'); | ||||||
|  |             $textShadow.innerText = text; | ||||||
|  | 
 | ||||||
|  |             let linkNodes = {}; | ||||||
|  |             let searchHTML = $textShadow.innerHTML; | ||||||
|  |             const p = "@"; | ||||||
|  |             const pRgx = new RegExp(`${p}\\d+`, 'g'); | ||||||
|  |             let occP = searchHTML.match(pRgx) || []; | ||||||
|  | 
 | ||||||
|  |             let m = 0; | ||||||
|  | 
 | ||||||
|  |             const allowedDomainChars = "a-zA-Z0-9áàäčçđéèêŋńñóòôöšŧüžæøåëìíîïðùúýþćěłřśţźǎǐǒǔǥǧǩǯəʒâûœÿãõāēīōūăąĉċďĕėęĝğġģĥħĩĭįıĵķĸĺļľņňŏőŕŗŝşťũŭůűųŵŷżאבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ"; | ||||||
|  |             const urlRgx = new RegExp(`(^|\\n|\\s|["><\\-_~:\\/?#\\[\\]@!$&'()*+,;=%.])(((https?:\\/\\/)?(?:[${allowedDomainChars}](?:[${allowedDomainChars}-]{0,61}[${allowedDomainChars}])?\\.)+[${allowedDomainChars}][${allowedDomainChars}-]{0,61}[${allowedDomainChars}])(:?\\d*)\\/?([${allowedDomainChars}_\\/\\-#.]*)(\\?([${allowedDomainChars}\\-_~:\\/?#\\[\\]@!$&'()*+,;=%.]*))?)`, 'g'); | ||||||
|  | 
 | ||||||
|  |             $textShadow.innerText = text.replace(urlRgx, | ||||||
|  |                 (match, whitespaceOrSpecial, url, g3, scheme) => { | ||||||
|                     let link = url; |                     let link = url; | ||||||
| 
 | 
 | ||||||
|                     // prefix www.example.com with http protocol to prevent it from being a relative link
 |                     // prefix www.example.com with http protocol to prevent it from being a relative link
 | ||||||
|                         if (link.startsWith('www')) { |                     if (!scheme && link.startsWith('www')) { | ||||||
|                         link = "http://" + link |                         link = "http://" + link | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                         // Check if link is valid
 |  | ||||||
|                     if (isUrlValid(link)) { |                     if (isUrlValid(link)) { | ||||||
|                             return `${whitespace}<a href="${link}" target="_blank">${url}</a>`; |                         // link is valid -> replace with link node placeholder
 | ||||||
|  | 
 | ||||||
|  |                         // find linkNodePlaceholder that is not yet present in text node
 | ||||||
|  |                         m++; | ||||||
|  |                         while (occP.includes(`${p}${m}`)) { | ||||||
|  |                             m++; | ||||||
|                         } |                         } | ||||||
|                         else { |                         let linkNodePlaceholder = `${p}${m}`; | ||||||
|  | 
 | ||||||
|  |                         // add linkNodePlaceholder to text node and save a reference to linkNodes object
 | ||||||
|  |                         linkNodes[linkNodePlaceholder] = `<a href="${link}" target="_blank">${url}</a>`; | ||||||
|  |                         return `${whitespaceOrSpecial}${linkNodePlaceholder}`; | ||||||
|  |                     } | ||||||
|  |                     // link is not valid -> do not replace
 | ||||||
|                     return match; |                     return match; | ||||||
|                         } |                 }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             this.$text.innerHTML = $textShadow.innerHTML.replace(pRgx, | ||||||
|  |                 (m) => { | ||||||
|  |                     let urlNode = linkNodes[m]; | ||||||
|  |                     return urlNode ? urlNode : m; | ||||||
|                 }); |                 }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this._evaluateOverflowing(this.$text); |         this._evaluateOverflowing(this.$text); | ||||||
| 
 |  | ||||||
|         this._setDocumentTitleMessages(); |  | ||||||
| 
 |  | ||||||
|         changeFavicon("images/favicon-96x96-notification.png"); |  | ||||||
|         this.show(); |         this.show(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     _setDocumentTitleMessages() { |     _setDocumentTitleMessages() { | ||||||
|         document.title = !this._receiveTextQueue.length |         document.title = this._receiveTextQueue.length <= 1 | ||||||
|             ? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop` |             ? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop` | ||||||
|             : `${ Localization.getTranslation("document-titles.message-received-plural", null, {count: this._receiveTextQueue.length + 1}) } - PairDrop`; |             : `${ Localization.getTranslation("document-titles.message-received-plural", null, {count: this._receiveTextQueue.length + 1}) } - PairDrop`; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 schlagmichdoch
						schlagmichdoch