From d48d66516d3381849a230acb4d541f5effb067d3 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Thu, 25 Jul 2024 09:45:49 +0530 Subject: [PATCH 01/19] v 1.0.0 prototype --- browser-extension/prototype/index.html | 57 ++++++++++ browser-extension/prototype/index.js | 141 +++++++++++++++++++++++++ browser-extension/prototype/info.png | Bin 0 -> 13149 bytes 3 files changed, 198 insertions(+) create mode 100644 browser-extension/prototype/index.html create mode 100644 browser-extension/prototype/index.js create mode 100644 browser-extension/prototype/info.png diff --git a/browser-extension/prototype/index.html b/browser-extension/prototype/index.html new file mode 100644 index 00000000..e5b08797 --- /dev/null +++ b/browser-extension/prototype/index.html @@ -0,0 +1,57 @@ + + + + + + + Document + + + + +

+
+ +

+ Lorem ipsum dolor sit amet consectetur crazy adipisicing elit. Quaerat alias iste quo exercitationem stupid + nesciunt ea? +

+ +

+ + + + Lorem ipsum, dolor sit amet stupid mad adipisicing elit. Magni minima adipisci architecto. +

+
+ + + +
+ +
+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa possimus quisquam temporibus + reprehenderit nesciunt dignissimos sunt ipsum, nostrum modi? Iusto libero sed alias! +

+ crazy +
+
+ + +

+ Lorem ipsum dolor crazy Lorem, ipsum dolor. sit stupid amet consectetur adipisicing elit. Aut architecto illum dolorum + mad. +

