HTMLR-PROJECT

by Felipe Alfaro

HTML

<input type="number" value="150" id="truncatelength-htmlrazor"/>
<input type="text" value="<p>You can <strong>add</strong> this html text</p>" id="addtext-htmlrazor"/>
<hr>
<div id="origin-htmlrazor">
    <h1>Hello World!</h1>
    <p>This is <strong>HTMLRazor</strong>!!</p>
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
</div>
<hr>
<div id="result-htmlrazor"></div>

<hr><hr><hr><hr><hr><hr><hr><hr><hr>
<div id="origin-html" contenteditable="true">
    <h1>Hello World!</h1>
    <p>Add more text here<br><small>from the formulary below</small></p>
    <div>
        ... or edit this text directly
    </div>
</div>
<hr>
<div id="result-html"></div>
<hr>

<br>
<label>Truncate text</label>
<input type="number" id="truncate-length" value="30"/>
<br>
<label>Add text</label>
<input type="text" id="text-to-add" value="my text"/>

CSS

#test {
    background: gainsboro;
}

#result {
    background: green;
}

#truncatelength-htmlrazor,
#addtext-htmlrazor{
    display: block;
    border: solid 1px #bfbdbd;
    background: whitesmoke;
    padding: 7px 14px;
    border-radius: 5px;
    margin: 8px 0;
    width: 400px;
}

#origin-htmlrazor {
    border: solid 2px #649fe8;
    padding: 16px;
    border-radius: 5px;
    background: gainsboro;
    cursor: pointer;
}

#result-htmlrazor {
    border: solid 2px #649fe8;
    padding: 16px;
    border-radius: 5px;
    background: #b4e3db;
}

#origin-html {
    padding: 16px;
    background: gainsboro;
}

#result-html {
    padding: 16px;
    background: #b4e3db;
}

TypeScript

// lib code

const REGEXP_TO_FIND_TAGS_IN_STRING: RegExp = /(<([^>]+)>)/ig;
const REGEXP_TO_FIND_SPACES: RegExp = /^\s*|\s*$|\s*(\r?\n)\s*|(\s)\s+/g;
const REGEXP_TO_FIND_EMPTY_TAGS: RegExp = /<[^/>][^>]*><\/[^>]+>/gm;
const REGEXP_TO_FIND_BR_TAGS_IN_THE_END: RegExp = /^(\s*<br( \/)?>)*|(<br( \/)?>\s*)*$/gm;
const REGEXP_TO_FIND_WORDS_OUTSIDE_TAGS: RegExp = /(\w+)(?![^<]*>|[^<>]*<\/)/gm;
const REGEXP_TO_FIND_TAGS_WITH_CONTENTS: RegExp = /<(\w+)[^>]*>(.*?)<\/\1>/gm;
const REGEXP_TO_FIND_PUNCTUATION_MARKS: RegExp = /[/\{,.;:}/]+/gm;
const DEFAULT_ELEMENT_HIDDEN_START: string = '<r-hidden style="display: none;">';
const DEFAULT_ELEMENT_HIDDEN_END: string = '</r-hidden>';
const DEFAULT_ELLIPSIS_TEXT: string = '...';
const PUNCTUATION_MARKS: string[] = ['.', ',', ';', ':']

const truncateHTMLText = (
    rawHTMLText: string,
    characterLimit: number
): string => {
    const htmlText = rawHTMLText
    	.replace(REGEXP_TO_FIND_SPACES, '')
    const pureText = rawHTMLText
    	.replace(REGEXP_TO_FIND_TAGS_IN_STRING, '')
        .replace(REGEXP_TO_FIND_SPACES, ' ')
        .trim();
    const matchList = Array.from(htmlText.matchAll(REGEXP_TO_FIND_TAGS_IN_STRING));
    let result: string = pureText.slice(0, characterLimit);

    matchList.forEach(match => {
    	const matchResultLastPart = result.slice(match.index).trim();
        
        if (matchResultLastPart.length) {
        	result = result.slice(0, match.index) + match[0] + matchResultLastPart;
        }
    });

    return result;
};

class HTMLRazor {
	public readonly htmlTextTruncated: string = '';
    public readonly ellipsisText: string | null = null;
    
	constructor(
    	public readonly htmlText: string,
        public readonly truncateLength: number,
       	ellipsis: boolean | string = false
    ) {
    	console.log('HTMLRazor');
    
        this.htmlTextTruncated = truncateHTMLText(
        	this.htmlText, this.truncateLength
        );
        
        if (ellipsis) {
        	this.ellipsisText =...