I am making a web extension.I wanted to highlight gender sensitive words written inside the contenteditable div, the reference is the dictionary[]. But when I try to type in a contenteditable div, newline(when I press enter) is not registering or like nullified.
document.addEventListener('input', function (event) {
let text = event.target
let formattedText = checkSpellingAndHighlight(text)
if (event.target.tagName === 'TEXTAREA' || event.target.tagName === 'INPUT') {
let text = event.target.value;
checkGender(text);
}
if(event.target.isContentEditable){
let cursorPosition = saveCursorPosition(text);
applyHighlightToContentEditable(text,formattedText)
restoreCursorPosition(text, cursorPosition);
}
});
let genderbiasWords = [];
const dictionary = [
'actress',
'anchorman',
'authoress',
'aviatrix',
'bachelor girl',
'bag ladies',
'brotherhood of man',
'busboys',
'businessman',
'cameraman',
'career girls',
'chairman',
'chambermaids',
'chick',
'comedienne',
'congressman',
'craftsmen',
'delivery boys',
'draftsmen',
'dykes',
'early man',
'employed mothers',
'executrixes',
'fair sex',
'father hood',
'female homosexuals',
'female lawyer',
'firemen',
'fish wives',
'fishermen',
'forefather',
'foremen',
'founding fathers',
'gay women',
'girl',
'girl Friday',
'girl athlete',
'granny midwives',
'heroic women',
'heroines',
'hookers',
'hostesses',
'house husbands',
'house wives',
'ladies',
'ladies chattering',
'lady doctor',
'layman',
'lineman',
'litte woman',
'lumbermen',
'maids',
'male chauvinist pig',
'male nurse',
'male secretary',
'man',
'man and wife',
'man of the street',
'man-made',
'manhood',
'mankind',
'manning',
'manpower',
'masterful',
'men',
'men and girls',
'men and ladies',
'mill girls',
'minority women',
'mother hood',
'old maid',
'old masters',
'one man show',
'poetess',
'policeman',
'pressmen',
'proprietress',
'repairmen',
'salesgirls',
'salesman',
'servants',
'spinster',
'spokesman',
'sportsmen',
'starlets',
'statemanship',
'statesmen',
'suffragette',
'to a man',
'usherette',
'watchmen',
'weaker sex',
'weatherman',
'whores',
'woman writer',
'women libbers',
'working men',
'working mothers',
'working wives',
'workmen',
'young girls'
];
function checkGender(text) {
let indicator = false;
dictionary.forEach(word => {
const regex = new RegExp(`\b${word}\b`, 'gi')
if(regex.test(text) && !genderbiasWords.includes(word)){
indicator = true
genderbiasWords.push(word)
}else if(text == ''){
genderbiasWords.length = 0
}
});
if (indicator) {
console.log("Gender-bias: ", genderbiasWords.join(", "));
}
}
// Check spelling and apply red underline to contenteditable divs
function checkSpellingAndHighlight(text) {
let formattedText = text.innerText
let textWithHTML = text.innerHTML // not used
dictionary.forEach(word => {
const regex = new RegExp(`\b${word}\b`,'gi')
if(regex.test(text.innerText)) {
// Wrap gender sensitive words with a span and a special class for underlining
formattedText = formattedText.replace(regex,`<span class='highlight-word'>${word}</span>`);
}
});
return formattedText;
}
// Apply the red underline styling to contenteditable divs
function applyHighlightToContentEditable(element, formattedText) {
element.innerHTML = formattedText; // Directly update the content with highlighted words
console.log({final:element.innerHTML})
}
// // Function to save the current cursor position
function saveCursorPosition(element) {
let selection = window.getSelection();
let range = selection.getRangeAt(0);
let preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
let cursorPosition = preCaretRange.toString().length;
return cursorPosition;
}
// // Function to restore the cursor position after modifying content
function restoreCursorPosition(element, cursorPosition) {
let selection = window.getSelection();
let range = document.createRange();
// Traverse the element's text nodes to find the right position to place the cursor
let node = element;
let chars = cursorPosition;
function traverseNodes(node) {
if (node.nodeType === 3) { // Text node
if (node.length >= chars) {
range.setStart(node, chars);
range.setEnd(node, chars);
return true;
} else {
chars -= node.length;
}
} else {
for (let i = 0; i < node.childNodes.length; i++) {
if (traverseNodes(node.childNodes[i])) {
return true;
}
}
}
return false;
}
traverseNodes(node);
selection.removeAllRanges();
selection.addRange(range);
}
// Inject the CSS to style the gender sensitive words in red underline
let style = document.createElement('style');
style.innerHTML = `
.highlight-word {
text-decoration: underline;
text-decoration-color: blue;
}
`;
document.head.appendChild(style);
Result of my code
It works fine with the underline and underline color. I did try to fix by returning the text.innerHTML instead of text.innerText, after typing a gender sensitive words, all of the following words become underlined too even if it is not gender sensitive.