@rws-framework/components
Version:
117 lines (90 loc) • 3.33 kB
text/typescript
import { RWSViewComponent, RWSView } from '@rws-framework/client';
import { observable, attr } from '@microsoft/fast-element';
import { ViewTemplate } from '@microsoft/fast-element';
class LineSplitter extends RWSViewComponent {
text: string = '';
content: string | ViewTemplate = '<span class="dots">.</span>';
query: string = '';
callback?: () => void;
dots = false;
allowedTags = '';
addClass = '';
private stopAnimation: () => void = () => {};
private allowedHTMLTags: string[] = ['dl', 'dt', 'dd', 'br', 'blockquote', 'span', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'strong', 'i', 'small', 'u'];
connectedCallback(): void {
super.connectedCallback();
if(this.dots){
this.stopAnimation = this.animateLoadingDots();
}
if(this.text){
this.splitLines();
}
}
parseTags(line: string): string | ViewTemplate
{
const componentAllowedTags: string[] = this.allowedHTMLTags.concat(this.allowedTags.split(','));
let output = this.domService.sanitizeHTML(line, { ADD_TAGS: [], ALLOWED_TAGS: componentAllowedTags });
output = output.replace(/<.*>([\s\S]*?)<\/.*>/g, (match: string) => {
return match.replace(/\n/g, '');
});
output = output.replace(/\n\n/g, '\n');
output = output.replace(/\n/g, '<br/>');
output = output.replace(/<\/p><br\/>/g, '</p>');
output = output
.replace(/<br\/><h([1-3])>/g, '<h$1>')
.replace(/<\/h([1-3])><br\/>/g, '</h$1>');
if(this.query !== null || this.query !== '') {
const query: string[] = this.query ? this.query.split(',').map(word => word.trim()) : [];
query.forEach(word => {
// Create a regex for the word, ensuring it's case-insensitive and doesn't affect existing HTML tags
const regex = new RegExp(`(${word})(?![^<]*>)`, 'gi');
output = output.replace(regex, '<span class="tagged">$1</span>');
});
}
return output;
}
splitLines(): void
{
if([". ", ". . ", ". . . "].includes(this.text)){
this.content = `<span class="dots">${this.text}</span>`
}else{
this.stopAnimation();
this.content = this.parseTags(this.text);
}
}
textChanged(oldVal: string, newVal: string)
{
if(newVal){
this.text = newVal;
this.splitLines();
}
}
contentChanged(){
if(this.callback){
this.callback();
}
}
animateLoadingDots(): () => void {
let counter = 1;
const interval = setInterval(() => {
counter = counter % 3 + 1;
this.text = '. '.repeat(counter);
}, 800);
// Zwracamy funkcję do zatrzymania animacji
return () => clearInterval(interval);
}
addClassChanged(oldVal: string, newVal: string)
{
if(newVal){
this.addClass = newVal;
}
}
queryChanged(oldVal: string, newVal: string){
if(newVal){
this.splitLines();
}
}
}
LineSplitter.defineComponent();
export { LineSplitter };