+ + + + + \ No newline at end of file diff --git a/browser-extension/prototype/index.js b/browser-extension/prototype/index.js new file mode 100644 index 00000000..7d1f1860 --- /dev/null +++ b/browser-extension/prototype/index.js @@ -0,0 +1,141 @@ +function checkFalseTextNode(text, actualLengthOfText) { + let totalNewlineAndWhitespaces = 0; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; + } + } + return totalNewlineAndWhitespaces === actualLengthOfText; +} + +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { + uliStore.push({ node: node, parent: node.parentNode }); + } + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); + } +} + + +function findPositions(word, text) { + let positions = {}; + + let len = word.length + let loc = [] + let index = text.toString().indexOf(word); + while (index !== -1) { + let obj = {}; + loc.push([index, index + len]); + index = text.toString().indexOf(word, index + 1); + } + + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; + } + return positions; +} + + +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let text = store.node.textContent + //We have to look into this store for all the slurWords + let slurs = []; + + targetWords.forEach(targetWord => { + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { + slurs.push(pos) + } + + if (parentNode.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = parentNode.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}`); + parentNode.innerHTML = replacedHTML + } + }) + uliStore[i].slurs = slurs; + } + return uliStore; //This will return the final uliStore (after appending slurs) +} + + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "2%" + img.style.width = "2%" + img.style.cursor = "pointer" + // img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + span.style.width = "12rem" + span.style.textAlign = "justify" + span.innerHTML = `This is ${targetWord}` + + + if (targetWord === "crazy") { + span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` + } + else if (targetWord === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` + } + else { + span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + +let targetWords = ["stupid", "crazy", "Crazy", "mad"] +let uliStore = [] +getAllTextNodes(document.body, uliStore) +abc = locateSlur(uliStore, targetWords) +console.log("uliStore", abc) +addMetaData(targetWords) diff --git a/browser-extension/prototype/info.png b/browser-extension/prototype/info.png new file mode 100644 index 0000000000000000000000000000000000000000..311011c6321e34669f055e688e9adb713e680d5e GIT binary patch literal 13149 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 F{|E5(mn#4O literal 0 HcmV?d00001 From bedd4d93a0d00e4de41d0620a9065f6b564a4b5e Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Thu, 15 Aug 2024 11:52:46 +0530 Subject: [PATCH 02/19] replacing child --- browser-extension/prototype/index2.html | 39 ++++++ browser-extension/prototype/index2.js | 141 +++++++++++++++++++ browser-extension/prototype/index3.html | 39 ++++++ browser-extension/prototype/index3.js | 171 ++++++++++++++++++++++++ 4 files changed, 390 insertions(+) create mode 100644 browser-extension/prototype/index2.html create mode 100644 browser-extension/prototype/index2.js create mode 100644 browser-extension/prototype/index3.html create mode 100644 browser-extension/prototype/index3.js diff --git a/browser-extension/prototype/index2.html b/browser-extension/prototype/index2.html new file mode 100644 index 00000000..5b2bf827 --- /dev/null +++ b/browser-extension/prototype/index2.html @@ -0,0 +1,39 @@ + + + + + + + Document + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/browser-extension/prototype/index2.js b/browser-extension/prototype/index2.js new file mode 100644 index 00000000..bbd6c27a --- /dev/null +++ b/browser-extension/prototype/index2.js @@ -0,0 +1,141 @@ +function checkFalseTextNode(text, actualLengthOfText) { + let totalNewlineAndWhitespaces = 0; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; + } + } + return totalNewlineAndWhitespaces === actualLengthOfText; +} + +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { + uliStore.push({ node: node, parent: node.parentNode }); + } + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); + } +} + + +function findPositions(word, text) { + let positions = {}; + + let len = word.length + let loc = [] + let index = text.toString().indexOf(word); + while (index !== -1) { + let obj = {}; + loc.push([index, index + len]); + index = text.toString().indexOf(word, index + 1); + } + + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; + } + return positions; +} + + +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let text = store.node.textContent + //We have to look into this store for all the slurWords + let slurs = []; + + targetWords.forEach(targetWord => { + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { + slurs.push(pos) + } + + if (parentNode.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = parentNode.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}*`); + parentNode.innerHTML = replacedHTML + } + }) + uliStore[i].slurs = slurs; + } + return uliStore; //This will return the final uliStore (after appending slurs) +} + + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "2%" + img.style.width = "2%" + img.style.cursor = "pointer" + // img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + span.style.width = "12rem" + span.style.textAlign = "justify" + span.innerHTML = `This is ${targetWord}` + + + if (targetWord === "crazy") { + span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` + } + else if (targetWord === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` + } + else { + span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + +let targetWords = ["stupid", "crazy", "Crazy", "mad"] +let uliStore = [] +getAllTextNodes(document.body, uliStore) +abc = locateSlur(uliStore, targetWords) +console.log("uliStore", abc) +// addMetaData(targetWords) diff --git a/browser-extension/prototype/index3.html b/browser-extension/prototype/index3.html new file mode 100644 index 00000000..06c2df62 --- /dev/null +++ b/browser-extension/prototype/index3.html @@ -0,0 +1,39 @@ + + + + + + + Document + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/browser-extension/prototype/index3.js b/browser-extension/prototype/index3.js new file mode 100644 index 00000000..5e49a7da --- /dev/null +++ b/browser-extension/prototype/index3.js @@ -0,0 +1,171 @@ +function checkFalseTextNode(text, actualLengthOfText) { + let totalNewlineAndWhitespaces = 0; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; + } + } + return totalNewlineAndWhitespaces === actualLengthOfText; +} + +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { + uliStore.push({ node: node, parent: node.parentNode }); + } + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); + } +} + + +function findPositions(word, text) { + let positions = {}; + + let len = word.length + let loc = [] + let index = text.toString().indexOf(word); + while (index !== -1) { + let obj = {}; + loc.push([index, index + len]); + index = text.toString().indexOf(word, index + 1); + } + + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; + } + return positions; +} + + +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let textnode = store.node + let text = store.node.textContent + let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block + //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent + tempParent.textContent = text ; + //We have to look into this store for all the slurWords + let slurs = []; + + targetWords.forEach(targetWord => { + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { + slurs.push(pos) + } + + if (tempParent.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = tempParent.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}*`); + tempParent.innerHTML = replacedHTML + } + }) + + + + // for(let i = 0 ; i < ) + // console.log("tempParent " , tempParent) + uliStore[i].nodeToParent = tempParent + uliStore[i].slurs = slurs; + + + + parentNode.childNodes.forEach((node) => { + // Check if the node is a text node + // if (node.nodeType === Node.TEXT_NODE) { + // // Check if the text node contains the target text + // if (node.textContent.trim() === "Replace this text node") { + // // Create a new element to replace the text node + // let newElement = document.createElement('span'); + // newElement.textContent = "This is the new element"; + + // // Replace the text node with the new element + // container.replaceChild(newElement, node); + // } + // } + if(node === textnode){ + parentNode.replaceChild(tempParent , node) + } + }); + } + return uliStore; //This will return the final uliStore (after appending slurs) +} + + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "2%" + img.style.width = "2%" + img.style.cursor = "pointer" + // img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + span.style.width = "12rem" + span.style.textAlign = "justify" + span.innerHTML = `This is ${targetWord}` + + + if (targetWord === "crazy") { + span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` + } + else if (targetWord === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` + } + else { + span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + +let targetWords = ["stupid", "crazy", "Crazy", "mad"] +let uliStore = [] +getAllTextNodes(document.body, uliStore) +abc = locateSlur(uliStore, targetWords) +console.log("uliStore", abc) +// addMetaData(targetWords) From 5eb7d3b529c239f7514b87ec06be02f8346b0493 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Thu, 15 Aug 2024 12:32:28 +0530 Subject: [PATCH 03/19] metadata ver 1.0.0 --- browser-extension/prototype/index3.js | 43 +++++++++------------------ browser-extension/prototype/new.js | 28 +++++++++++++++++ 2 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 browser-extension/prototype/new.js diff --git a/browser-extension/prototype/index3.js b/browser-extension/prototype/index3.js index 5e49a7da..c4273773 100644 --- a/browser-extension/prototype/index3.js +++ b/browser-extension/prototype/index3.js @@ -48,11 +48,11 @@ function locateSlur(uliStore, targetWords) { for (let i = 0; i < n; i++) { let store = uliStore[i]; //This will contain the textNode let parentNode = store.parent - let textnode = store.node + let textnode = store.node let text = store.node.textContent let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent - tempParent.textContent = text ; + tempParent.textContent = text; //We have to look into this store for all the slurWords let slurs = []; @@ -66,37 +66,21 @@ function locateSlur(uliStore, targetWords) { if (tempParent.innerHTML.includes(targetWord)) { const className = `icon-container-${targetWord}`; const parts = tempParent.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}*`); + const replacedHTML = parts.join(`${targetWord}`); tempParent.innerHTML = replacedHTML } }) - - - // for(let i = 0 ; i < ) // console.log("tempParent " , tempParent) uliStore[i].nodeToParent = tempParent uliStore[i].slurs = slurs; - parentNode.childNodes.forEach((node) => { - // Check if the node is a text node - // if (node.nodeType === Node.TEXT_NODE) { - // // Check if the text node contains the target text - // if (node.textContent.trim() === "Replace this text node") { - // // Create a new element to replace the text node - // let newElement = document.createElement('span'); - // newElement.textContent = "This is the new element"; - - // // Replace the text node with the new element - // container.replaceChild(newElement, node); - // } - // } - if(node === textnode){ - parentNode.replaceChild(tempParent , node) + if (node === textnode) { + parentNode.replaceChild(tempParent, node) } - }); + }); } return uliStore; //This will return the final uliStore (after appending slurs) } @@ -111,11 +95,11 @@ function addMetaData(targetWords) { let sup = document.createElement("sup"); let img = document.createElement("img"); - img.style.height = "2%" - img.style.width = "2%" + img.style.height = "3%" + img.style.width = "3%" img.style.cursor = "pointer" - // img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" - img.src = "./info.png" + img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + // img.src = "./info.png" img.alt = "altText" let span = document.createElement("span") @@ -162,10 +146,11 @@ function addMetaData(targetWords) { }) } - -let targetWords = ["stupid", "crazy", "Crazy", "mad"] +// let imgSrc = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" +// let imgAlt = "slur word desc" +let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] let uliStore = [] getAllTextNodes(document.body, uliStore) abc = locateSlur(uliStore, targetWords) console.log("uliStore", abc) -// addMetaData(targetWords) +addMetaData(targetWords) diff --git a/browser-extension/prototype/new.js b/browser-extension/prototype/new.js new file mode 100644 index 00000000..b57a9d91 --- /dev/null +++ b/browser-extension/prototype/new.js @@ -0,0 +1,28 @@ +const iconSrc = './info.svg'; +const iconAlt = 'Icon description'; +const targetWords = ['crazy', 'stupid', 'mad']; // Replace with your list of target words + +// Find all elements that contain any of the target words +document.querySelectorAll('*').forEach(element => { + targetWords.forEach(targetWord => { + if (element.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + // Split the innerHTML into parts to handle replacements + const parts = element.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}`); + + // Update the element with the replaced content + element.innerHTML = replacedHTML; + + // Add icon after each occurrence of the target word + const iconContainers = element.querySelectorAll(`.${className}`); + iconContainers.forEach(container => { + const icon = document.createElement('img'); + icon.src = iconSrc; + icon.alt = iconAlt; + container.appendChild(icon); + + }); + } + }); +}); \ No newline at end of file From 8b6085ff02ae1a6cb8a6ec718ea1dc24f64d2e2c Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Thu, 15 Aug 2024 13:31:40 +0530 Subject: [PATCH 04/19] removed O(n) complexity --- browser-extension/prototype/index3.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/browser-extension/prototype/index3.js b/browser-extension/prototype/index3.js index c4273773..42f5dab7 100644 --- a/browser-extension/prototype/index3.js +++ b/browser-extension/prototype/index3.js @@ -76,11 +76,16 @@ function locateSlur(uliStore, targetWords) { uliStore[i].slurs = slurs; - parentNode.childNodes.forEach((node) => { - if (node === textnode) { - parentNode.replaceChild(tempParent, node) - } - }); + //Additional O(N) complexity + // parentNode.childNodes.forEach((node) => { + // if (node === textnode) { + // parentNode.replaceChild(tempParent, node) + // } + // }); + + //O(1) complexity + parentNode.replaceChild(tempParent, node) + } return uliStore; //This will return the final uliStore (after appending slurs) } @@ -146,8 +151,7 @@ function addMetaData(targetWords) { }) } -// let imgSrc = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" -// let imgAlt = "slur word desc" + let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] let uliStore = [] getAllTextNodes(document.body, uliStore) From 9e41b8240c948c588f2efc5a6969c47cbaf6e443 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 16 Aug 2024 10:26:49 +0530 Subject: [PATCH 05/19] integration work started --- browser-extension/plugin/manifest.json | 24 ++- .../plugin/src/content-script.js | 10 +- browser-extension/plugin/src/slur-metadata.js | 163 +++++++++++++++ .../plugin/src/transform-general.js | 192 +++++++++++++----- browser-extension/prototype/index3.js | 2 +- 5 files changed, 328 insertions(+), 63 deletions(-) create mode 100644 browser-extension/plugin/src/slur-metadata.js diff --git a/browser-extension/plugin/manifest.json b/browser-extension/plugin/manifest.json index 0f72e6ec..1f13f924 100644 --- a/browser-extension/plugin/manifest.json +++ b/browser-extension/plugin/manifest.json @@ -5,22 +5,34 @@ "version": "0.1.16", "author": "tattlemade|cis", "content_security_policy": { - "extension_pages": "default-src 'none'; connect-src https://ogbv-plugin.tattle.co.in/ https://uli-media.tattle.co.in/; font-src https://fonts.gstatic.com; object-src 'none'; script-src 'self'; style-src https://fonts.googleapis.com 'self' 'unsafe-inline'; img-src https://uli-media.tattle.co.in/; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; report-uri 'none';" + "extension_pages": "default-src 'none'; connect-src http://localhost:3000 ws://localhost; font-src https://fonts.gstatic.com; object-src 'none'; script-src 'self'; style-src https://fonts.googleapis.com 'self' 'unsafe-inline'; img-src https://uli-media.tattle.co.in/; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; report-uri 'none';" }, - "permissions": ["storage", "contextMenus"], - "host_permissions": ["https://ogbv-plugin.tattle.co.in/*"], + "permissions": [ + "storage", + "contextMenus" + ], + "host_permissions": [ + "https://ogbv-plugin.tattle.co.in/*" + ], "background": { "service_worker": "background.js" }, "content_scripts": [ { - "matches": [""], - "js": ["content-script.js"], + "matches": [ + "" + ], + "js": [ + "content-script.js" + ], "run_at": "document_end" } ], "action": { "default_popup": "options.html" }, - "icons": { "16": "icon16.png", "48": "icon32.png" } + "icons": { + "16": "icon16.png", + "48": "icon32.png" + } } \ No newline at end of file diff --git a/browser-extension/plugin/src/content-script.js b/browser-extension/plugin/src/content-script.js index e31fb03f..92f792ca 100644 --- a/browser-extension/plugin/src/content-script.js +++ b/browser-extension/plugin/src/content-script.js @@ -148,13 +148,19 @@ chrome.runtime.onMessage.addListener(async function (request) { window.addEventListener( 'load', async () => { - console.log('content loaded'); + // console.log('content loaded'); + // console.log("wowowow") const pref = await getPreferenceData(); - console.log(pref); + // console.log(pref); const { enableSlurReplacement } = pref; if (enableSlurReplacement) { processPage(location.href); } + else{ + let body = document.getElementsByTagName('body'); + let first_body = body[0]; + transformGeneral.processNewlyAddedNodesGeneral2(first_body); + } }, false ); diff --git a/browser-extension/plugin/src/slur-metadata.js b/browser-extension/plugin/src/slur-metadata.js new file mode 100644 index 00000000..b0862957 --- /dev/null +++ b/browser-extension/plugin/src/slur-metadata.js @@ -0,0 +1,163 @@ +// Created on Aug, 15 +// Author : Hardik PS + +function checkFalseTextNode(text, actualLengthOfText) { + let totalNewlineAndWhitespaces = 0; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; + } + } + return totalNewlineAndWhitespaces === actualLengthOfText; +} + +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { + uliStore.push({ node: node, parent: node.parentNode }); + } + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); + } +} + + +function findPositions(word, text) { + let positions = {}; + + let len = word.length + let loc = [] + let index = text.toString().indexOf(word); + while (index !== -1) { + let obj = {}; + loc.push([index, index + len]); + index = text.toString().indexOf(word, index + 1); + } + + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; + } + return positions; +} + + +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let textnode = store.node + let text = store.node.textContent + let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block + //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent + tempParent.textContent = text; + //We have to look into this store for all the slurWords + let slurs = []; + + targetWords.forEach(targetWord => { + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { + slurs.push(pos) + } + + if (tempParent.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = tempParent.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}`); + tempParent.innerHTML = replacedHTML + } + }) + // for(let i = 0 ; i < ) + // console.log("tempParent " , tempParent) + uliStore[i].nodeToParent = tempParent + uliStore[i].slurs = slurs; + + + //Additional O(N) complexity + // parentNode.childNodes.forEach((node) => { + // if (node === textnode) { + // parentNode.replaceChild(tempParent, node) + // } + // }); + + //O(1) complexity + parentNode.replaceChild(tempParent, node) + + } + return uliStore; //This will return the final uliStore (after appending slurs) +} + + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "3%" + img.style.width = "3%" + img.style.cursor = "pointer" + img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + // img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + span.style.width = "12rem" + span.style.textAlign = "justify" + span.innerHTML = `This is ${targetWord}` + + + if (targetWord === "crazy") { + span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` + } + else if (targetWord === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` + } + else { + span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + +let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] +let uliStore = [] +getAllTextNodes(document.body, uliStore) +abc = locateSlur(uliStore, targetWords) +console.log("uliStore", abc) +addMetaData(targetWords) diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index 07c724ba..9cc2dcd0 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -49,6 +49,22 @@ function setCaretPosition(element, offset) { sel.addRange(range); } + +const processNewlyAddedNodesGeneral2 = function (firstBody) { + + console.log("HEY THERE !!!") + let targetWords = ["stupid", "crazy", "Crazy", "mad", "Mad", "MAD"] + let uliStore = [] + // getAllTextNodes(document.body, uliStore) + getAllTextNodes(firstBody, uliStore) + console.log(uliStore) + abc = locateSlur(uliStore, targetWords) + console.log("uliStore", abc) + addMetaData(targetWords) + +} + + const processNewlyAddedNodesGeneral = function (firstBody) { log('processing new nodes'); const config = { attributes: true, childList: true, subtree: true }; @@ -79,52 +95,31 @@ const processNewlyAddedNodesGeneral = function (firstBody) { /* getAllTextNodes() STARTS HERE */ function checkFalseTextNode(text, actualLengthOfText) { - let n = text.length; let totalNewlineAndWhitespaces = 0; - for (let i = 0; i < n; i++) { - if (text[i] === "\n") { - totalNewlineAndWhitespaces += 1; - } - - else if (text[i] === " ") { - totalNewlineAndWhitespaces += 1; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { + // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; } - - } - if (totalNewlineAndWhitespaces === actualLengthOfText) { - //False Text Node Confirmed - return true; - } - else { - //True Text Node Confirmed - return false; } + return totalNewlineAndWhitespaces === actualLengthOfText; } -function getAllTextNodes(node) { - let uliStore = [] - if (node.nodeType === 3) { - //If node.data contains just whitespaces and \n, then its a false text node - - // let whitespaces = (node.data.split(" ").length - 1); - // console.log(node.data) ; - if (checkFalseTextNode(node.data, node.length) === false) { +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { uliStore.push({ node: node, parent: node.parentNode }); } - // textNodes.push({ node: node, parent: node.parentNode }); - return; - } - - let children = Array.from(node.childNodes); - for (let i = 0; i < children.length; i++) { - getAllTextNodes(children[i]); + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); } - - return uliStore ; } + /* getAllTextNodes() ENDS HERE */ @@ -132,45 +127,64 @@ function getAllTextNodes(node) { function findPositions(word, text) { let positions = {}; - + let len = word.length let loc = [] let index = text.toString().indexOf(word); while (index !== -1) { - let obj = {} ; - loc.push([index , index + len]); + let obj = {}; + loc.push([index, index + len]); index = text.toString().indexOf(word, index + 1); } - - if(loc.length !== 0){ - positions.slurText = word - positions.slurLocation = loc ; + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; } return positions; } -function locateSlur(uliStore, targetWords){ - let n = uliStore.length ; - for(let i = 0 ; i < n ; i++){ - let store = uliStore[i] ; //This will contain the textNode - let parentNode = store.parent +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let textnode = store.node let text = store.node.textContent - //We have to look into this store for all the slurWords - let slurs = [] ; + let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block + //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent + tempParent.textContent = text; + + let slurs = []; targetWords.forEach(targetWord => { - let slurWord = targetWord ; - let pos = findPositions(slurWord , text) ; - if(Object.keys(pos).length !== 0){ + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { slurs.push(pos) } + + if (tempParent.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = tempParent.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}`); + tempParent.innerHTML = replacedHTML + } }) - uliStore[i].slurs = slurs ; + // for(let i = 0 ; i < ) + // console.log("tempParent " , tempParent) + uliStore[i].nodeToParent = tempParent + uliStore[i].slurs = slurs; + + //O(1) complexity + parentNode.replaceChild(tempParent, textnode) + } - return uliStore ; //This will return the final uliStore (after appending slurs) + return uliStore; } @@ -178,8 +192,78 @@ function locateSlur(uliStore, targetWords){ + +/* addMetaData() STARTS HERE */ + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "3%" + img.style.width = "3%" + img.style.cursor = "pointer" + img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + // img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + span.style.width = "12rem" + span.style.textAlign = "justify" + span.innerHTML = `This is ${targetWord}` + + + if (targetWord === "crazy") { + span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` + } + else if (targetWord === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` + } + else { + span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + +/* addMetaData() ENDS HERE */ + + + + export default { - processNewlyAddedNodesGeneral + processNewlyAddedNodesGeneral , + processNewlyAddedNodesGeneral2 }; diff --git a/browser-extension/prototype/index3.js b/browser-extension/prototype/index3.js index 42f5dab7..1834978a 100644 --- a/browser-extension/prototype/index3.js +++ b/browser-extension/prototype/index3.js @@ -84,7 +84,7 @@ function locateSlur(uliStore, targetWords) { // }); //O(1) complexity - parentNode.replaceChild(tempParent, node) + parentNode.replaceChild(tempParent, textnode) } return uliStore; //This will return the final uliStore (after appending slurs) From ad502ba0d7d76e436d510c3ee86b3f3971fae50b Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 23 Aug 2024 00:23:37 +0530 Subject: [PATCH 06/19] integrations --- .../plugin/src/transform-general.js | 83 ++++++++++++++----- 1 file changed, 60 insertions(+), 23 deletions(-) diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index 9cc2dcd0..c853744a 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -52,16 +52,26 @@ function setCaretPosition(element, offset) { const processNewlyAddedNodesGeneral2 = function (firstBody) { - console.log("HEY THERE !!!") - let targetWords = ["stupid", "crazy", "Crazy", "mad", "Mad", "MAD"] - let uliStore = [] - // getAllTextNodes(document.body, uliStore) - getAllTextNodes(firstBody, uliStore) - console.log(uliStore) - abc = locateSlur(uliStore, targetWords) - console.log("uliStore", abc) - addMetaData(targetWords) - + // const config = { attributes: true, childList: true, subtree: true }; + const callback = () => { + console.log("HEY THERE !!!") + let targetWords = ["bad", "BAD" , "Bad" , "Stupid" , "STUPID" , "stupid", "crazy", "Crazy", "mad", "Mad", "MAD" , "CRAZY"] + let uliStore = [] + // getAllTextNodes(document.body, uliStore) + getAllTextNodes(firstBody, uliStore) + console.log(uliStore) + abc = locateSlur(uliStore, targetWords) + console.log("uliStore", abc) + addMetaData(targetWords) + } + + callback() ; + + + // const observer = new MutationObserver(callback); + // observer.observe(firstBody , config); + + } @@ -160,7 +170,7 @@ function locateSlur(uliStore, targetWords) { tempParent.textContent = text; let slurs = []; - + let slurPresentInTempParent = false; targetWords.forEach(targetWord => { let slurWord = targetWord; let pos = findPositions(slurWord, text); @@ -173,6 +183,7 @@ function locateSlur(uliStore, targetWords) { const parts = tempParent.innerHTML.split(targetWord); const replacedHTML = parts.join(`${targetWord}`); tempParent.innerHTML = replacedHTML + slurPresentInTempParent = true; } }) // for(let i = 0 ; i < ) @@ -181,10 +192,15 @@ function locateSlur(uliStore, targetWords) { uliStore[i].slurs = slurs; //O(1) complexity - parentNode.replaceChild(tempParent, textnode) + if (slurPresentInTempParent) { + // parentNode.replaceChild(tempParent, textnode) + textnode.replaceWith(tempParent) + // textnode.replaceWith(createTextNode(tempParent.innerHTML)) + + } } - return uliStore; + return uliStore; } @@ -204,14 +220,15 @@ function addMetaData(targetWords) { let sup = document.createElement("sup"); let img = document.createElement("img"); - img.style.height = "3%" - img.style.width = "3%" + img.style.height = "2%" + img.style.width = "2%" img.style.cursor = "pointer" img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" // img.src = "./info.png" img.alt = "altText" let span = document.createElement("span") + // span.style.all = "unset" span.style.display = "none" span.style.position = "absolute" span.style.backgroundColor = "antiquewhite" @@ -220,20 +237,39 @@ function addMetaData(targetWords) { span.style.padding = "2px 6px" span.style.width = "12rem" span.style.textAlign = "justify" + span.style.fontWeight = "lighter" + span.style.color = "black" + span.style.zIndex = "1000000000"; // This ensures it appears above other elements + span.style.fontSize = "14px" + span.style.textDecoration = "none" + span.style.fontStyle = "normal" + // span.style.height = "fit-content" span.innerHTML = `This is ${targetWord}` + // span.style.display = "none"; + // span.style.position = "absolute"; + // span.style.backgroundColor = "antiquewhite !important"; + // span.style.border = "1px solid black !important"; + // span.style.borderRadius = "12px !important"; + // span.style.padding = "2px 6px !important"; + // span.style.width = "12rem !important"; + // span.style.textAlign = "justify !important"; + // span.innerHTML = `This is ${targetWord}`; + + + - if (targetWord === "crazy") { - span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + if (targetWord.toLowerCase() === "crazy") { + span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` } - else if (targetWord === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` + else if (targetWord.toLowerCase() === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` } - else if (targetWord === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` + else if (targetWord.toLowerCase() === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` } else { - span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` + span.innerHTML = `This word is considered offensive.` } @@ -246,6 +282,7 @@ function addMetaData(targetWords) { const svgs = element.children[0].children[0]; svgs.addEventListener('mouseover', function () { sups.children[1].style.display = "inline-block" + // sups.children[1].style.display = "block" }); svgs.addEventListener('mouseout', function () { @@ -262,7 +299,7 @@ function addMetaData(targetWords) { export default { - processNewlyAddedNodesGeneral , + processNewlyAddedNodesGeneral, processNewlyAddedNodesGeneral2 }; From 0d6d33400bbab48ffbb55c480aff37fd573212de Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Sat, 24 Aug 2024 12:55:24 +0530 Subject: [PATCH 07/19] EnableSlurMetaData Added --- .../plugin/src/content-script.js | 4 +- .../plugin/src/transform-general.js | 4 +- .../src/ui-components/pages/Preferences.jsx | 61 ++++++++++++++++++- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/browser-extension/plugin/src/content-script.js b/browser-extension/plugin/src/content-script.js index 92f792ca..2e581e82 100644 --- a/browser-extension/plugin/src/content-script.js +++ b/browser-extension/plugin/src/content-script.js @@ -152,11 +152,11 @@ window.addEventListener( // console.log("wowowow") const pref = await getPreferenceData(); // console.log(pref); - const { enableSlurReplacement } = pref; + const { enableSlurReplacement , enableSlurMetadata } = pref; if (enableSlurReplacement) { processPage(location.href); } - else{ + else if (enableSlurMetadata) { let body = document.getElementsByTagName('body'); let first_body = body[0]; transformGeneral.processNewlyAddedNodesGeneral2(first_body); diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index c853744a..e9433750 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -55,7 +55,7 @@ const processNewlyAddedNodesGeneral2 = function (firstBody) { // const config = { attributes: true, childList: true, subtree: true }; const callback = () => { console.log("HEY THERE !!!") - let targetWords = ["bad", "BAD" , "Bad" , "Stupid" , "STUPID" , "stupid", "crazy", "Crazy", "mad", "Mad", "MAD" , "CRAZY"] + let targetWords = ["Blog" , "BLOG", "Choose" , "domain", "bad", "BAD" , "Bad" , "Stupid" , "STUPID" , "stupid", "crazy", "Crazy", "mad", "Mad", "MAD" , "CRAZY"] let uliStore = [] // getAllTextNodes(document.body, uliStore) getAllTextNodes(firstBody, uliStore) @@ -235,7 +235,7 @@ function addMetaData(targetWords) { span.style.border = "1px solid black" span.style.borderRadius = "12px" span.style.padding = "2px 6px" - span.style.width = "12rem" + // span.style.width = "12rem" span.style.textAlign = "justify" span.style.fontWeight = "lighter" span.style.color = "black" diff --git a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx index 07dde087..e6bfbde1 100644 --- a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx +++ b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx @@ -30,6 +30,7 @@ export function Preferences() { const [enable, setEnable] = useState(true); const [enableML, setEnableMLOption] = useState(false); const [enableSlurReplacement, setEnableSlurReplacement] = useState(true); + const [enableSlurMetadata, setEnableSlurMetadata] = useState(false); const [storeLocally, setStoreLocally] = useState(true); const [language, setLanguage] = useState('English'); const { t, i18n } = useTranslation(); @@ -51,7 +52,8 @@ export function Preferences() { enableML, storeLocally, language, - enableSlurReplacement + enableSlurReplacement, + enableSlurMetadata } = preference; if (enable != undefined) { setEnable(enable); @@ -68,6 +70,9 @@ export function Preferences() { if (enableSlurReplacement != undefined) { setEnableSlurReplacement(enableSlurReplacement); } + if (enableSlurMetadata != undefined) { + setEnableSlurMetadata(enableSlurMetadata); + } } } } catch (err) { @@ -114,11 +119,44 @@ export function Preferences() { } } + async function handleSlurMetadata(enableSlurMetadata) { + try { + const confirmed = window.confirm( + 'This action requires a page reload. Do you want to continue?' + ); + if (confirmed) { + const tabsCurrent = await userBrowserTabs.query({ + active: true, + currentWindow: true + }); + const tabId = tabsCurrent[0].id; + + await setPreferenceData({ + ...localPreferences, + enableSlurMetadata + }); + + userBrowserTabs.sendMessage(tabId, { + type: 'ULI_ENABLE_SLUR_METADATA', + payload: enableSlurMetadata + }); + userBrowserTabs.reload(tabId); + } + } catch (error) { + console.log(error); + } + } + async function changeEnableSlurReplacementOption(checked) { console.log(checked); setEnableSlurReplacement(checked); } + async function changeEnableSlurMetadataOption(checked) { + console.log(checked); + setEnableSlurMetadata(checked); + } + async function clickSave(preference) { const preferenceInLS = await getPreferenceData(); // alert(JSON.stringify({preferenceInLS, preference})) @@ -135,17 +173,26 @@ export function Preferences() { enableML, storeLocally, language, - enableSlurReplacement + enableSlurReplacement, + enableSlurMetadata }); const enableSlurReplacementChanged = enableSlurReplacement !== preferenceInLS.enableSlurReplacement; + const enableSlurMetadataChanged = + enableSlurMetadata !== preferenceInLS.enableSlurMetadata; + if (enableSlurReplacementChanged) { console.log('enable val changed', enableSlurReplacementChanged); await handleSlurReplacement(enableSlurReplacement); } + if(enableSlurMetadataChanged){ + console.log('enable val changed', enableSlurMetadataChanged); + await handleSlurMetadata(enableSlurMetadata); + } + showNotification({ type: 'message', message: t('message_ok_saved') @@ -224,6 +271,16 @@ export function Preferences() { /> + + + changeEnableSlurMetadataOption(e.target.checked) + } + /> + + Date: Thu, 29 Aug 2024 09:45:33 +0530 Subject: [PATCH 08/19] on slurList work --- browser-extension/prototype/index3.html | 14 +- browser-extension/prototype/index4.js | 212 ++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 browser-extension/prototype/index4.js diff --git a/browser-extension/prototype/index3.html b/browser-extension/prototype/index3.html index 06c2df62..d7f9dab0 100644 --- a/browser-extension/prototype/index3.html +++ b/browser-extension/prototype/index3.html @@ -26,13 +26,25 @@ , a documentary by crazy + +

+ +

