2018-10-28 06:02:57 +01:00
|
|
|
import { Component, OnInit, Input, EventEmitter, Output, Renderer2, ViewChild, ElementRef } from '@angular/core';
|
2018-10-28 04:58:00 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-databinded-text',
|
|
|
|
templateUrl: './databinded-text.component.html',
|
|
|
|
styleUrls: ['./databinded-text.component.scss']
|
|
|
|
})
|
|
|
|
export class DatabindedTextComponent implements OnInit {
|
|
|
|
private accounts: string[] = [];
|
2018-10-28 05:45:32 +01:00
|
|
|
private hashtags: string[] = [];
|
2018-10-28 20:03:57 +01:00
|
|
|
private links: string[] = [];
|
2018-10-28 04:58:00 +01:00
|
|
|
|
|
|
|
processedText: string;
|
|
|
|
|
2018-10-28 06:02:57 +01:00
|
|
|
@ViewChild('content') contentElement: ElementRef;
|
|
|
|
|
2018-10-28 04:58:00 +01:00
|
|
|
@Output() accountSelected = new EventEmitter<string>();
|
|
|
|
@Output() hashtagSelected = new EventEmitter<string>();
|
|
|
|
@Output() textSelected = new EventEmitter();
|
|
|
|
|
2018-11-01 04:47:38 +01:00
|
|
|
@Input() textIsSelectable: boolean = true;
|
|
|
|
|
2018-10-28 04:58:00 +01:00
|
|
|
@Input('text')
|
2018-10-28 05:45:32 +01:00
|
|
|
set text(value: string) {
|
2018-10-28 06:02:57 +01:00
|
|
|
this.processedText = '';
|
|
|
|
let linksSections = value.split('<a ');
|
2018-10-28 05:45:32 +01:00
|
|
|
|
|
|
|
for (let section of linksSections) {
|
|
|
|
if (!section.includes('href')) {
|
|
|
|
this.processedText += section;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
if (section.includes('class="mention hashtag"') || section.includes('target="_blank">#')) {
|
2018-10-30 04:56:00 +01:00
|
|
|
try {
|
|
|
|
this.processHashtag(section);
|
|
|
|
}
|
|
|
|
catch (err) {
|
|
|
|
console.warn('process hashtag');
|
|
|
|
console.warn(value);
|
|
|
|
}
|
|
|
|
|
2018-10-31 04:27:20 +01:00
|
|
|
} else if (section.includes('class="u-url mention"') || section.includes('class="mention"') || section.includes('class="mention status-link"')) {
|
2018-10-30 04:56:00 +01:00
|
|
|
try {
|
|
|
|
this.processUser(section);
|
|
|
|
}
|
|
|
|
catch (err) {
|
|
|
|
console.warn('process mention');
|
|
|
|
console.warn(value);
|
|
|
|
}
|
2018-10-28 20:03:57 +01:00
|
|
|
} else {
|
2018-10-30 04:56:00 +01:00
|
|
|
try {
|
|
|
|
this.processLink(section);
|
|
|
|
}
|
|
|
|
catch (err) {
|
|
|
|
console.warn('process link');
|
|
|
|
console.warn(value);
|
|
|
|
}
|
2018-10-28 20:03:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-28 05:45:32 +01:00
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
private processHashtag(section: string) {
|
|
|
|
let extractedLinkAndNext = section.split('</a>');
|
|
|
|
let extractedHashtag = extractedLinkAndNext[0].split('#')[1].replace('<span>', '').replace('</span>', '');
|
2018-10-28 05:45:32 +01:00
|
|
|
|
2018-11-01 23:38:59 +01:00
|
|
|
let classname = this.getClassNameForHastag(extractedHashtag);
|
|
|
|
this.processedText += ` <a href class="${classname}">#${extractedHashtag}</a>`;
|
2018-10-28 20:03:57 +01:00
|
|
|
if (extractedLinkAndNext[1]) this.processedText += extractedLinkAndNext[1];
|
|
|
|
this.hashtags.push(extractedHashtag);
|
|
|
|
}
|
2018-10-28 05:45:32 +01:00
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
private processUser(section: string) {
|
2018-10-31 04:27:20 +01:00
|
|
|
// let mentionClass = 'class="mention"';
|
|
|
|
// if (section.includes('class="u-url mention"'))
|
|
|
|
// mentionClass = 'class="u-url mention"';
|
2018-10-28 05:45:32 +01:00
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
let extractedAccountAndNext = section.split('</a></span>');
|
2018-10-28 05:45:32 +01:00
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
let extractedAccountName = extractedAccountAndNext[0].split('@<span>')[1].replace('<span>', '').replace('</span>', '');
|
|
|
|
|
|
|
|
let extractedAccountLink = extractedAccountAndNext[0].split('href="https://')[1].split('"')[0].replace(' ', '').replace('@', '').split('/');
|
2018-10-31 04:27:20 +01:00
|
|
|
|
|
|
|
let domain = extractedAccountLink[0];
|
|
|
|
let username = extractedAccountLink[extractedAccountLink.length - 1];
|
|
|
|
|
|
|
|
let extractedAccount = `@${username}@${domain}`;
|
2018-10-28 20:03:57 +01:00
|
|
|
|
|
|
|
let classname = this.getClassNameForAccount(extractedAccount);
|
|
|
|
this.processedText += ` <a href class="${classname}" title="${extractedAccount}">@${extractedAccountName}</a>`;
|
|
|
|
|
|
|
|
if (extractedAccountAndNext[1]) this.processedText += extractedAccountAndNext[1];
|
|
|
|
this.accounts.push(extractedAccount);
|
|
|
|
}
|
|
|
|
|
|
|
|
private processLink(section: string) {
|
|
|
|
let extractedLinkAndNext = section.split('</a>')
|
|
|
|
let extractedUrl = extractedLinkAndNext[0].split('"')[1];
|
|
|
|
|
|
|
|
let extractedName = '';
|
|
|
|
try {
|
|
|
|
extractedName = extractedLinkAndNext[0].split('<span class="ellipsis">')[1].split('</span>')[0];
|
2018-10-30 04:56:00 +01:00
|
|
|
} catch (err) {
|
2018-10-28 20:03:57 +01:00
|
|
|
try {
|
2018-10-30 04:56:00 +01:00
|
|
|
extractedName = extractedLinkAndNext[0].split('<span class="invisible">https://</span><span class="">')[1].split('</span>')[0];
|
2018-10-28 05:45:32 +01:00
|
|
|
}
|
2018-10-30 04:56:00 +01:00
|
|
|
catch (err) {
|
|
|
|
extractedName = extractedLinkAndNext[0].split(' target="_blank">')[1].split('</span>')[0];
|
2018-10-28 20:03:57 +01:00
|
|
|
}
|
2018-10-30 04:56:00 +01:00
|
|
|
}
|
2018-10-28 20:03:57 +01:00
|
|
|
|
|
|
|
this.links.push(extractedUrl);
|
|
|
|
let classname = this.getClassNameForLink(extractedUrl);
|
|
|
|
|
|
|
|
this.processedText += `<a href class="${classname}" title="open link">${extractedName}</a>`;
|
|
|
|
if (extractedLinkAndNext.length > 1) this.processedText += extractedLinkAndNext[1];
|
2018-10-28 04:58:00 +01:00
|
|
|
}
|
|
|
|
|
2018-10-28 05:45:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
constructor(private renderer: Renderer2) { }
|
2018-10-28 04:58:00 +01:00
|
|
|
|
|
|
|
ngOnInit() {
|
|
|
|
}
|
|
|
|
|
2018-10-28 05:45:32 +01:00
|
|
|
ngAfterViewInit() {
|
2018-10-28 06:02:57 +01:00
|
|
|
for (const hashtag of this.hashtags) {
|
2018-11-01 23:38:59 +01:00
|
|
|
let classname = this.getClassNameForHastag(hashtag);
|
|
|
|
let el = this.contentElement.nativeElement.querySelector(`.${classname}`);
|
2018-10-28 06:02:57 +01:00
|
|
|
|
2018-10-28 06:25:13 +01:00
|
|
|
this.renderer.listen(el, 'click', (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
2018-10-28 06:02:57 +01:00
|
|
|
this.selectHashtag(hashtag);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const account of this.accounts) {
|
2018-10-28 20:03:57 +01:00
|
|
|
let classname = this.getClassNameForAccount(account);
|
2018-10-28 06:02:57 +01:00
|
|
|
let el = this.contentElement.nativeElement.querySelector(`.${classname}`);
|
|
|
|
|
2018-10-28 06:25:13 +01:00
|
|
|
this.renderer.listen(el, 'click', (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
2018-10-28 06:02:57 +01:00
|
|
|
this.selectAccount(account);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
for (const link of this.links) {
|
|
|
|
let classname = this.getClassNameForLink(link);
|
|
|
|
let el = this.contentElement.nativeElement.querySelector(`.${classname}`);
|
|
|
|
this.renderer.listen(el, 'click', (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
|
|
|
window.open(link, '_blank');
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
2018-10-28 05:45:32 +01:00
|
|
|
}
|
|
|
|
|
2018-11-01 23:38:59 +01:00
|
|
|
private getClassNameForHastag(value: string): string {
|
|
|
|
let res = value.replace(/[.,\/#?!@$%+\^&\*;:{}=\-_`~()]/g, "");
|
|
|
|
return `hashtag-${res}`;
|
|
|
|
}
|
|
|
|
|
2018-10-28 20:03:57 +01:00
|
|
|
private getClassNameForAccount(value: string): string {
|
2018-10-28 06:25:13 +01:00
|
|
|
let res = value;
|
2018-10-28 20:03:57 +01:00
|
|
|
while (res.includes('.')) res = res.replace('.', '-');
|
|
|
|
while (res.includes('@')) res = res.replace('@', '-');
|
|
|
|
return `account-${res}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
private getClassNameForLink(value: string): string {
|
2018-10-31 04:27:20 +01:00
|
|
|
let res = value.replace(/[.,\/#?!@$%+\^&\*;:{}=\-_`~()]/g, "");
|
2018-10-28 20:03:57 +01:00
|
|
|
return `link-${res}`;
|
2018-10-28 06:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private selectAccount(account: string) {
|
2018-10-28 05:45:32 +01:00
|
|
|
this.accountSelected.next(account);
|
|
|
|
}
|
|
|
|
|
2018-10-28 06:02:57 +01:00
|
|
|
private selectHashtag(hashtag: string) {
|
2018-10-28 05:45:32 +01:00
|
|
|
this.hashtagSelected.next(hashtag);
|
|
|
|
}
|
|
|
|
|
2018-10-28 06:33:53 +01:00
|
|
|
selectText() {
|
2018-10-28 05:45:32 +01:00
|
|
|
this.textSelected.next();
|
|
|
|
}
|
|
|
|
|
2018-10-28 04:58:00 +01:00
|
|
|
}
|