+ + + + diff --git a/browser-extension/prototype/index4.js b/browser-extension/prototype/index4.js new file mode 100644 index 00000000..9c88a883 --- /dev/null +++ b/browser-extension/prototype/index4.js @@ -0,0 +1,212 @@ +let slurList = + 'जिहादी|छक्का|छिनाल|रंडी|रण्डी|रांड|रंडीखाना|रण्डी रोना|लुल्ली|गांड|कुतिया|कुत्ती|बत्तमीज़|कुल्टा|हरामजादी|साली|चुदाई|ma ki chui|मा के भोसड़े|भोस्डीके|भोछडी वाला |लोड़ू|बहन चोद|मादरचोद|लानती|छुतीये|चूतिये |चूत|लौड़ा|लौड़े|चरित्रहीन |लिब्राण्डू|नंगी पुंगी|पागल औरत |बाज़ारू औरत|बलात्कार|बदसूरत|मुजरा|जाहिल औरत|औरत-ए-जाहिल|भोसड़ीwala|चंडाल चौकड़ी|म्लेच्छा|सूअर|सूअर की औलाद|दोगली|🏹🏹|पनौती|हरामी|गधी|बुरखा धत्त|बुल्ली |कलमुंही |पिछवाड़ा|काम वाली बाई|पैर की जूती|गंदी नाली|हगना|सुल्ली|हिज़रापंती|naachne waali|तवाइफ़|सौ टका टंच माल|किन्नर|गद्दार|चमचा|चमची|आतंकवादी|मुलिया|Katwa|चाटुकार|बहन की लोड़ी|चुस्लिम|चुस्लामि|चुसल्मान|चूस|भीमटा|भीमटी|बैल बुद्धि|हलाला|भद्दी औरत|भांड औरत|भाड़े का टट्टू|दो कौड़ी की औरत|घटिया औरत|बेहूदा औरत|चालू औरत|झूठी औरत|मर क्यों नहीं जाती|नल्ली|भूतनी के|चूत के बाल|मादरजात|भड़वा|चूची|टट्टी|गटर पैदाइश|मुँह मैं ले|मूत|नाजायज़|कटा लुंड|काला टेंट|जूता खायेगी|बुरखे वाली|काली कलूटी|काले तवे|मोटी भैंस|देहातन|देहाती औरत|गणिका|हबशी|ओला हु उबर|ABLANARI|AblaNari|ablanari|chakka|jihidis|jihadi|Jihidi|zehadi|jehadan|jihadinon|Chakko|chakki|chaka|Chinal|Randi|ramdi|Randie|randya|randikhana|randi ke beej|Lulli|Gasti|Meetha|Halwa|Gud|Gaandu|Gaand|Gandiaal|lodu|kutiya|kutti|Chudail|Badchalan|Battameez|kulta|haramjadi|dyan|saali|sali|chod|chodu bhagat|chudai|chooda|chuda|Bhdsk|2BHK|Bhosi ke|bsdk|bhonsdi ke|bhosad|bhosdiwale|maa ka bhosra|Lodu|bhenchod|Madarchod|Maderchod|mcp|mc|Lanti|chutiye|chutiya|Chut|hutiye|chutie|chutia|chut ke dhakkan|chut marli|chutan|Lavde|Gandu|Rakhail|librandu|chal phut|nangi poongi|pagal aurat|bazaru|bazari aurat|ola hi uber hai|balatkar|Ugly|Mujra|mujra|jaahil aurat|Mulli|hilana|hilaogi|Mlechcha|Suar|suar ki aulad|doghli|Panauti|panooti|harami|gadhi|रनडwa|🅱️ulli|kalmuhi|pichwada|jhadu|bai|kaam wali bai|pair ki jutti|naali|hagna|tukde tukde gang|Sulli|नाचने वाली|Tawaif|sau taka tunch maal|Skirt waali bai|Dhimmi hood|Dhimmihood|izzlam|gaddar|chamcha|chamchi|aatankwadi|Mulliya|Uncut|chatukar|Bahan Ke loudi|Kachra|Chuslim|chuslami|Chusalmans|chus|Bhimta|bheem-meem walas|bail budhi|Budhdhi|हलाला|bhadi aurat|bhanndh aurat|bhadi ka tattu|2 Kaudi ki aurat|Gatiya|Ghatiya aurat|behuda aurat|chalu aurat|jhuti aurat|Kaali aurat|Kaali bhaand|marr kyun nahi jaati|nalli|dimaag se paidal|bhootni|bhootni ke|choot ke baal|madarjaat|bhadva|bhadvi|bhandve|chuchi|tatti|maa ka boba chusu|mooh|munh mein le|mutth|najayaz paidaish|najayaz aulaad|Gutter ki paidaish|kata Lund|kala tent|joota khayegi|burkhe waali|ladki kahin ka|victim card|Aurat card|kali kalutti|Kale tawe|naali saaf kar|moti bhains|sukkhi haddi|Pataka|choodiyan pehen lo|abba ka naam|Ganika|gaand phadna|chewtypa|atrocuty_act|RandiKutiya|sulli|Rice bags|ola u uber|lovejihad|dull-it|toxic aunty|Presstitutes|libtard|bimbo|slims|Black Pepper|faggot|Sissy|whore|chrislamocommies|piddilover|Dynast Sycophants|Deshdrohi Chinese|Pak agents|Chinese Corona|Chinks|chinky|Feminazi|Mulli|halala|Half M|Scumreds|scumbags|burnol|anti national tukde|pheminist|dented-painted|Muzlim|Buzlim|Izzlam|pissfull|Simp|Bitch| Ms |sekoolar|sickular|sc0undrel|Characterless woman|Drama Queen|Ferrorists|Cunt|Slut|pussy|ugly|stupid|promiscuous|crazy|fat|fag|homo|hoe|motherfucker|sisterfucker|bastard|bint|dyke|gash|muslimette|muttah|scag|gender nigger|assfucker|boobs|boobies|Melons|lesbain|moslem|nasty|redlight|nymph|piss|pimp|poop|pube|puke|retarded|slave|sissy|ola uh uber|pu55i|pu55y|mothafuck|mothafucka|mothafuckaz|mothafucked|mothafucker|mothafuckin|mothafucking |mothafuckings|motherfuck|motherfucked|motherfucker|motherfuckin|motherfucking|motherfuckings|lesbain|lesbayn|lesbian|lesbin|lesbo|nastyslut|nastywhore|nastybitch|nastyho|Koodhi|pottai|Potta Alith|Aththai|athai|loosu|fuck|cunt'; + + + + + +function checkFalseTextNode(text, actualLengthOfText) { + let totalNewlineAndWhitespaces = 0; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { + // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; + } + } + return totalNewlineAndWhitespaces === actualLengthOfText; +} + + +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { + uliStore.push({ node: node, parent: node.parentNode }); + } + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); + } +} + + + +/* getAllTextNodes() ENDS HERE */ + + +/* locateSlur() STARTS HERE */ + +function findPositions(word, text) { + let positions = {}; + + let len = word.length + let loc = [] + let index = text.toString().indexOf(word); + while (index !== -1) { + let obj = {}; + loc.push([index, index + len]); + index = text.toString().indexOf(word, index + 1); + } + + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; + } + return positions; +} + + + +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let textnode = store.node + let text = store.node.textContent + let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block + //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent + tempParent.textContent = text; + + let slurs = []; + let slurPresentInTempParent = false; + targetWords.forEach(targetWord => { + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { + slurs.push(pos) + } + + if (tempParent.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = tempParent.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}`); + tempParent.innerHTML = replacedHTML + slurPresentInTempParent = true; + } + }) + // for(let i = 0 ; i < ) + // console.log("tempParent " , tempParent) + uliStore[i].nodeToParent = tempParent + uliStore[i].slurs = slurs; + + //O(1) complexity + if (slurPresentInTempParent) { + // parentNode.replaceChild(tempParent, textnode) + textnode.replaceWith(tempParent) + // textnode.replaceWith(createTextNode(tempParent.innerHTML)) + + } + + } + return uliStore; +} + + +/* locateSlur() ENDS HERE */ + + + + +/* addMetaData() STARTS HERE */ + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + console.log("className " , className) + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "2%" + img.style.width = "2%" + img.style.cursor = "pointer" + img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + // img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + // span.style.all = "unset" + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + // span.style.width = "12rem" + span.style.textAlign = "justify" + span.style.fontWeight = "lighter" + span.style.color = "black" + span.style.zIndex = "1000000000"; // This ensures it appears above other elements + span.style.fontSize = "14px" + span.style.textDecoration = "none" + span.style.fontStyle = "normal" + // span.style.height = "fit-content" + span.innerHTML = `This is ${targetWord}` + + // span.style.display = "none"; + // span.style.position = "absolute"; + // span.style.backgroundColor = "antiquewhite !important"; + // span.style.border = "1px solid black !important"; + // span.style.borderRadius = "12px !important"; + // span.style.padding = "2px 6px !important"; + // span.style.width = "12rem !important"; + // span.style.textAlign = "justify !important"; + // span.innerHTML = `This is ${targetWord}`; + + + + + if (targetWord.toLowerCase() === "crazy") { + span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord.toLowerCase() === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` + } + else if (targetWord.toLowerCase() === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` + } + else { + span.innerHTML = `This word is considered offensive.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + // sups.children[1].style.display = "block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + + +// let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] +let targetWords = slurList.split("|"); +targetWords = targetWords.filter((x) => x.split(" ").length == 1) ; +// let removeHash = targetWords.filter((x) => x.includes("#")===false); + +console.log(targetWords) +// console.log(oneWordTargetWords) +// console.log(targetWords) ; +let uliStore = [] +getAllTextNodes(document.body, uliStore) +abc = locateSlur(uliStore, targetWords) +// console.log("uliStore", abc) +addMetaData(targetWords) + From 9f842866be7bd4c2a4efef0dae9e5aa5106700e9 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 30 Aug 2024 09:54:02 +0530 Subject: [PATCH 09/19] updated manifest.json && deleted prototype --- browser-extension/plugin/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser-extension/plugin/manifest.json b/browser-extension/plugin/manifest.json index 1f13f924..0cd36a03 100644 --- a/browser-extension/plugin/manifest.json +++ b/browser-extension/plugin/manifest.json @@ -5,7 +5,7 @@ "version": "0.1.16", "author": "tattlemade|cis", "content_security_policy": { - "extension_pages": "default-src 'none'; connect-src http://localhost:3000 ws://localhost; font-src https://fonts.gstatic.com; object-src 'none'; script-src 'self'; style-src https://fonts.googleapis.com 'self' 'unsafe-inline'; img-src https://uli-media.tattle.co.in/; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; report-uri 'none';" + "extension_pages": "default-src 'none'; connect-src https://ogbv-plugin.tattle.co.in/ https://uli-media.tattle.co.in/; font-src https://fonts.gstatic.com; object-src 'none'; script-src 'self'; style-src https://fonts.googleapis.com 'self' 'unsafe-inline'; img-src https://uli-media.tattle.co.in/; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; report-uri 'none';" }, "permissions": [ "storage", From 463bcf592363b1027212938826f98a77e2329ed6 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 30 Aug 2024 10:07:34 +0530 Subject: [PATCH 10/19] updated manifest.json && deleted prototype --- browser-extension/prototype/index.html | 57 ------- browser-extension/prototype/index.js | 141 ---------------- browser-extension/prototype/index2.html | 39 ----- browser-extension/prototype/index2.js | 141 ---------------- browser-extension/prototype/index3.html | 51 ------ browser-extension/prototype/index3.js | 160 ------------------ browser-extension/prototype/index4.js | 212 ------------------------ browser-extension/prototype/info.png | Bin 13149 -> 0 bytes browser-extension/prototype/new.js | 28 ---- 9 files changed, 829 deletions(-) delete mode 100644 browser-extension/prototype/index.html delete mode 100644 browser-extension/prototype/index.js delete mode 100644 browser-extension/prototype/index2.html delete mode 100644 browser-extension/prototype/index2.js delete mode 100644 browser-extension/prototype/index3.html delete mode 100644 browser-extension/prototype/index3.js delete mode 100644 browser-extension/prototype/index4.js delete mode 100644 browser-extension/prototype/info.png delete mode 100644 browser-extension/prototype/new.js diff --git a/browser-extension/prototype/index.html b/browser-extension/prototype/index.html deleted file mode 100644 index e5b08797..00000000 --- a/browser-extension/prototype/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - Document - - - - -

-
- -

- Lorem ipsum dolor sit amet consectetur crazy adipisicing elit. Quaerat alias iste quo exercitationem stupid - nesciunt ea? -

- -

- - - - Lorem ipsum, dolor sit amet stupid mad adipisicing elit. Magni minima adipisci architecto. -

-
- - - -
- -
-

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa possimus quisquam temporibus - reprehenderit nesciunt dignissimos sunt ipsum, nostrum modi? Iusto libero sed alias! -

- crazy -
-
- - -

- Lorem ipsum dolor crazy Lorem, ipsum dolor. sit stupid amet consectetur adipisicing elit. Aut architecto illum dolorum - mad. -

- - - - - \ No newline at end of file diff --git a/browser-extension/prototype/index.js b/browser-extension/prototype/index.js deleted file mode 100644 index 7d1f1860..00000000 --- a/browser-extension/prototype/index.js +++ /dev/null @@ -1,141 +0,0 @@ -function checkFalseTextNode(text, actualLengthOfText) { - let totalNewlineAndWhitespaces = 0; - for (let i = 0; i < text.length; i++) { - if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode - totalNewlineAndWhitespaces++; - } - } - return totalNewlineAndWhitespaces === actualLengthOfText; -} - -// Function to recursively get all text nodes under a given node -function getAllTextNodes(node, uliStore) { - if (node.nodeType === 3) { // Text node - if (!checkFalseTextNode(node.data, node.length)) { - uliStore.push({ node: node, parent: node.parentNode }); - } - } else { - let children = Array.from(node.childNodes); - children.forEach(child => getAllTextNodes(child, uliStore)); - } -} - - -function findPositions(word, text) { - let positions = {}; - - let len = word.length - let loc = [] - let index = text.toString().indexOf(word); - while (index !== -1) { - let obj = {}; - loc.push([index, index + len]); - index = text.toString().indexOf(word, index + 1); - } - - - if (loc.length !== 0) { - positions.slurText = word - positions.slurLocation = loc; - } - return positions; -} - - -function locateSlur(uliStore, targetWords) { - let n = uliStore.length; - - for (let i = 0; i < n; i++) { - let store = uliStore[i]; //This will contain the textNode - let parentNode = store.parent - let text = store.node.textContent - //We have to look into this store for all the slurWords - let slurs = []; - - targetWords.forEach(targetWord => { - let slurWord = targetWord; - let pos = findPositions(slurWord, text); - if (Object.keys(pos).length !== 0) { - slurs.push(pos) - } - - if (parentNode.innerHTML.includes(targetWord)) { - const className = `icon-container-${targetWord}`; - const parts = parentNode.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}`); - parentNode.innerHTML = replacedHTML - } - }) - uliStore[i].slurs = slurs; - } - return uliStore; //This will return the final uliStore (after appending slurs) -} - - -function addMetaData(targetWords) { - targetWords.forEach(targetWord => { - const className = `icon-container-${targetWord}` - const elements = Array.from(document.querySelectorAll(`.${className}`)) - elements.forEach(element => { - - let sup = document.createElement("sup"); - - let img = document.createElement("img"); - img.style.height = "2%" - img.style.width = "2%" - img.style.cursor = "pointer" - // img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" - img.src = "./info.png" - img.alt = "altText" - - let span = document.createElement("span") - span.style.display = "none" - span.style.position = "absolute" - span.style.backgroundColor = "antiquewhite" - span.style.border = "1px solid black" - span.style.borderRadius = "12px" - span.style.padding = "2px 6px" - span.style.width = "12rem" - span.style.textAlign = "justify" - span.innerHTML = `This is ${targetWord}` - - - if (targetWord === "crazy") { - span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` - } - else if (targetWord === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` - } - else { - span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` - } - - - sup.appendChild(img) - sup.appendChild(span) - - element.append(sup) - let sups = element.children[0] - let spans = element.children[0].children[1] - const svgs = element.children[0].children[0]; - svgs.addEventListener('mouseover', function () { - sups.children[1].style.display = "inline-block" - }); - - svgs.addEventListener('mouseout', function () { - sups.children[1].style.display = "none" - }); - }) - }) -} - - -let targetWords = ["stupid", "crazy", "Crazy", "mad"] -let uliStore = [] -getAllTextNodes(document.body, uliStore) -abc = locateSlur(uliStore, targetWords) -console.log("uliStore", abc) -addMetaData(targetWords) diff --git a/browser-extension/prototype/index2.html b/browser-extension/prototype/index2.html deleted file mode 100644 index 5b2bf827..00000000 --- a/browser-extension/prototype/index2.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - Document - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/browser-extension/prototype/index2.js b/browser-extension/prototype/index2.js deleted file mode 100644 index bbd6c27a..00000000 --- a/browser-extension/prototype/index2.js +++ /dev/null @@ -1,141 +0,0 @@ -function checkFalseTextNode(text, actualLengthOfText) { - let totalNewlineAndWhitespaces = 0; - for (let i = 0; i < text.length; i++) { - if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode - totalNewlineAndWhitespaces++; - } - } - return totalNewlineAndWhitespaces === actualLengthOfText; -} - -// Function to recursively get all text nodes under a given node -function getAllTextNodes(node, uliStore) { - if (node.nodeType === 3) { // Text node - if (!checkFalseTextNode(node.data, node.length)) { - uliStore.push({ node: node, parent: node.parentNode }); - } - } else { - let children = Array.from(node.childNodes); - children.forEach(child => getAllTextNodes(child, uliStore)); - } -} - - -function findPositions(word, text) { - let positions = {}; - - let len = word.length - let loc = [] - let index = text.toString().indexOf(word); - while (index !== -1) { - let obj = {}; - loc.push([index, index + len]); - index = text.toString().indexOf(word, index + 1); - } - - - if (loc.length !== 0) { - positions.slurText = word - positions.slurLocation = loc; - } - return positions; -} - - -function locateSlur(uliStore, targetWords) { - let n = uliStore.length; - - for (let i = 0; i < n; i++) { - let store = uliStore[i]; //This will contain the textNode - let parentNode = store.parent - let text = store.node.textContent - //We have to look into this store for all the slurWords - let slurs = []; - - targetWords.forEach(targetWord => { - let slurWord = targetWord; - let pos = findPositions(slurWord, text); - if (Object.keys(pos).length !== 0) { - slurs.push(pos) - } - - if (parentNode.innerHTML.includes(targetWord)) { - const className = `icon-container-${targetWord}`; - const parts = parentNode.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}*`); - parentNode.innerHTML = replacedHTML - } - }) - uliStore[i].slurs = slurs; - } - return uliStore; //This will return the final uliStore (after appending slurs) -} - - -function addMetaData(targetWords) { - targetWords.forEach(targetWord => { - const className = `icon-container-${targetWord}` - const elements = Array.from(document.querySelectorAll(`.${className}`)) - elements.forEach(element => { - - let sup = document.createElement("sup"); - - let img = document.createElement("img"); - img.style.height = "2%" - img.style.width = "2%" - img.style.cursor = "pointer" - // img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" - img.src = "./info.png" - img.alt = "altText" - - let span = document.createElement("span") - span.style.display = "none" - span.style.position = "absolute" - span.style.backgroundColor = "antiquewhite" - span.style.border = "1px solid black" - span.style.borderRadius = "12px" - span.style.padding = "2px 6px" - span.style.width = "12rem" - span.style.textAlign = "justify" - span.innerHTML = `This is ${targetWord}` - - - if (targetWord === "crazy") { - span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` - } - else if (targetWord === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` - } - else { - span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` - } - - - sup.appendChild(img) - sup.appendChild(span) - - element.append(sup) - let sups = element.children[0] - let spans = element.children[0].children[1] - const svgs = element.children[0].children[0]; - svgs.addEventListener('mouseover', function () { - sups.children[1].style.display = "inline-block" - }); - - svgs.addEventListener('mouseout', function () { - sups.children[1].style.display = "none" - }); - }) - }) -} - - -let targetWords = ["stupid", "crazy", "Crazy", "mad"] -let uliStore = [] -getAllTextNodes(document.body, uliStore) -abc = locateSlur(uliStore, targetWords) -console.log("uliStore", abc) -// addMetaData(targetWords) diff --git a/browser-extension/prototype/index3.html b/browser-extension/prototype/index3.html deleted file mode 100644 index d7f9dab0..00000000 --- a/browser-extension/prototype/index3.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - Document - - - - - - - - -

- -

- - - - - - - - - - \ No newline at end of file diff --git a/browser-extension/prototype/index3.js b/browser-extension/prototype/index3.js deleted file mode 100644 index 1834978a..00000000 --- a/browser-extension/prototype/index3.js +++ /dev/null @@ -1,160 +0,0 @@ -function checkFalseTextNode(text, actualLengthOfText) { - let totalNewlineAndWhitespaces = 0; - for (let i = 0; i < text.length; i++) { - if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode - totalNewlineAndWhitespaces++; - } - } - return totalNewlineAndWhitespaces === actualLengthOfText; -} - -// Function to recursively get all text nodes under a given node -function getAllTextNodes(node, uliStore) { - if (node.nodeType === 3) { // Text node - if (!checkFalseTextNode(node.data, node.length)) { - uliStore.push({ node: node, parent: node.parentNode }); - } - } else { - let children = Array.from(node.childNodes); - children.forEach(child => getAllTextNodes(child, uliStore)); - } -} - - -function findPositions(word, text) { - let positions = {}; - - let len = word.length - let loc = [] - let index = text.toString().indexOf(word); - while (index !== -1) { - let obj = {}; - loc.push([index, index + len]); - index = text.toString().indexOf(word, index + 1); - } - - - if (loc.length !== 0) { - positions.slurText = word - positions.slurLocation = loc; - } - return positions; -} - - -function locateSlur(uliStore, targetWords) { - let n = uliStore.length; - - for (let i = 0; i < n; i++) { - let store = uliStore[i]; //This will contain the textNode - let parentNode = store.parent - let textnode = store.node - let text = store.node.textContent - let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block - //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent - tempParent.textContent = text; - //We have to look into this store for all the slurWords - let slurs = []; - - targetWords.forEach(targetWord => { - let slurWord = targetWord; - let pos = findPositions(slurWord, text); - if (Object.keys(pos).length !== 0) { - slurs.push(pos) - } - - if (tempParent.innerHTML.includes(targetWord)) { - const className = `icon-container-${targetWord}`; - const parts = tempParent.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}`); - tempParent.innerHTML = replacedHTML - } - }) - // for(let i = 0 ; i < ) - // console.log("tempParent " , tempParent) - uliStore[i].nodeToParent = tempParent - uliStore[i].slurs = slurs; - - - //Additional O(N) complexity - // parentNode.childNodes.forEach((node) => { - // if (node === textnode) { - // parentNode.replaceChild(tempParent, node) - // } - // }); - - //O(1) complexity - parentNode.replaceChild(tempParent, textnode) - - } - return uliStore; //This will return the final uliStore (after appending slurs) -} - - -function addMetaData(targetWords) { - targetWords.forEach(targetWord => { - const className = `icon-container-${targetWord}` - const elements = Array.from(document.querySelectorAll(`.${className}`)) - elements.forEach(element => { - - let sup = document.createElement("sup"); - - let img = document.createElement("img"); - img.style.height = "3%" - img.style.width = "3%" - img.style.cursor = "pointer" - img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" - // img.src = "./info.png" - img.alt = "altText" - - let span = document.createElement("span") - span.style.display = "none" - span.style.position = "absolute" - span.style.backgroundColor = "antiquewhite" - span.style.border = "1px solid black" - span.style.borderRadius = "12px" - span.style.padding = "2px 6px" - span.style.width = "12rem" - span.style.textAlign = "justify" - span.innerHTML = `This is ${targetWord}` - - - if (targetWord === "crazy") { - span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` - } - else if (targetWord === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` - } - else { - span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` - } - - - sup.appendChild(img) - sup.appendChild(span) - - element.append(sup) - let sups = element.children[0] - let spans = element.children[0].children[1] - const svgs = element.children[0].children[0]; - svgs.addEventListener('mouseover', function () { - sups.children[1].style.display = "inline-block" - }); - - svgs.addEventListener('mouseout', function () { - sups.children[1].style.display = "none" - }); - }) - }) -} - - -let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] -let uliStore = [] -getAllTextNodes(document.body, uliStore) -abc = locateSlur(uliStore, targetWords) -console.log("uliStore", abc) -addMetaData(targetWords) diff --git a/browser-extension/prototype/index4.js b/browser-extension/prototype/index4.js deleted file mode 100644 index 9c88a883..00000000 --- a/browser-extension/prototype/index4.js +++ /dev/null @@ -1,212 +0,0 @@ -let slurList = - 'जिहादी|छक्का|छिनाल|रंडी|रण्डी|रांड|रंडीखाना|रण्डी रोना|लुल्ली|गांड|कुतिया|कुत्ती|बत्तमीज़|कुल्टा|हरामजादी|साली|चुदाई|ma ki chui|मा के भोसड़े|भोस्डीके|भोछडी वाला |लोड़ू|बहन चोद|मादरचोद|लानती|छुतीये|चूतिये |चूत|लौड़ा|लौड़े|चरित्रहीन |लिब्राण्डू|नंगी पुंगी|पागल औरत |बाज़ारू औरत|बलात्कार|बदसूरत|मुजरा|जाहिल औरत|औरत-ए-जाहिल|भोसड़ीwala|चंडाल चौकड़ी|म्लेच्छा|सूअर|सूअर की औलाद|दोगली|🏹🏹|पनौती|हरामी|गधी|बुरखा धत्त|बुल्ली |कलमुंही |पिछवाड़ा|काम वाली बाई|पैर की जूती|गंदी नाली|हगना|सुल्ली|हिज़रापंती|naachne waali|तवाइफ़|सौ टका टंच माल|किन्नर|गद्दार|चमचा|चमची|आतंकवादी|मुलिया|Katwa|चाटुकार|बहन की लोड़ी|चुस्लिम|चुस्लामि|चुसल्मान|चूस|भीमटा|भीमटी|बैल बुद्धि|हलाला|भद्दी औरत|भांड औरत|भाड़े का टट्टू|दो कौड़ी की औरत|घटिया औरत|बेहूदा औरत|चालू औरत|झूठी औरत|मर क्यों नहीं जाती|नल्ली|भूतनी के|चूत के बाल|मादरजात|भड़वा|चूची|टट्टी|गटर पैदाइश|मुँह मैं ले|मूत|नाजायज़|कटा लुंड|काला टेंट|जूता खायेगी|बुरखे वाली|काली कलूटी|काले तवे|मोटी भैंस|देहातन|देहाती औरत|गणिका|हबशी|ओला हु उबर|ABLANARI|AblaNari|ablanari|chakka|jihidis|jihadi|Jihidi|zehadi|jehadan|jihadinon|Chakko|chakki|chaka|Chinal|Randi|ramdi|Randie|randya|randikhana|randi ke beej|Lulli|Gasti|Meetha|Halwa|Gud|Gaandu|Gaand|Gandiaal|lodu|kutiya|kutti|Chudail|Badchalan|Battameez|kulta|haramjadi|dyan|saali|sali|chod|chodu bhagat|chudai|chooda|chuda|Bhdsk|2BHK|Bhosi ke|bsdk|bhonsdi ke|bhosad|bhosdiwale|maa ka bhosra|Lodu|bhenchod|Madarchod|Maderchod|mcp|mc|Lanti|chutiye|chutiya|Chut|hutiye|chutie|chutia|chut ke dhakkan|chut marli|chutan|Lavde|Gandu|Rakhail|librandu|chal phut|nangi poongi|pagal aurat|bazaru|bazari aurat|ola hi uber hai|balatkar|Ugly|Mujra|mujra|jaahil aurat|Mulli|hilana|hilaogi|Mlechcha|Suar|suar ki aulad|doghli|Panauti|panooti|harami|gadhi|रनडwa|🅱️ulli|kalmuhi|pichwada|jhadu|bai|kaam wali bai|pair ki jutti|naali|hagna|tukde tukde gang|Sulli|नाचने वाली|Tawaif|sau taka tunch maal|Skirt waali bai|Dhimmi hood|Dhimmihood|izzlam|gaddar|chamcha|chamchi|aatankwadi|Mulliya|Uncut|chatukar|Bahan Ke loudi|Kachra|Chuslim|chuslami|Chusalmans|chus|Bhimta|bheem-meem walas|bail budhi|Budhdhi|हलाला|bhadi aurat|bhanndh aurat|bhadi ka tattu|2 Kaudi ki aurat|Gatiya|Ghatiya aurat|behuda aurat|chalu aurat|jhuti aurat|Kaali aurat|Kaali bhaand|marr kyun nahi jaati|nalli|dimaag se paidal|bhootni|bhootni ke|choot ke baal|madarjaat|bhadva|bhadvi|bhandve|chuchi|tatti|maa ka boba chusu|mooh|munh mein le|mutth|najayaz paidaish|najayaz aulaad|Gutter ki paidaish|kata Lund|kala tent|joota khayegi|burkhe waali|ladki kahin ka|victim card|Aurat card|kali kalutti|Kale tawe|naali saaf kar|moti bhains|sukkhi haddi|Pataka|choodiyan pehen lo|abba ka naam|Ganika|gaand phadna|chewtypa|atrocuty_act|RandiKutiya|sulli|Rice bags|ola u uber|lovejihad|dull-it|toxic aunty|Presstitutes|libtard|bimbo|slims|Black Pepper|faggot|Sissy|whore|chrislamocommies|piddilover|Dynast Sycophants|Deshdrohi Chinese|Pak agents|Chinese Corona|Chinks|chinky|Feminazi|Mulli|halala|Half M|Scumreds|scumbags|burnol|anti national tukde|pheminist|dented-painted|Muzlim|Buzlim|Izzlam|pissfull|Simp|Bitch| Ms |sekoolar|sickular|sc0undrel|Characterless woman|Drama Queen|Ferrorists|Cunt|Slut|pussy|ugly|stupid|promiscuous|crazy|fat|fag|homo|hoe|motherfucker|sisterfucker|bastard|bint|dyke|gash|muslimette|muttah|scag|gender nigger|assfucker|boobs|boobies|Melons|lesbain|moslem|nasty|redlight|nymph|piss|pimp|poop|pube|puke|retarded|slave|sissy|ola uh uber|pu55i|pu55y|mothafuck|mothafucka|mothafuckaz|mothafucked|mothafucker|mothafuckin|mothafucking |mothafuckings|motherfuck|motherfucked|motherfucker|motherfuckin|motherfucking|motherfuckings|lesbain|lesbayn|lesbian|lesbin|lesbo|nastyslut|nastywhore|nastybitch|nastyho|Koodhi|pottai|Potta Alith|Aththai|athai|loosu|fuck|cunt'; - - - - - -function checkFalseTextNode(text, actualLengthOfText) { - let totalNewlineAndWhitespaces = 0; - for (let i = 0; i < text.length; i++) { - if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { - // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode - totalNewlineAndWhitespaces++; - } - } - return totalNewlineAndWhitespaces === actualLengthOfText; -} - - -// Function to recursively get all text nodes under a given node -function getAllTextNodes(node, uliStore) { - if (node.nodeType === 3) { // Text node - if (!checkFalseTextNode(node.data, node.length)) { - uliStore.push({ node: node, parent: node.parentNode }); - } - } else { - let children = Array.from(node.childNodes); - children.forEach(child => getAllTextNodes(child, uliStore)); - } -} - - - -/* getAllTextNodes() ENDS HERE */ - - -/* locateSlur() STARTS HERE */ - -function findPositions(word, text) { - let positions = {}; - - let len = word.length - let loc = [] - let index = text.toString().indexOf(word); - while (index !== -1) { - let obj = {}; - loc.push([index, index + len]); - index = text.toString().indexOf(word, index + 1); - } - - - if (loc.length !== 0) { - positions.slurText = word - positions.slurLocation = loc; - } - return positions; -} - - - -function locateSlur(uliStore, targetWords) { - let n = uliStore.length; - - for (let i = 0; i < n; i++) { - let store = uliStore[i]; //This will contain the textNode - let parentNode = store.parent - let textnode = store.node - let text = store.node.textContent - let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block - //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent - tempParent.textContent = text; - - let slurs = []; - let slurPresentInTempParent = false; - targetWords.forEach(targetWord => { - let slurWord = targetWord; - let pos = findPositions(slurWord, text); - if (Object.keys(pos).length !== 0) { - slurs.push(pos) - } - - if (tempParent.innerHTML.includes(targetWord)) { - const className = `icon-container-${targetWord}`; - const parts = tempParent.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}`); - tempParent.innerHTML = replacedHTML - slurPresentInTempParent = true; - } - }) - // for(let i = 0 ; i < ) - // console.log("tempParent " , tempParent) - uliStore[i].nodeToParent = tempParent - uliStore[i].slurs = slurs; - - //O(1) complexity - if (slurPresentInTempParent) { - // parentNode.replaceChild(tempParent, textnode) - textnode.replaceWith(tempParent) - // textnode.replaceWith(createTextNode(tempParent.innerHTML)) - - } - - } - return uliStore; -} - - -/* locateSlur() ENDS HERE */ - - - - -/* addMetaData() STARTS HERE */ - -function addMetaData(targetWords) { - targetWords.forEach(targetWord => { - const className = `icon-container-${targetWord}` - console.log("className " , className) - const elements = Array.from(document.querySelectorAll(`.${className}`)) - elements.forEach(element => { - - let sup = document.createElement("sup"); - - let img = document.createElement("img"); - img.style.height = "2%" - img.style.width = "2%" - img.style.cursor = "pointer" - img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" - // img.src = "./info.png" - img.alt = "altText" - - let span = document.createElement("span") - // span.style.all = "unset" - span.style.display = "none" - span.style.position = "absolute" - span.style.backgroundColor = "antiquewhite" - span.style.border = "1px solid black" - span.style.borderRadius = "12px" - span.style.padding = "2px 6px" - // span.style.width = "12rem" - span.style.textAlign = "justify" - span.style.fontWeight = "lighter" - span.style.color = "black" - span.style.zIndex = "1000000000"; // This ensures it appears above other elements - span.style.fontSize = "14px" - span.style.textDecoration = "none" - span.style.fontStyle = "normal" - // span.style.height = "fit-content" - span.innerHTML = `This is ${targetWord}` - - // span.style.display = "none"; - // span.style.position = "absolute"; - // span.style.backgroundColor = "antiquewhite !important"; - // span.style.border = "1px solid black !important"; - // span.style.borderRadius = "12px !important"; - // span.style.padding = "2px 6px !important"; - // span.style.width = "12rem !important"; - // span.style.textAlign = "justify !important"; - // span.innerHTML = `This is ${targetWord}`; - - - - - if (targetWord.toLowerCase() === "crazy") { - span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord.toLowerCase() === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` - } - else if (targetWord.toLowerCase() === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` - } - else { - span.innerHTML = `This word is considered offensive.` - } - - - sup.appendChild(img) - sup.appendChild(span) - - element.append(sup) - let sups = element.children[0] - let spans = element.children[0].children[1] - const svgs = element.children[0].children[0]; - svgs.addEventListener('mouseover', function () { - sups.children[1].style.display = "inline-block" - // sups.children[1].style.display = "block" - }); - - svgs.addEventListener('mouseout', function () { - sups.children[1].style.display = "none" - }); - }) - }) -} - - - -// let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] -let targetWords = slurList.split("|"); -targetWords = targetWords.filter((x) => x.split(" ").length == 1) ; -// let removeHash = targetWords.filter((x) => x.includes("#")===false); - -console.log(targetWords) -// console.log(oneWordTargetWords) -// console.log(targetWords) ; -let uliStore = [] -getAllTextNodes(document.body, uliStore) -abc = locateSlur(uliStore, targetWords) -// console.log("uliStore", abc) -addMetaData(targetWords) - diff --git a/browser-extension/prototype/info.png b/browser-extension/prototype/info.png deleted file mode 100644 index 311011c6321e34669f055e688e9adb713e680d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13149 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 F{|E5(mn#4O diff --git a/browser-extension/prototype/new.js b/browser-extension/prototype/new.js deleted file mode 100644 index b57a9d91..00000000 --- a/browser-extension/prototype/new.js +++ /dev/null @@ -1,28 +0,0 @@ -const iconSrc = './info.svg'; -const iconAlt = 'Icon description'; -const targetWords = ['crazy', 'stupid', 'mad']; // Replace with your list of target words - -// Find all elements that contain any of the target words -document.querySelectorAll('*').forEach(element => { - targetWords.forEach(targetWord => { - if (element.innerHTML.includes(targetWord)) { - const className = `icon-container-${targetWord}`; - // Split the innerHTML into parts to handle replacements - const parts = element.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}`); - - // Update the element with the replaced content - element.innerHTML = replacedHTML; - - // Add icon after each occurrence of the target word - const iconContainers = element.querySelectorAll(`.${className}`); - iconContainers.forEach(container => { - const icon = document.createElement('img'); - icon.src = iconSrc; - icon.alt = iconAlt; - container.appendChild(icon); - - }); - } - }); -}); \ No newline at end of file From b90b1841dd7a4e242b301be9c29c5d8afa592ea5 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 30 Aug 2024 22:59:38 +0530 Subject: [PATCH 11/19] updated manifest.json to original one --- browser-extension/plugin/manifest.json | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/browser-extension/plugin/manifest.json b/browser-extension/plugin/manifest.json index 0cd36a03..0f72e6ec 100644 --- a/browser-extension/plugin/manifest.json +++ b/browser-extension/plugin/manifest.json @@ -7,32 +7,20 @@ "content_security_policy": { "extension_pages": "default-src 'none'; connect-src https://ogbv-plugin.tattle.co.in/ https://uli-media.tattle.co.in/; font-src https://fonts.gstatic.com; object-src 'none'; script-src 'self'; style-src https://fonts.googleapis.com 'self' 'unsafe-inline'; img-src https://uli-media.tattle.co.in/; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; report-uri 'none';" }, - "permissions": [ - "storage", - "contextMenus" - ], - "host_permissions": [ - "https://ogbv-plugin.tattle.co.in/*" - ], + "permissions": ["storage", "contextMenus"], + "host_permissions": ["https://ogbv-plugin.tattle.co.in/*"], "background": { "service_worker": "background.js" }, "content_scripts": [ { - "matches": [ - "" - ], - "js": [ - "content-script.js" - ], + "matches": [""], + "js": ["content-script.js"], "run_at": "document_end" } ], "action": { "default_popup": "options.html" }, - "icons": { - "16": "icon16.png", - "48": "icon32.png" - } + "icons": { "16": "icon16.png", "48": "icon32.png" } } \ No newline at end of file From 5c246f026066cbafc182b93744dc4702141ec648 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Sat, 31 Aug 2024 13:38:59 +0530 Subject: [PATCH 12/19] updating temporary slurList --- .../plugin/src/transform-general.js | 66 +++++++++++-------- .../plugin/src/ui-components/pages/App.jsx | 3 +- .../src/ui-components/pages/Preferences.jsx | 7 +- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index e9433750..2e5cc1a1 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -53,28 +53,34 @@ function setCaretPosition(element, offset) { const processNewlyAddedNodesGeneral2 = function (firstBody) { // const config = { attributes: true, childList: true, subtree: true }; - const callback = () => { - console.log("HEY THERE !!!") - let targetWords = ["Blog" , "BLOG", "Choose" , "domain", "bad", "BAD" , "Bad" , "Stupid" , "STUPID" , "stupid", "crazy", "Crazy", "mad", "Mad", "MAD" , "CRAZY"] - let uliStore = [] - // getAllTextNodes(document.body, uliStore) - getAllTextNodes(firstBody, uliStore) - console.log(uliStore) - abc = locateSlur(uliStore, targetWords) - console.log("uliStore", abc) - addMetaData(targetWords) - } - callback() ; + console.log("HEY THERE !!!") + let targetWords = ["Blog", "BLOG", "Choose", "domain", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "mad", "Mad", "MAD", "CRAZY" , "ABLANARI", "AblaNari", "ablanari", "chakka", + "jihidis", "Jihadi", "Jihidi", "zehadi", "jehadan", + "Chakko", "chakki", "chaka", "Chinal", "Randi", "ramdi", "Randie", "randya", "randikhana", + "Lulli", "Gasti", "Meetha", "Halwa", "Gud", "Gandu", "Gaand", "Gandiaal", "lodu", "kutiya" + + ] + // "जिहादी", "छक्का", "छिनाल", "रंडी", "रण्डी", "रांड", "रंडीखाना", "लुल्ली", "गांड", "कुतिया", "कुत्ती", "बत्तमीज़", "कुल्टा", "हरामजादी", "साली", "चुदाई", "भोस्डीके", "लोड़ू", "मादरचोद", "लानती", "छुतीये", "चूत", "लौड़ा", "लौड़े", "लिब्राण्डू", "पुंगी", "पागल", "बाज़ारू", "बलात्कार", "बदसूरत", "मुजरा", "औरत-ए-जाहिल", "भोसड़ीwala", "म्लेच्छा", "सूअर", "दोगली", "🏹🏹", "पनौती", "हरामी", "गधी", "पिछवाड़ा", "हगना", "सुल्ली", "हिज़रापंती", "तवाइफ़", "किन्नर", "गद्दार", "चमचा", "चमची", "आतंकवादी", "मुलिया", "Katwa", "चाटुकार", "चुस्लिम", "चुस्लामि", "चुसल्मान", "चूस", "भीमटा", "भीमटी", "बैल", "भद्दी", "भांड", "भाड़े", "नल्ली", "मादरजात", "भड़वा", "चूची", "टट्टी", "मूत", "नाजायज़", "देहातन", "देहाती", "गणिका", "हबशी", - // const observer = new MutationObserver(callback); - // observer.observe(firstBody , config); + let slurList = [ "kutti", "Badchalan", "Battameez", "kulta", "haramjadi", "dyan", "saali", "sali", "chooda", "chuda", "Bhdsk", "bsdk", "bhosad", "bhosdiwale", "Lodu", "bhenchod", "Madarchod", "Maderchod", "mcp", "mc", "Lanti", "chutiye", "chutiya", "chutie", "chutia", "chutan", "Lavde","Rakhail", "librandu", "bazaru", "balatkar", "Ugly", "Mujra", "mujra", "hilana", "hilaogi", "Mlechcha", "Suar", "doghli", "Panauti", "panooti", "harami", "gadhi", "kalmuhi", "pichwada", "jhadu", "bai", "naali", "hagna", "Sulli", "Tawaif", "Dhimmihood", "izzlam", "gaddar", "chamcha", "chamchi", "aatankwadi", "Mulliya", "Uncut", "chatukar", "Kachra", "Chuslim", "chuslami", "Chusalmans", "Bhimta", "Budhdhi", "Gatiya", "nalli", "bhootni", "madarjaat", "bhadva", "bhadvi", "bhandve", "chuchi", "tatti", "mooh", "mutth", "Pataka", "Ganika", "chewtypa", "atrocuty_act", "RandiKutiya", "sulli", "lovejihad", "dull-it", "Presstitutes", "libtard", "bimbo", "slims", "faggot", "Sissy", "whore", "chrislamocommies", "piddilover", "Chinks", "chinky", "Feminazi", "Mulli", "halala", "Scumreds", "scumbags", "burnol", "pheminist", "dented-painted", "Muzlim", "Buzlim", "Izzlam", "pissfull", "Simp", "Bitch", "sekoolar", "sickular", "Ferrorists", "Cunt", "Slut", "pussy", "ugly", "promiscuous", "fat", "fag", "homo", "hoe", "motherfucker", "sisterfucker", "bastard", "bint", "dyke", "gash", "muslimette", "muttah", "scag", "assfucker", "boobs", "boobies", "Melons", "lesbain", "moslem", "nasty", "redlight", "nymph", "piss", "pimp", "poop", "pube", "puke", "retarded", "slave", "sissy", "mothafucka", "mothafucked", "mothafucker", "motherfucked", "motherfucking", "lesbain", "lesbayn", "lesbian", "lesbin", "lesbo", "nastyslut", "nastywhore", "nastybitch", "nastyho", "Koodhi", "pottai", "Aththai", "athai", "loosu", "fuck", "cunt", "stupid", "Stupid", "crazy", "Crazy", "mad", "MAD"]; + // let targetWords = slurList ; + let uliStore = [] + // getAllTextNodes(document.body, uliStore) + getAllTextNodes(firstBody, uliStore) + // console.log(uliStore) + abc = locateSlur(uliStore, targetWords) + // console.log("uliStore", abc) + addMetaData(targetWords) } + + + const processNewlyAddedNodesGeneral = function (firstBody) { log('processing new nodes'); const config = { attributes: true, childList: true, subtree: true }; @@ -177,7 +183,8 @@ function locateSlur(uliStore, targetWords) { if (Object.keys(pos).length !== 0) { slurs.push(pos) } - + + if (tempParent.innerHTML.includes(targetWord)) { const className = `icon-container-${targetWord}`; const parts = tempParent.innerHTML.split(targetWord); @@ -214,6 +221,7 @@ function locateSlur(uliStore, targetWords) { function addMetaData(targetWords) { targetWords.forEach(targetWord => { const className = `icon-container-${targetWord}` + console.log(className) const elements = Array.from(document.querySelectorAll(`.${className}`)) elements.forEach(element => { @@ -223,7 +231,9 @@ function addMetaData(targetWords) { img.style.height = "2%" img.style.width = "2%" img.style.cursor = "pointer" + img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + // img.src = "./icon16.png" // img.src = "./info.png" img.alt = "altText" @@ -259,18 +269,20 @@ function addMetaData(targetWords) { - if (targetWord.toLowerCase() === "crazy") { - span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord.toLowerCase() === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` - } - else if (targetWord.toLowerCase() === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` - } - else { - span.innerHTML = `This word is considered offensive.` - } + // if (targetWord.toLowerCase() === "crazy") { + // span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + // } + // else if (targetWord.toLowerCase() === "mad") { + // span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` + // } + // else if (targetWord.toLowerCase() === 'stupid') { + // span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` + // } + // else { + // + // } + + span.innerHTML = `This word is considered offensive.` sup.appendChild(img) diff --git a/browser-extension/plugin/src/ui-components/pages/App.jsx b/browser-extension/plugin/src/ui-components/pages/App.jsx index ced7519b..a4165a48 100644 --- a/browser-extension/plugin/src/ui-components/pages/App.jsx +++ b/browser-extension/plugin/src/ui-components/pages/App.jsx @@ -78,7 +78,8 @@ export function App() { setUser(user); setAccountActivated(true); await setPreferenceData({ - enableSlurReplacement: true + enableSlurReplacement: true, + enableSlurMetadata: false }); userBrowserTabs.reload(); navigate('/preferences'); diff --git a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx index e6bfbde1..8eb2e42d 100644 --- a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx +++ b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx @@ -40,6 +40,7 @@ export function Preferences() { async function getPrefsLocalStorage() { try { const preference = await getPreferenceData(); + console.log("preference " , preference) if (!ignore) { // console.log({ preference }); setLocalPreferences(preference); @@ -93,6 +94,8 @@ export function Preferences() { async function handleSlurReplacement(enableSlurReplacement) { try { + setEnableSlurMetadata(false); + const confirmed = window.confirm( 'This action requires a page reload. Do you want to continue?' ); @@ -121,6 +124,8 @@ export function Preferences() { async function handleSlurMetadata(enableSlurMetadata) { try { + setEnableSlurReplacement(false) + const confirmed = window.confirm( 'This action requires a page reload. Do you want to continue?' ); @@ -181,7 +186,7 @@ export function Preferences() { enableSlurReplacement !== preferenceInLS.enableSlurReplacement; const enableSlurMetadataChanged = - enableSlurMetadata !== preferenceInLS.enableSlurMetadata; + enableSlurMetadata !== preferenceInLS.enableSlurMetadata; if (enableSlurReplacementChanged) { console.log('enable val changed', enableSlurReplacementChanged); From 3c7087d3992c7059741b92ba9b6bb76c380cca2c Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Sat, 31 Aug 2024 15:20:06 +0530 Subject: [PATCH 13/19] updating slurList v 1.0.0 --- .../plugin/src/transform-general.js | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index 2e5cc1a1..b58012cd 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -53,34 +53,21 @@ function setCaretPosition(element, offset) { const processNewlyAddedNodesGeneral2 = function (firstBody) { // const config = { attributes: true, childList: true, subtree: true }; - console.log("HEY THERE !!!") - let targetWords = ["Blog", "BLOG", "Choose", "domain", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "mad", "Mad", "MAD", "CRAZY" , "ABLANARI", "AblaNari", "ablanari", "chakka", - "jihidis", "Jihadi", "Jihidi", "zehadi", "jehadan", - "Chakko", "chakki", "chaka", "Chinal", "Randi", "ramdi", "Randie", "randya", "randikhana", - "Lulli", "Gasti", "Meetha", "Halwa", "Gud", "Gandu", "Gaand", "Gandiaal", "lodu", "kutiya" - - ] - - // "जिहादी", "छक्का", "छिनाल", "रंडी", "रण्डी", "रांड", "रंडीखाना", "लुल्ली", "गांड", "कुतिया", "कुत्ती", "बत्तमीज़", "कुल्टा", "हरामजादी", "साली", "चुदाई", "भोस्डीके", "लोड़ू", "मादरचोद", "लानती", "छुतीये", "चूत", "लौड़ा", "लौड़े", "लिब्राण्डू", "पुंगी", "पागल", "बाज़ारू", "बलात्कार", "बदसूरत", "मुजरा", "औरत-ए-जाहिल", "भोसड़ीwala", "म्लेच्छा", "सूअर", "दोगली", "🏹🏹", "पनौती", "हरामी", "गधी", "पिछवाड़ा", "हगना", "सुल्ली", "हिज़रापंती", "तवाइफ़", "किन्नर", "गद्दार", "चमचा", "चमची", "आतंकवादी", "मुलिया", "Katwa", "चाटुकार", "चुस्लिम", "चुस्लामि", "चुसल्मान", "चूस", "भीमटा", "भीमटी", "बैल", "भद्दी", "भांड", "भाड़े", "नल्ली", "मादरजात", "भड़वा", "चूची", "टट्टी", "मूत", "नाजायज़", "देहातन", "देहाती", "गणिका", "हबशी", - - let slurList = [ "kutti", "Badchalan", "Battameez", "kulta", "haramjadi", "dyan", "saali", "sali", "chooda", "chuda", "Bhdsk", "bsdk", "bhosad", "bhosdiwale", "Lodu", "bhenchod", "Madarchod", "Maderchod", "mcp", "mc", "Lanti", "chutiye", "chutiya", "chutie", "chutia", "chutan", "Lavde","Rakhail", "librandu", "bazaru", "balatkar", "Ugly", "Mujra", "mujra", "hilana", "hilaogi", "Mlechcha", "Suar", "doghli", "Panauti", "panooti", "harami", "gadhi", "kalmuhi", "pichwada", "jhadu", "bai", "naali", "hagna", "Sulli", "Tawaif", "Dhimmihood", "izzlam", "gaddar", "chamcha", "chamchi", "aatankwadi", "Mulliya", "Uncut", "chatukar", "Kachra", "Chuslim", "chuslami", "Chusalmans", "Bhimta", "Budhdhi", "Gatiya", "nalli", "bhootni", "madarjaat", "bhadva", "bhadvi", "bhandve", "chuchi", "tatti", "mooh", "mutth", "Pataka", "Ganika", "chewtypa", "atrocuty_act", "RandiKutiya", "sulli", "lovejihad", "dull-it", "Presstitutes", "libtard", "bimbo", "slims", "faggot", "Sissy", "whore", "chrislamocommies", "piddilover", "Chinks", "chinky", "Feminazi", "Mulli", "halala", "Scumreds", "scumbags", "burnol", "pheminist", "dented-painted", "Muzlim", "Buzlim", "Izzlam", "pissfull", "Simp", "Bitch", "sekoolar", "sickular", "Ferrorists", "Cunt", "Slut", "pussy", "ugly", "promiscuous", "fat", "fag", "homo", "hoe", "motherfucker", "sisterfucker", "bastard", "bint", "dyke", "gash", "muslimette", "muttah", "scag", "assfucker", "boobs", "boobies", "Melons", "lesbain", "moslem", "nasty", "redlight", "nymph", "piss", "pimp", "poop", "pube", "puke", "retarded", "slave", "sissy", "mothafucka", "mothafucked", "mothafucker", "motherfucked", "motherfucking", "lesbain", "lesbayn", "lesbian", "lesbin", "lesbo", "nastyslut", "nastywhore", "nastybitch", "nastyho", "Koodhi", "pottai", "Aththai", "athai", "loosu", "fuck", "cunt", "stupid", "Stupid", "crazy", "Crazy", "mad", "MAD"]; - + let targetWords = ["Blog", "BLOG", "Choose", "domain", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "mad", "Mad", "MAD", "CRAZY","ABLANARI","AblaNari","ablanari","chakka","jihidis","Jihadi","jihadi","Jihidi","zehadi","jehadan","jihadinon","Chakko","chakki","chaka","Chinal","Randi","ramdi","randya","Lulli","Gasti","Meetha","Halwa","Gud","Gandu","Gaand","Gandiaal","lodu"] // let targetWords = slurList ; let uliStore = [] // getAllTextNodes(document.body, uliStore) getAllTextNodes(firstBody, uliStore) - // console.log(uliStore) + console.log(uliStore) abc = locateSlur(uliStore, targetWords) - // console.log("uliStore", abc) + console.log("uliStore", abc) addMetaData(targetWords) } - - const processNewlyAddedNodesGeneral = function (firstBody) { log('processing new nodes'); const config = { attributes: true, childList: true, subtree: true }; @@ -183,8 +170,7 @@ function locateSlur(uliStore, targetWords) { if (Object.keys(pos).length !== 0) { slurs.push(pos) } - - + if (tempParent.innerHTML.includes(targetWord)) { const className = `icon-container-${targetWord}`; const parts = tempParent.innerHTML.split(targetWord); @@ -221,7 +207,6 @@ function locateSlur(uliStore, targetWords) { function addMetaData(targetWords) { targetWords.forEach(targetWord => { const className = `icon-container-${targetWord}` - console.log(className) const elements = Array.from(document.querySelectorAll(`.${className}`)) elements.forEach(element => { @@ -269,20 +254,18 @@ function addMetaData(targetWords) { - // if (targetWord.toLowerCase() === "crazy") { - // span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - // } - // else if (targetWord.toLowerCase() === "mad") { - // span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` - // } - // else if (targetWord.toLowerCase() === 'stupid') { - // span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` - // } - // else { - // - // } - - span.innerHTML = `This word is considered offensive.` + if (targetWord.toLowerCase() === "crazy") { + span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord.toLowerCase() === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` + } + else if (targetWord.toLowerCase() === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` + } + else { + span.innerHTML = `This word is considered offensive.` + } sup.appendChild(img) From d71f0ba1e5ef609464c5e7c99ee4c9d5870c1218 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Thu, 5 Sep 2024 10:33:31 +0530 Subject: [PATCH 14/19] uli icon updated --- browser-extension/plugin/src/content-script.js | 9 +++++---- browser-extension/plugin/src/transform-general.js | 9 +++++---- .../plugin/src/ui-components/pages/Preferences.jsx | 10 ++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/browser-extension/plugin/src/content-script.js b/browser-extension/plugin/src/content-script.js index 2e581e82..28c1ee15 100644 --- a/browser-extension/plugin/src/content-script.js +++ b/browser-extension/plugin/src/content-script.js @@ -153,14 +153,15 @@ window.addEventListener( const pref = await getPreferenceData(); // console.log(pref); const { enableSlurReplacement , enableSlurMetadata } = pref; - if (enableSlurReplacement) { - processPage(location.href); - } - else if (enableSlurMetadata) { + if (enableSlurMetadata) { let body = document.getElementsByTagName('body'); let first_body = body[0]; transformGeneral.processNewlyAddedNodesGeneral2(first_body); } + else if (enableSlurReplacement) { + processPage(location.href); + } + }, false ); diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index b58012cd..d3e2b5ec 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -54,7 +54,7 @@ const processNewlyAddedNodesGeneral2 = function (firstBody) { // const config = { attributes: true, childList: true, subtree: true }; console.log("HEY THERE !!!") - let targetWords = ["Blog", "BLOG", "Choose", "domain", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "mad", "Mad", "MAD", "CRAZY","ABLANARI","AblaNari","ablanari","chakka","jihidis","Jihadi","jihadi","Jihidi","zehadi","jehadan","jihadinon","Chakko","chakki","chaka","Chinal","Randi","ramdi","randya","Lulli","Gasti","Meetha","Halwa","Gud","Gandu","Gaand","Gandiaal","lodu"] + let targetWords = ["Blog", "BLOG", "Choose", "domain", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "idiot" , "Idiot" , "IDIOT", "CRAZY","ABLANARI","AblaNari","ablanari","chakka","jihidis","Jihadi","jihadi","Jihidi","zehadi","jehadan","jihadinon","Chakko","chakki","chaka","Chinal","Randi","ramdi","randya","Lulli","Gasti","Meetha","Halwa","Gud","Gandu","Gaand","Gandiaal","lodu"] // let targetWords = slurList ; let uliStore = [] @@ -213,11 +213,12 @@ function addMetaData(targetWords) { let sup = document.createElement("sup"); let img = document.createElement("img"); - img.style.height = "2%" - img.style.width = "2%" + img.style.height = "1.5%" + img.style.width = "1.5%" + img.style.border = "1px solid black" img.style.cursor = "pointer" - img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + img.src = "https://raw.githubusercontent.com/tattle-made/Uli/main/uli-website/src/images/favicon-32x32.png" // img.src = "./icon16.png" // img.src = "./info.png" img.alt = "altText" diff --git a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx index 8eb2e42d..af1d5965 100644 --- a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx +++ b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx @@ -94,7 +94,7 @@ export function Preferences() { async function handleSlurReplacement(enableSlurReplacement) { try { - setEnableSlurMetadata(false); + // setEnableSlurMetadata(false); const confirmed = window.confirm( 'This action requires a page reload. Do you want to continue?' @@ -108,7 +108,8 @@ export function Preferences() { await setPreferenceData({ ...localPreferences, - enableSlurReplacement + enableSlurReplacement, + // enableSlurMetadata }); userBrowserTabs.sendMessage(tabId, { @@ -124,7 +125,7 @@ export function Preferences() { async function handleSlurMetadata(enableSlurMetadata) { try { - setEnableSlurReplacement(false) + // setEnableSlurReplacement(false) const confirmed = window.confirm( 'This action requires a page reload. Do you want to continue?' @@ -138,7 +139,8 @@ export function Preferences() { await setPreferenceData({ ...localPreferences, - enableSlurMetadata + enableSlurMetadata, + // enableSlurReplacement }); userBrowserTabs.sendMessage(tabId, { From c26675e75a7a3796122b4c163db7faf31be448ba Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 6 Sep 2024 23:07:21 +0530 Subject: [PATCH 15/19] added tests for EnableSlurMetadata functions --- browser-extension/plugin/package-lock.json | 684 +++++++++++++++++- browser-extension/plugin/package.json | 5 + .../plugin/src/transform-general.js | 10 +- .../plugin/test/enableSlurMetadata.test.js | 249 +++++++ .../plugin/test/slurDetection.js | 197 +++++ 5 files changed, 1137 insertions(+), 8 deletions(-) create mode 100644 browser-extension/plugin/test/enableSlurMetadata.test.js create mode 100644 browser-extension/plugin/test/slurDetection.js diff --git a/browser-extension/plugin/package-lock.json b/browser-extension/plugin/package-lock.json index afe69d03..5dd5a5da 100644 --- a/browser-extension/plugin/package-lock.json +++ b/browser-extension/plugin/package-lock.json @@ -34,6 +34,8 @@ "eslint-plugin-react": "7.33.2", "husky": "8.0.3", "jest": "29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jsdom": "^25.0.0", "lint-staged": "15.1.0", "parcel": "2.10.3", "prettier": "3.1.0", @@ -3512,6 +3514,15 @@ "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", "dev": true }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", @@ -3601,6 +3612,17 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, "node_modules/@types/node": { "version": "20.9.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", @@ -3616,6 +3638,12 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.31", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.31.tgz", @@ -3647,6 +3675,13 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true + }, "node_modules/abortcontroller-polyfill": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", @@ -3665,6 +3700,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -3674,6 +3719,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", @@ -4794,6 +4851,30 @@ "optional": true, "peer": true }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "dev": true, + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -4809,6 +4890,53 @@ "node": ">= 14" } }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -4840,6 +4968,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "node_modules/dedent": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", @@ -5029,6 +5163,28 @@ } ] }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", @@ -6129,6 +6285,18 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -6210,9 +6378,9 @@ } }, "node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "dependencies": { "agent-base": "^7.1.0", @@ -6223,9 +6391,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -6281,6 +6449,18 @@ "@babel/runtime": "^7.23.2" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -6621,6 +6801,12 @@ "node": ">=8" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -7077,6 +7263,237 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-environment-jsdom": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", + "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -7492,6 +7909,101 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", + "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", + "dev": true, + "dependencies": { + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.4", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsdom/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -8490,6 +9002,12 @@ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", "dev": true }, + "node_modules/nwsapi": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", + "dev": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8785,6 +9303,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -9117,6 +9659,12 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -9184,6 +9732,12 @@ } ] }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9365,6 +9919,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -9468,6 +10028,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9551,6 +10117,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -10112,6 +10696,12 @@ "node": ">= 10" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/tar-fs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", @@ -10204,6 +10794,30 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -10423,6 +11037,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/urlpattern-polyfill": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", @@ -10460,6 +11084,18 @@ "node": ">=0.10.0" } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -10481,6 +11117,27 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -10678,6 +11335,21 @@ } } }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/browser-extension/plugin/package.json b/browser-extension/plugin/package.json index 576b2708..34b78467 100644 --- a/browser-extension/plugin/package.json +++ b/browser-extension/plugin/package.json @@ -18,6 +18,9 @@ "dev:chrome": "mkdir -p dist && concurrently \"npm run start:options\" \"npm run start:contentScript\" \"npm run moveBuildArtefactsToDistDir\"", "dev:clean": "rm -rf dist/" }, + "jest": { + "testEnvironment": "jsdom" + }, "keywords": [], "author": "", "license": "ISC", @@ -29,6 +32,8 @@ "eslint-plugin-react": "7.33.2", "husky": "8.0.3", "jest": "29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jsdom": "^25.0.0", "lint-staged": "15.1.0", "parcel": "2.10.3", "prettier": "3.1.0", diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index d3e2b5ec..eaa2de1b 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -2,6 +2,7 @@ import { replaceSlur } from './slur-replace'; import { log } from './logger'; import repository from './repository'; const { getPreferenceData } = repository; +import {slurJSON} from '../../api-server/assets/slur_metadata.json' // Traverse dom nodes to find leaf node that are text nodes and process function bft(node) { @@ -258,7 +259,7 @@ function addMetaData(targetWords) { if (targetWord.toLowerCase() === "crazy") { span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` } - else if (targetWord.toLowerCase() === "mad") { + else if (targetWord.toLowerCase() === "idiot") { span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` } else if (targetWord.toLowerCase() === 'stupid') { @@ -296,7 +297,12 @@ function addMetaData(targetWords) { export default { processNewlyAddedNodesGeneral, - processNewlyAddedNodesGeneral2 + processNewlyAddedNodesGeneral2, + addMetaData, + locateSlur, + findPositions, + getAllTextNodes, + checkFalseTextNode }; diff --git a/browser-extension/plugin/test/enableSlurMetadata.test.js b/browser-extension/plugin/test/enableSlurMetadata.test.js new file mode 100644 index 00000000..7477d3b6 --- /dev/null +++ b/browser-extension/plugin/test/enableSlurMetadata.test.js @@ -0,0 +1,249 @@ +const { TextEncoder, TextDecoder } = require('util'); +global.TextEncoder = TextEncoder; +global.TextDecoder = TextDecoder; + +const { findPositions, locateSlur, addMetaData, checkFalseTextNode, getAllTextNodes } = require('./slurDetection.js'); +const { JSDOM } = require('jsdom'); + +jest.mock('./slurDetection.js', () => { + const actualModule = jest.requireActual('./slurDetection.js'); + return { + ...actualModule, + checkFalseTextNode: jest.fn() + }; +}); + +describe('getAllTextNodes', () => { + let dom; + + beforeEach(() => { + dom = new JSDOM(` + + +
+

Valid text node 1

+ Valid text node 2 +
+ Valid text node 3 +
+
+ + + `); + + checkFalseTextNode.mockImplementation((text, length) => { + return text.trim().length === 0; + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should collect all valid text nodes', () => { + const root = dom.window.document.querySelector('#root'); + const uliStore = []; + + getAllTextNodes(root, uliStore); + + expect(uliStore.length).toBe(3); + + expect(uliStore[0].node.textContent.trim()).toBe('Valid text node 1'); + expect(uliStore[1].node.textContent.trim()).toBe('Valid text node 2'); + }); + + it('should ignore text nodes that only contain whitespace', () => { + const root = dom.window.document.querySelector('#root'); + const uliStore = []; + + getAllTextNodes(root, uliStore); + + uliStore.forEach(item => { + expect(item.node.textContent.trim()).not.toBe(''); + }); + }); + + it('should correctly associate the parent node with the text node', () => { + const root = dom.window.document.querySelector('#root'); + const uliStore = []; + + getAllTextNodes(root, uliStore); + + expect(uliStore[0].parent.tagName).toBe('P'); + expect(uliStore[1].parent.tagName).toBe('SPAN'); + }); +}); + +describe('locateSlur', () => { + function setupMockDOM(uliStore) { + uliStore.forEach(store => { + const parentElement = document.createElement('div'); + const textNode = document.createTextNode(store.text); + + parentElement.appendChild(textNode); + store.parent = parentElement; + store.node = textNode; + + document.body.appendChild(parentElement); + }); + } + + beforeEach(() => { + document.body.innerHTML = ''; + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('replaces target words with annotated spans and updates the DOM correctly', () => { + const targetWords = ['crazy', 'mad']; + + const uliStore = [ + { text: 'This is a crazy situation.', parent: null, node: null }, + { text: 'Don\'t be mad at me!', parent: null, node: null }, + { text: 'This is a normal sentence.', parent: null, node: null } + ]; + + setupMockDOM(uliStore); + + const result = locateSlur(uliStore, targetWords); + + const firstParentElement = result[0].parent; + expect(firstParentElement.innerHTML).toContain('crazy'); + + const secondParentElement = result[1].parent; + expect(secondParentElement.innerHTML).toContain('mad'); + + const thirdParentElement = result[2].parent; + expect(thirdParentElement.innerHTML).toBe('This is a normal sentence.'); + + expect(firstParentElement.querySelector('span')).not.toBeNull(); + expect(secondParentElement.querySelector('span')).not.toBeNull(); + + expect(firstParentElement.textContent).toContain('crazy'); + expect(secondParentElement.textContent).toContain('mad'); + }); + + it('returns the updated uliStore with the correct slur positions', () => { + const targetWords = ['stupid']; + + const uliStore = [ + { text: 'This is a stupid mistake.', parent: null, node: null } + ]; + + setupMockDOM(uliStore); + + const result = locateSlur(uliStore, targetWords); + + const slurs = result[0].slurs; + expect(slurs).toHaveLength(1); + expect(slurs[0]).toHaveProperty('slurText'); + + const parentElement = result[0].parent; + expect(parentElement.innerHTML).toContain('stupid'); + }); +}); + +describe('findPositions', () => { + test('finds positions of a single occurrence of a word', () => { + const result = findPositions('word', 'This is a word in a sentence.'); + expect(result).toEqual({ + slurText: 'word', + slurLocation: [[10, 14]] + }); + }); + + test('finds positions of multiple occurrences of a word', () => { + const result = findPositions('test', 'This test is just a test.'); + expect(result).toEqual({ + slurText: 'test', + slurLocation: [[5, 9], [20, 24]] + }); + }); + + test('returns an empty object if the word is not found', () => { + const result = findPositions('missing', 'This sentence has no such word.'); + expect(result).toEqual({}); + }); +}); + +describe('checkFalseTextNode', () => { + test('returns true for text nodes with only spaces', () => { + expect(checkFalseTextNode(" ", 4)).toBe(true); + }); + + test('returns true for text nodes with newline characters', () => { + expect(checkFalseTextNode("\n\n", 2)).toBe(true); + }); + + test('returns false for text nodes with non-whitespace characters', () => { + expect(checkFalseTextNode("text\n ", 5)).toBe(false); + }); + + test('returns true for text nodes with mixed spaces and tabs', () => { + expect(checkFalseTextNode(" \t \t", 4)).toBe(true); + }); +}); + +describe('addMetaData', () => { + beforeEach(() => { + document.body.innerHTML = ` +
crazy
+
mad
+
stupid
+ `; + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('adds metadata with tooltip for target words', () => { + const targetWords = ['crazy', 'mad', 'stupid']; + + addMetaData(targetWords); + + targetWords.forEach(targetWord => { + const element = document.querySelector(`.icon-container-${targetWord}`); + expect(element).not.toBeNull(); + + const sup = element.querySelector('sup'); + expect(sup).not.toBeNull(); + + const img = sup.querySelector('img'); + expect(img).not.toBeNull(); + expect(img.src).toContain('Minimalist_info_Icon.png'); + + const span = sup.querySelector('span'); + expect(span).not.toBeNull(); + expect(span.style.display).toBe('none'); + + if (targetWord === 'crazy') { + expect(span.textContent).toContain('perpetuate stereotypes about mental health'); + } else if (targetWord === 'mad') { + expect(span.textContent).toContain('Using "mad" to describe someone negatively can be insensitive'); + } else if (targetWord === 'stupid') { + expect(span.textContent).toContain('Describing actions or decisions as "stupid" can be demeaning'); + } + }); + }); + + it('displays and hides tooltip on mouseover and mouseout', () => { + const targetWords = ['crazy']; + + addMetaData(targetWords); + + const element = document.querySelector('.icon-container-crazy'); + const img = element.querySelector('img'); + const span = element.querySelector('span'); + + const mouseOverEvent = new Event('mouseover'); + img.dispatchEvent(mouseOverEvent); + expect(span.style.display).toBe('inline-block'); + + const mouseOutEvent = new Event('mouseout'); + img.dispatchEvent(mouseOutEvent); + expect(span.style.display).toBe('none'); + }); +}); diff --git a/browser-extension/plugin/test/slurDetection.js b/browser-extension/plugin/test/slurDetection.js new file mode 100644 index 00000000..e2589fc8 --- /dev/null +++ b/browser-extension/plugin/test/slurDetection.js @@ -0,0 +1,197 @@ + +/* getAllTextNodes() STARTS HERE */ + +function checkFalseTextNode(text, actualLengthOfText) { + let totalNewlineAndWhitespaces = 0; + for (let i = 0; i < text.length; i++) { + if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { + // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode + totalNewlineAndWhitespaces++; + } + } + return totalNewlineAndWhitespaces === actualLengthOfText; +} + + +// Function to recursively get all text nodes under a given node +function getAllTextNodes(node, uliStore) { + if (node.nodeType === 3) { // Text node + if (!checkFalseTextNode(node.data, node.length)) { + uliStore.push({ node: node, parent: node.parentNode }); + } + } else { + let children = Array.from(node.childNodes); + children.forEach(child => getAllTextNodes(child, uliStore)); + } +} + + + +/* getAllTextNodes() ENDS HERE */ + + +/* locateSlur() STARTS HERE */ + +function findPositions(word, text) { + let positions = {}; + + let len = word.length + let loc = [] + let index = text.toString().indexOf(word); + while (index !== -1) { + let obj = {}; + loc.push([index, index + len]); + index = text.toString().indexOf(word, index + 1); + } + + + if (loc.length !== 0) { + positions.slurText = word + positions.slurLocation = loc; + } + return positions; +} + + + +function locateSlur(uliStore, targetWords) { + let n = uliStore.length; + + for (let i = 0; i < n; i++) { + let store = uliStore[i]; //This will contain the textNode + let parentNode = store.parent + let textnode = store.node + let text = store.node.textContent + let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block + //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent + tempParent.textContent = text; + + let slurs = []; + let slurPresentInTempParent = false; + targetWords.forEach(targetWord => { + let slurWord = targetWord; + let pos = findPositions(slurWord, text); + if (Object.keys(pos).length !== 0) { + slurs.push(pos) + } + + if (tempParent.innerHTML.includes(targetWord)) { + const className = `icon-container-${targetWord}`; + const parts = tempParent.innerHTML.split(targetWord); + const replacedHTML = parts.join(`${targetWord}`); + tempParent.innerHTML = replacedHTML + slurPresentInTempParent = true; + } + }) + // for(let i = 0 ; i < ) + // console.log("tempParent " , tempParent) + uliStore[i].nodeToParent = tempParent + uliStore[i].slurs = slurs; + + //O(1) complexity + if (slurPresentInTempParent) { + // parentNode.replaceChild(tempParent, textnode) + textnode.replaceWith(tempParent) + // textnode.replaceWith(createTextNode(tempParent.innerHTML)) + + } + + } + return uliStore; +} + + +/* locateSlur() ENDS HERE */ + + + + +/* addMetaData() STARTS HERE */ + +function addMetaData(targetWords) { + targetWords.forEach(targetWord => { + const className = `icon-container-${targetWord}` + const elements = Array.from(document.querySelectorAll(`.${className}`)) + elements.forEach(element => { + + let sup = document.createElement("sup"); + + let img = document.createElement("img"); + img.style.height = "2%" + img.style.width = "2%" + img.style.cursor = "pointer" + img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" + // img.src = "./info.png" + img.alt = "altText" + + let span = document.createElement("span") + // span.style.all = "unset" + span.style.display = "none" + span.style.position = "absolute" + span.style.backgroundColor = "antiquewhite" + span.style.border = "1px solid black" + span.style.borderRadius = "12px" + span.style.padding = "2px 6px" + // span.style.width = "12rem" + span.style.textAlign = "justify" + span.style.fontWeight = "lighter" + span.style.color = "black" + span.style.zIndex = "1000000000"; // This ensures it appears above other elements + span.style.fontSize = "14px" + span.style.textDecoration = "none" + span.style.fontStyle = "normal" + // span.style.height = "fit-content" + span.innerHTML = `This is ${targetWord}` + + // span.style.display = "none"; + // span.style.position = "absolute"; + // span.style.backgroundColor = "antiquewhite !important"; + // span.style.border = "1px solid black !important"; + // span.style.borderRadius = "12px !important"; + // span.style.padding = "2px 6px !important"; + // span.style.width = "12rem !important"; + // span.style.textAlign = "justify !important"; + // span.innerHTML = `This is ${targetWord}`; + + + + + if (targetWord.toLowerCase() === "crazy") { + span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` + } + else if (targetWord.toLowerCase() === "mad") { + span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` + } + else if (targetWord.toLowerCase() === 'stupid') { + span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` + } + else { + span.innerHTML = `This word is considered offensive.` + } + + + sup.appendChild(img) + sup.appendChild(span) + + element.append(sup) + let sups = element.children[0] + let spans = element.children[0].children[1] + const svgs = element.children[0].children[0]; + svgs.addEventListener('mouseover', function () { + sups.children[1].style.display = "inline-block" + // sups.children[1].style.display = "block" + }); + + svgs.addEventListener('mouseout', function () { + sups.children[1].style.display = "none" + }); + }) + }) +} + + +/* addMetaData() ENDS HERE */ + + + +module.exports = { addMetaData, locateSlur, findPositions, getAllTextNodes, checkFalseTextNode } \ No newline at end of file From 1067024c0b85d1348ff44412209e884556a986cf Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Sun, 8 Sep 2024 16:36:10 +0530 Subject: [PATCH 16/19] integrated slur_metadata.json --- .../api-server/assets/slur_metadata.json | 287 +++++++++++------- .../plugin/src/transform-general.js | 86 ++++-- .../src/ui-components/pages/Preferences.jsx | 4 +- 3 files changed, 231 insertions(+), 146 deletions(-) diff --git a/browser-extension/api-server/assets/slur_metadata.json b/browser-extension/api-server/assets/slur_metadata.json index a140d4c4..de3b386a 100644 --- a/browser-extension/api-server/assets/slur_metadata.json +++ b/browser-extension/api-server/assets/slur_metadata.json @@ -1,112 +1,177 @@ [ - { - "fuck": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "a casual slur used to convey dislike, disrespect or lack of care. Sometimes also used aggresively or intensely", - "Categories": ["sexualized"] - } - }, - { - "cunt": { - "Level of Severity": "High", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "slang for women's genetalia", - "Categories": ["sexualized"] - } - }, - { - "slut": { - "Level of Severity": "High", - "Casual": "No", - "Appropriated": "Yes", - "If, Appropriated, Is it by Community or Others?": "Community", - "What Makes it Problematic?": "", - "Categories": ["gendered", "sexualized", "body shaming"] - } - }, - { - "whore": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "Yes", - "If, Appropriated, Is it by Community or Others?": "Community", - "What Makes it Problematic?": "", - "Categories": ["gendered", "sexualized"] - } - }, - { - "Randi": { - "Level of Severity": "High", - "Casual": "No", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": ["gendered", "sexualized"] - } - }, - { - "chutiya": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": [] - } - }, - { - "bsdk": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": ["sexualized"] - } - }, - { - "jihadi": { - "Level of Severity": "High", - "Casual": "No", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": ["religion", "ethnicity", "political affiliation"] - } - }, - { - "Madarchod": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", - "Categories": ["gendered", "sexualized"] - } - }, - { - "bhenchod": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", - "Categories": ["gendered", "sexualized"] - } - }, - { - "motherfucker": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "slur based on incest which is a common theme for derogatory words. Incest based slurs imply immorality since it is a deviation from established moral codes. But such insults express action over female bodies", - "Categories": ["sexualized", "gendered"] - } - } -] + { + "fuck": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "a casual slur used to convey dislike, disrespect or lack of care. Sometimes also used aggresively or intensely", + "Categories": [ + "sexualized" + ] + } + }, + { + "cunt": { + "Level of Severity": "High", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "slang for women's genetalia", + "Categories": [ + "sexualized" + ] + } + }, + { + "slut": { + "Level of Severity": "High", + "Casual": "No", + "Appropriated": "Yes", + "If, Appropriated, Is it by Community or Others?": "Community", + "What Makes it Problematic?": "", + "Categories": [ + "gendered", + "sexualized", + "body shaming" + ] + } + }, + { + "whore": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "Yes", + "If, Appropriated, Is it by Community or Others?": "Community", + "What Makes it Problematic?": "", + "Categories": [ + "gendered", + "sexualized" + ] + } + }, + { + "Randi": { + "Level of Severity": "High", + "Casual": "No", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": [ + "gendered", + "sexualized" + ] + } + }, + { + "chutiya": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": [] + } + }, + { + "bsdk": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": [ + "sexualized" + ] + } + }, + { + "jihadi": { + "Level of Severity": "High", + "Casual": "No", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": [ + "religion", + "ethnicity", + "political affiliation" + ] + } + }, + { + "Madarchod": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", + "Categories": [ + "gendered", + "sexualized" + ] + } + }, + { + "behenchod": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", + "Categories": [ + "gendered", + "sexualized" + ] + } + }, + { + "motherfucker": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "slur based on incest which is a common theme for derogatory words. Incest based slurs imply immorality since it is a deviation from established moral codes. But such insults express action over female bodies", + "Categories": [ + "sexualized", + "gendered" + ] + } + }, + { + "idiot": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "Used to demean someone's intelligence, often in a casual or aggressive manner.", + "Categories": [ + "intellectual ability" + ] + } + }, + { + "crazy": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "Yes", + "If, Appropriated, Is it by Community or Others?": "Community", + "What Makes it Problematic?": "Historically used to refer to mental health issues, reinforcing negative stereotypes about mental illness.", + "Categories": [ + "mental health" + ] + } + }, + { + "stupid": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "Used to insult someone's intelligence or capability, often belittling and dismissive.", + "Categories": [ + "intellectual ability" + ] + } + } +] \ No newline at end of file diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index eaa2de1b..ce8bb6dc 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -2,7 +2,7 @@ import { replaceSlur } from './slur-replace'; import { log } from './logger'; import repository from './repository'; const { getPreferenceData } = repository; -import {slurJSON} from '../../api-server/assets/slur_metadata.json' +const jsonData = require('../../api-server/assets/slur_metadata.json') // Traverse dom nodes to find leaf node that are text nodes and process function bft(node) { @@ -52,18 +52,21 @@ function setCaretPosition(element, offset) { const processNewlyAddedNodesGeneral2 = function (firstBody) { + + // const config = { attributes: true, childList: true, subtree: true }; console.log("HEY THERE !!!") - let targetWords = ["Blog", "BLOG", "Choose", "domain", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "idiot" , "Idiot" , "IDIOT", "CRAZY","ABLANARI","AblaNari","ablanari","chakka","jihidis","Jihadi","jihadi","Jihidi","zehadi","jehadan","jihadinon","Chakko","chakki","chaka","Chinal","Randi","ramdi","randya","Lulli","Gasti","Meetha","Halwa","Gud","Gandu","Gaand","Gandiaal","lodu"] + let targetWords = ["Blog", "BLOG", "Choose", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "idiot" , "Idiot" , "IDIOT", "CRAZY","ABLANARI","AblaNari","ablanari","chakka","jihidis","Jihadi","jihadi","Jihidi","zehadi","jehadan","jihadinon","Chakko","chakki","chaka","Chinal","Randi","ramdi","randya","Lulli","Gasti","Meetha","Halwa","Gud","Gandu","Gaand","Gandiaal","lodu","fuck","Fuck","Cunt","cunt","slut","Slut","Whore","whore","Chutiya","chutiya","Bsdk","bsdk","Madarchod","madarchod","behenchod","Bhenchod" , "Behenchod","motherfucker" + ] // let targetWords = slurList ; let uliStore = [] // getAllTextNodes(document.body, uliStore) getAllTextNodes(firstBody, uliStore) - console.log(uliStore) + // console.log(uliStore) abc = locateSlur(uliStore, targetWords) - console.log("uliStore", abc) + // console.log("uliStore", abc) addMetaData(targetWords) } @@ -232,7 +235,7 @@ function addMetaData(targetWords) { span.style.border = "1px solid black" span.style.borderRadius = "12px" span.style.padding = "2px 6px" - // span.style.width = "12rem" + span.style.width = "16rem" span.style.textAlign = "justify" span.style.fontWeight = "lighter" span.style.color = "black" @@ -241,34 +244,51 @@ function addMetaData(targetWords) { span.style.textDecoration = "none" span.style.fontStyle = "normal" // span.style.height = "fit-content" - span.innerHTML = `This is ${targetWord}` - - // span.style.display = "none"; - // span.style.position = "absolute"; - // span.style.backgroundColor = "antiquewhite !important"; - // span.style.border = "1px solid black !important"; - // span.style.borderRadius = "12px !important"; - // span.style.padding = "2px 6px !important"; - // span.style.width = "12rem !important"; - // span.style.textAlign = "justify !important"; - // span.innerHTML = `This is ${targetWord}`; - - - - - if (targetWord.toLowerCase() === "crazy") { - span.innerHTML = `It can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord.toLowerCase() === "idiot") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive.` - } - else if (targetWord.toLowerCase() === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful.` - } - else { - span.innerHTML = `This word is considered offensive.` - } - + span.innerHTML = `${targetWord} is an offensive word` + + + jsonData.forEach(slur => { + const slurWord = Object.keys(slur)[0]; // Get the slur word (the key) + if (slurWord.toLowerCase() === targetWord.toLowerCase()) { // Check if it matches the provided word + const slurDetails = slur[slurWord]; // Access the details of the slur + + let levelOfSeverity = slurDetails["Level of Severity"] ; + let casual = slurDetails["Casual"] ; + let approapriated = slurDetails["Appropriated"] ; + let reason = slurDetails["If, Appropriated, Is it by Community or Others?"] ; + let problematic = slurDetails["What Makes it Problematic?"]; + let categories = slurDetails["Categories"] ; + + let htmlContent = `` ; + if(levelOfSeverity){ + htmlContent += `

Level of Severity: ${levelOfSeverity}

` + } + + if(casual){ + htmlContent += `

Casual: ${casual}

` + } + + if(approapriated){ + htmlContent += `

Appropriated: ${approapriated}

` + } + + if(reason){ + htmlContent += `

If, Appropriated, Is it by Community or Others?: ${reason}

` + } + + if(problematic){ + htmlContent += `

What Makes it Problematic?: ${problematic}

` + } + + if(categories.length > 0){ + htmlContent += `

Categories: ${slurDetails["Categories"].join(', ')}

` + } + + + span.innerHTML = htmlContent; // Set the HTML content to the span element + } + }); + sup.appendChild(img) sup.appendChild(span) diff --git a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx index af1d5965..6c5848d4 100644 --- a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx +++ b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx @@ -109,7 +109,7 @@ export function Preferences() { await setPreferenceData({ ...localPreferences, enableSlurReplacement, - // enableSlurMetadata + enableSlurMetadata }); userBrowserTabs.sendMessage(tabId, { @@ -140,7 +140,7 @@ export function Preferences() { await setPreferenceData({ ...localPreferences, enableSlurMetadata, - // enableSlurReplacement + enableSlurReplacement }); userBrowserTabs.sendMessage(tabId, { From 1e4109e72bbf6b22f5a24f97ae4d47d02b7127c8 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Sun, 8 Sep 2024 16:47:50 +0530 Subject: [PATCH 17/19] updated slur_metadata.json to original one --- .../api-server/assets/slur_metadata.json | 243 +++++++----------- 1 file changed, 89 insertions(+), 154 deletions(-) diff --git a/browser-extension/api-server/assets/slur_metadata.json b/browser-extension/api-server/assets/slur_metadata.json index de3b386a..c3104a7a 100644 --- a/browser-extension/api-server/assets/slur_metadata.json +++ b/browser-extension/api-server/assets/slur_metadata.json @@ -1,177 +1,112 @@ [ { - "fuck": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "a casual slur used to convey dislike, disrespect or lack of care. Sometimes also used aggresively or intensely", - "Categories": [ - "sexualized" - ] - } + "fuck": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "a casual slur used to convey dislike, disrespect or lack of care. Sometimes also used aggresively or intensely", + "Categories": ["sexualized"] + } }, { - "cunt": { - "Level of Severity": "High", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "slang for women's genetalia", - "Categories": [ - "sexualized" - ] - } + "cunt": { + "Level of Severity": "High", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "slang for women's genetalia", + "Categories": ["sexualized"] + } }, { - "slut": { - "Level of Severity": "High", - "Casual": "No", - "Appropriated": "Yes", - "If, Appropriated, Is it by Community or Others?": "Community", - "What Makes it Problematic?": "", - "Categories": [ - "gendered", - "sexualized", - "body shaming" - ] - } + "slut": { + "Level of Severity": "High", + "Casual": "No", + "Appropriated": "Yes", + "If, Appropriated, Is it by Community or Others?": "Community", + "What Makes it Problematic?": "", + "Categories": ["gendered", "sexualized", "body shaming"] + } }, { - "whore": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "Yes", - "If, Appropriated, Is it by Community or Others?": "Community", - "What Makes it Problematic?": "", - "Categories": [ - "gendered", - "sexualized" - ] - } + "whore": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "Yes", + "If, Appropriated, Is it by Community or Others?": "Community", + "What Makes it Problematic?": "", + "Categories": ["gendered", "sexualized"] + } }, { - "Randi": { - "Level of Severity": "High", - "Casual": "No", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": [ - "gendered", - "sexualized" - ] - } + "Randi": { + "Level of Severity": "High", + "Casual": "No", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": ["gendered", "sexualized"] + } }, { - "chutiya": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": [] - } + "chutiya": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": [] + } }, { - "bsdk": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": [ - "sexualized" - ] - } + "bsdk": { + "Level of Severity": "Low", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": ["sexualized"] + } }, { - "jihadi": { - "Level of Severity": "High", - "Casual": "No", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "", - "Categories": [ - "religion", - "ethnicity", - "political affiliation" - ] - } + "jihadi": { + "Level of Severity": "High", + "Casual": "No", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "", + "Categories": ["religion", "ethnicity", "political affiliation"] + } }, { - "Madarchod": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", - "Categories": [ - "gendered", - "sexualized" - ] - } + "Madarchod": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", + "Categories": ["gendered", "sexualized"] + } }, { - "behenchod": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", - "Categories": [ - "gendered", - "sexualized" - ] - } + "bhenchod": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "sexualized act and describing incest, acted on a woman's (sister) body", + "Categories": ["gendered", "sexualized"] + } }, { - "motherfucker": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "slur based on incest which is a common theme for derogatory words. Incest based slurs imply immorality since it is a deviation from established moral codes. But such insults express action over female bodies", - "Categories": [ - "sexualized", - "gendered" - ] - } - }, - { - "idiot": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "Used to demean someone's intelligence, often in a casual or aggressive manner.", - "Categories": [ - "intellectual ability" - ] - } - }, - { - "crazy": { - "Level of Severity": "Medium", - "Casual": "Yes", - "Appropriated": "Yes", - "If, Appropriated, Is it by Community or Others?": "Community", - "What Makes it Problematic?": "Historically used to refer to mental health issues, reinforcing negative stereotypes about mental illness.", - "Categories": [ - "mental health" - ] - } - }, - { - "stupid": { - "Level of Severity": "Low", - "Casual": "Yes", - "Appropriated": "No", - "If, Appropriated, Is it by Community or Others?": "", - "What Makes it Problematic?": "Used to insult someone's intelligence or capability, often belittling and dismissive.", - "Categories": [ - "intellectual ability" - ] - } + "motherfucker": { + "Level of Severity": "Medium", + "Casual": "Yes", + "Appropriated": "No", + "If, Appropriated, Is it by Community or Others?": "", + "What Makes it Problematic?": "slur based on incest which is a common theme for derogatory words. Incest based slurs imply immorality since it is a deviation from established moral codes. But such insults express action over female bodies", + "Categories": ["sexualized", "gendered"] + } } -] \ No newline at end of file + ] \ No newline at end of file From f12d29e99a13a549ef5c32236bddc05dfd1f1229 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Thu, 12 Sep 2024 10:54:52 +0530 Subject: [PATCH 18/19] Checklist UI Update --- .../src/ui-components/pages/Preferences.jsx | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx index 6c5848d4..6c1d0810 100644 --- a/browser-extension/plugin/src/ui-components/pages/Preferences.jsx +++ b/browser-extension/plugin/src/ui-components/pages/Preferences.jsx @@ -92,9 +92,9 @@ export function Preferences() { }; }, [user]); - async function handleSlurReplacement(enableSlurReplacement) { + async function handleSlurReplacementAndSlurMetadata(enableSlurReplacement, enableSlurMetadata) { try { - // setEnableSlurMetadata(false); + const confirmed = window.confirm( 'This action requires a page reload. Do you want to continue?' @@ -123,44 +123,15 @@ export function Preferences() { } } - async function handleSlurMetadata(enableSlurMetadata) { - try { - // setEnableSlurReplacement(false) - - const confirmed = window.confirm( - 'This action requires a page reload. Do you want to continue?' - ); - if (confirmed) { - const tabsCurrent = await userBrowserTabs.query({ - active: true, - currentWindow: true - }); - const tabId = tabsCurrent[0].id; - - await setPreferenceData({ - ...localPreferences, - enableSlurMetadata, - enableSlurReplacement - }); - - userBrowserTabs.sendMessage(tabId, { - type: 'ULI_ENABLE_SLUR_METADATA', - payload: enableSlurMetadata - }); - userBrowserTabs.reload(tabId); - } - } catch (error) { - console.log(error); - } - } - async function changeEnableSlurReplacementOption(checked) { console.log(checked); + if(checked === true) setEnableSlurMetadata(false); setEnableSlurReplacement(checked); } async function changeEnableSlurMetadataOption(checked) { console.log(checked); + if(checked === true) setEnableSlurReplacement(false); setEnableSlurMetadata(checked); } @@ -190,14 +161,9 @@ export function Preferences() { const enableSlurMetadataChanged = enableSlurMetadata !== preferenceInLS.enableSlurMetadata; - if (enableSlurReplacementChanged) { + if (enableSlurReplacementChanged || enableSlurMetadataChanged) { console.log('enable val changed', enableSlurReplacementChanged); - await handleSlurReplacement(enableSlurReplacement); - } - - if(enableSlurMetadataChanged){ - console.log('enable val changed', enableSlurMetadataChanged); - await handleSlurMetadata(enableSlurMetadata); + await handleSlurReplacementAndSlurMetadata(enableSlurReplacement, enableSlurMetadata); } showNotification({ From 93ca2b0da2c9d6c62171e8d988c9e4f0d02be108 Mon Sep 17 00:00:00 2001 From: hardik-pratap-singh <21bcs090@iiitdmj.ac.in> Date: Fri, 13 Sep 2024 01:21:48 +0530 Subject: [PATCH 19/19] deleted unnecessary logs --- .../plugin/src/content-script.js | 5 +- browser-extension/plugin/src/slur-metadata.js | 163 ------------------ .../plugin/src/transform-general.js | 92 ++-------- .../plugin/test/enableSlurMetadata.test.js | 6 +- ...tion.js => enableSlurMetadataFunctions.js} | 0 5 files changed, 18 insertions(+), 248 deletions(-) delete mode 100644 browser-extension/plugin/src/slur-metadata.js rename browser-extension/plugin/test/{slurDetection.js => enableSlurMetadataFunctions.js} (100%) diff --git a/browser-extension/plugin/src/content-script.js b/browser-extension/plugin/src/content-script.js index 28c1ee15..dece1a77 100644 --- a/browser-extension/plugin/src/content-script.js +++ b/browser-extension/plugin/src/content-script.js @@ -148,10 +148,8 @@ chrome.runtime.onMessage.addListener(async function (request) { window.addEventListener( 'load', async () => { - // console.log('content loaded'); - // console.log("wowowow") + console.log('content loaded'); const pref = await getPreferenceData(); - // console.log(pref); const { enableSlurReplacement , enableSlurMetadata } = pref; if (enableSlurMetadata) { let body = document.getElementsByTagName('body'); @@ -161,7 +159,6 @@ window.addEventListener( else if (enableSlurReplacement) { processPage(location.href); } - }, false ); diff --git a/browser-extension/plugin/src/slur-metadata.js b/browser-extension/plugin/src/slur-metadata.js deleted file mode 100644 index b0862957..00000000 --- a/browser-extension/plugin/src/slur-metadata.js +++ /dev/null @@ -1,163 +0,0 @@ -// Created on Aug, 15 -// Author : Hardik PS - -function checkFalseTextNode(text, actualLengthOfText) { - let totalNewlineAndWhitespaces = 0; - for (let i = 0; i < text.length; i++) { - if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode - totalNewlineAndWhitespaces++; - } - } - return totalNewlineAndWhitespaces === actualLengthOfText; -} - -// Function to recursively get all text nodes under a given node -function getAllTextNodes(node, uliStore) { - if (node.nodeType === 3) { // Text node - if (!checkFalseTextNode(node.data, node.length)) { - uliStore.push({ node: node, parent: node.parentNode }); - } - } else { - let children = Array.from(node.childNodes); - children.forEach(child => getAllTextNodes(child, uliStore)); - } -} - - -function findPositions(word, text) { - let positions = {}; - - let len = word.length - let loc = [] - let index = text.toString().indexOf(word); - while (index !== -1) { - let obj = {}; - loc.push([index, index + len]); - index = text.toString().indexOf(word, index + 1); - } - - - if (loc.length !== 0) { - positions.slurText = word - positions.slurLocation = loc; - } - return positions; -} - - -function locateSlur(uliStore, targetWords) { - let n = uliStore.length; - - for (let i = 0; i < n; i++) { - let store = uliStore[i]; //This will contain the textNode - let parentNode = store.parent - let textnode = store.node - let text = store.node.textContent - let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block - //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent - tempParent.textContent = text; - //We have to look into this store for all the slurWords - let slurs = []; - - targetWords.forEach(targetWord => { - let slurWord = targetWord; - let pos = findPositions(slurWord, text); - if (Object.keys(pos).length !== 0) { - slurs.push(pos) - } - - if (tempParent.innerHTML.includes(targetWord)) { - const className = `icon-container-${targetWord}`; - const parts = tempParent.innerHTML.split(targetWord); - const replacedHTML = parts.join(`${targetWord}`); - tempParent.innerHTML = replacedHTML - } - }) - // for(let i = 0 ; i < ) - // console.log("tempParent " , tempParent) - uliStore[i].nodeToParent = tempParent - uliStore[i].slurs = slurs; - - - //Additional O(N) complexity - // parentNode.childNodes.forEach((node) => { - // if (node === textnode) { - // parentNode.replaceChild(tempParent, node) - // } - // }); - - //O(1) complexity - parentNode.replaceChild(tempParent, node) - - } - return uliStore; //This will return the final uliStore (after appending slurs) -} - - -function addMetaData(targetWords) { - targetWords.forEach(targetWord => { - const className = `icon-container-${targetWord}` - const elements = Array.from(document.querySelectorAll(`.${className}`)) - elements.forEach(element => { - - let sup = document.createElement("sup"); - - let img = document.createElement("img"); - img.style.height = "3%" - img.style.width = "3%" - img.style.cursor = "pointer" - img.src = "https://upload.wikimedia.org/wikipedia/commons/4/43/Minimalist_info_Icon.png" - // img.src = "./info.png" - img.alt = "altText" - - let span = document.createElement("span") - span.style.display = "none" - span.style.position = "absolute" - span.style.backgroundColor = "antiquewhite" - span.style.border = "1px solid black" - span.style.borderRadius = "12px" - span.style.padding = "2px 6px" - span.style.width = "12rem" - span.style.textAlign = "justify" - span.innerHTML = `This is ${targetWord}` - - - if (targetWord === "crazy") { - span.innerHTML = `Referring to behaviors or situations as "crazy" can perpetuate stereotypes about mental health and may be hurtful to those with mental health conditions.` - } - else if (targetWord === "mad") { - span.innerHTML = `Using "mad" to describe someone negatively can be insensitive, as it historically stigmatizes mental health issues and can imply irrationality or instability.` - } - else if (targetWord === 'stupid') { - span.innerHTML = `Describing actions or decisions as "stupid" can be demeaning and hurtful, as it implies lack of intelligence or judgment, which can be offensive to individuals or groups.` - } - else { - span.innerHTML = `This word is considered offensive or derogatory due to its association with negative stereotypes about people with disabilities. Using such terms can perpetuate discrimination and harm individuals by devaluing their worth and capabilities.` - } - - - sup.appendChild(img) - sup.appendChild(span) - - element.append(sup) - let sups = element.children[0] - let spans = element.children[0].children[1] - const svgs = element.children[0].children[0]; - svgs.addEventListener('mouseover', function () { - sups.children[1].style.display = "inline-block" - }); - - svgs.addEventListener('mouseout', function () { - sups.children[1].style.display = "none" - }); - }) - }) -} - - -let targetWords = ["stupid", "crazy", "Crazy", "mad" , "Mad" , "MAD"] -let uliStore = [] -getAllTextNodes(document.body, uliStore) -abc = locateSlur(uliStore, targetWords) -console.log("uliStore", abc) -addMetaData(targetWords) diff --git a/browser-extension/plugin/src/transform-general.js b/browser-extension/plugin/src/transform-general.js index ce8bb6dc..5161957f 100644 --- a/browser-extension/plugin/src/transform-general.js +++ b/browser-extension/plugin/src/transform-general.js @@ -50,28 +50,19 @@ function setCaretPosition(element, offset) { sel.addRange(range); } - const processNewlyAddedNodesGeneral2 = function (firstBody) { - - - - // const config = { attributes: true, childList: true, subtree: true }; - console.log("HEY THERE !!!") - let targetWords = ["Blog", "BLOG", "Choose", "bad", "BAD", "Bad", "Stupid", "STUPID", "stupid", "crazy", "Crazy", "idiot" , "Idiot" , "IDIOT", "CRAZY","ABLANARI","AblaNari","ablanari","chakka","jihidis","Jihadi","jihadi","Jihidi","zehadi","jehadan","jihadinon","Chakko","chakki","chaka","Chinal","Randi","ramdi","randya","Lulli","Gasti","Meetha","Halwa","Gud","Gandu","Gaand","Gandiaal","lodu","fuck","Fuck","Cunt","cunt","slut","Slut","Whore","whore","Chutiya","chutiya","Bsdk","bsdk","Madarchod","madarchod","behenchod","Bhenchod" , "Behenchod","motherfucker" - ] - - // let targetWords = slurList ; + let targetWords = [] ; + jsonData.forEach(slur => { + const slurWord = Object.keys(slur)[0]; + targetWords.push(slurWord) ; + targetWords.push(slurWord.charAt(0).toUpperCase() + slurWord.slice(1)); + }) let uliStore = [] - // getAllTextNodes(document.body, uliStore) getAllTextNodes(firstBody, uliStore) - // console.log(uliStore) abc = locateSlur(uliStore, targetWords) - // console.log("uliStore", abc) addMetaData(targetWords) } - - const processNewlyAddedNodesGeneral = function (firstBody) { log('processing new nodes'); const config = { attributes: true, childList: true, subtree: true }; @@ -95,27 +86,19 @@ const processNewlyAddedNodesGeneral = function (firstBody) { observer.observe(firstBody, config); }; - -// Code inserted below is for uliStore - - -/* getAllTextNodes() STARTS HERE */ - function checkFalseTextNode(text, actualLengthOfText) { let totalNewlineAndWhitespaces = 0; for (let i = 0; i < text.length; i++) { if (text[i] === "\n" || text[i] === " " || text[i] === "\t") { - // I think not only \n and " " , if a textNode is comprised of any escape characters and whitespace, it should be a false textNode totalNewlineAndWhitespaces++; } } return totalNewlineAndWhitespaces === actualLengthOfText; } - -// Function to recursively get all text nodes under a given node +// Function to recursively get all text nodes for a given node function getAllTextNodes(node, uliStore) { - if (node.nodeType === 3) { // Text node + if (node.nodeType === 3) { if (!checkFalseTextNode(node.data, node.length)) { uliStore.push({ node: node, parent: node.parentNode }); } @@ -125,16 +108,8 @@ function getAllTextNodes(node, uliStore) { } } - - -/* getAllTextNodes() ENDS HERE */ - - -/* locateSlur() STARTS HERE */ - function findPositions(word, text) { let positions = {}; - let len = word.length let loc = [] let index = text.toString().indexOf(word); @@ -143,8 +118,6 @@ function findPositions(word, text) { loc.push([index, index + len]); index = text.toString().indexOf(word, index + 1); } - - if (loc.length !== 0) { positions.slurText = word positions.slurLocation = loc; @@ -158,14 +131,12 @@ function locateSlur(uliStore, targetWords) { let n = uliStore.length; for (let i = 0; i < n; i++) { - let store = uliStore[i]; //This will contain the textNode + let store = uliStore[i]; let parentNode = store.parent let textnode = store.node let text = store.node.textContent - let tempParent = document.createElement("span"); //I chose span over p because span is an inline element and p is a block element, injecting block - //element would cause a lot of change in the stylings and can damage the overall webpage to a greater extent + let tempParent = document.createElement("span"); tempParent.textContent = text; - let slurs = []; let slurPresentInTempParent = false; targetWords.forEach(targetWord => { @@ -183,31 +154,17 @@ function locateSlur(uliStore, targetWords) { slurPresentInTempParent = true; } }) - // for(let i = 0 ; i < ) - // console.log("tempParent " , tempParent) uliStore[i].nodeToParent = tempParent uliStore[i].slurs = slurs; //O(1) complexity if (slurPresentInTempParent) { - // parentNode.replaceChild(tempParent, textnode) textnode.replaceWith(tempParent) - // textnode.replaceWith(createTextNode(tempParent.innerHTML)) - } - } return uliStore; } - -/* locateSlur() ENDS HERE */ - - - - -/* addMetaData() STARTS HERE */ - function addMetaData(targetWords) { targetWords.forEach(targetWord => { const className = `icon-container-${targetWord}` @@ -215,7 +172,6 @@ function addMetaData(targetWords) { elements.forEach(element => { let sup = document.createElement("sup"); - let img = document.createElement("img"); img.style.height = "1.5%" img.style.width = "1.5%" @@ -223,12 +179,9 @@ function addMetaData(targetWords) { img.style.cursor = "pointer" img.src = "https://raw.githubusercontent.com/tattle-made/Uli/main/uli-website/src/images/favicon-32x32.png" - // img.src = "./icon16.png" - // img.src = "./info.png" img.alt = "altText" let span = document.createElement("span") - // span.style.all = "unset" span.style.display = "none" span.style.position = "absolute" span.style.backgroundColor = "antiquewhite" @@ -243,49 +196,39 @@ function addMetaData(targetWords) { span.style.fontSize = "14px" span.style.textDecoration = "none" span.style.fontStyle = "normal" - // span.style.height = "fit-content" span.innerHTML = `${targetWord} is an offensive word` jsonData.forEach(slur => { - const slurWord = Object.keys(slur)[0]; // Get the slur word (the key) - if (slurWord.toLowerCase() === targetWord.toLowerCase()) { // Check if it matches the provided word - const slurDetails = slur[slurWord]; // Access the details of the slur - + const slurWord = Object.keys(slur)[0]; + if (slurWord.toLowerCase() === targetWord.toLowerCase()) { + const slurDetails = slur[slurWord]; let levelOfSeverity = slurDetails["Level of Severity"] ; let casual = slurDetails["Casual"] ; let approapriated = slurDetails["Appropriated"] ; let reason = slurDetails["If, Appropriated, Is it by Community or Others?"] ; let problematic = slurDetails["What Makes it Problematic?"]; let categories = slurDetails["Categories"] ; - let htmlContent = `` ; if(levelOfSeverity){ htmlContent += `

Level of Severity: ${levelOfSeverity}

` } - if(casual){ htmlContent += `

Casual: ${casual}

` } - if(approapriated){ htmlContent += `

Appropriated: ${approapriated}

` } - if(reason){ htmlContent += `

If, Appropriated, Is it by Community or Others?: ${reason}

` } - if(problematic){ htmlContent += `

What Makes it Problematic?: ${problematic}

` } - if(categories.length > 0){ htmlContent += `

Categories: ${slurDetails["Categories"].join(', ')}

` } - - - span.innerHTML = htmlContent; // Set the HTML content to the span element + span.innerHTML = htmlContent; } }); @@ -299,7 +242,6 @@ function addMetaData(targetWords) { const svgs = element.children[0].children[0]; svgs.addEventListener('mouseover', function () { sups.children[1].style.display = "inline-block" - // sups.children[1].style.display = "block" }); svgs.addEventListener('mouseout', function () { @@ -309,12 +251,6 @@ function addMetaData(targetWords) { }) } - -/* addMetaData() ENDS HERE */ - - - - export default { processNewlyAddedNodesGeneral, processNewlyAddedNodesGeneral2, diff --git a/browser-extension/plugin/test/enableSlurMetadata.test.js b/browser-extension/plugin/test/enableSlurMetadata.test.js index 7477d3b6..63dbd9a3 100644 --- a/browser-extension/plugin/test/enableSlurMetadata.test.js +++ b/browser-extension/plugin/test/enableSlurMetadata.test.js @@ -2,11 +2,11 @@ const { TextEncoder, TextDecoder } = require('util'); global.TextEncoder = TextEncoder; global.TextDecoder = TextDecoder; -const { findPositions, locateSlur, addMetaData, checkFalseTextNode, getAllTextNodes } = require('./slurDetection.js'); +const { findPositions, locateSlur, addMetaData, checkFalseTextNode, getAllTextNodes } = require('./enableSlurMetadataFunctions.js'); const { JSDOM } = require('jsdom'); -jest.mock('./slurDetection.js', () => { - const actualModule = jest.requireActual('./slurDetection.js'); +jest.mock('./enableSlurMetadataFunctions.js', () => { + const actualModule = jest.requireActual('./enableSlurMetadataFunctions.js'); return { ...actualModule, checkFalseTextNode: jest.fn() diff --git a/browser-extension/plugin/test/slurDetection.js b/browser-extension/plugin/test/enableSlurMetadataFunctions.js similarity index 100% rename from browser-extension/plugin/test/slurDetection.js rename to browser-extension/plugin/test/enableSlurMetadataFunctions.js