Skip to content

Commit aec1ef3

Browse files
Merge pull request #548 from bitdefender/link-checker-translate
Link checker translate
2 parents 8505fe7 + a0e64bc commit aec1ef3

File tree

2 files changed

+98
-41
lines changed

2 files changed

+98
-41
lines changed

_src/blocks/columns/columns.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,7 @@
11981198
justify-content: center;
11991199
align-items: center;
12001200
}
1201+
12011202
.section.migration.table-align-top tr{
12021203
flex-direction: unset;
12031204
}

_src/blocks/link-checker/link-checker.js

Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from '../../scripts/utils/bot-prevention.js';
1010

1111
class StatusMessageFactory {
12-
static createMessage(status, url) {
12+
static createMessage(status, url, statusMessages) {
1313
let urlObject = url;
1414
// Ensure the URL has a protocol
1515
if (!/^https?:\/\//i.test(url)) {
@@ -22,46 +22,44 @@ class StatusMessageFactory {
2222
urlObject.hostname = `www.${urlObject.hostname}`;
2323
}
2424

25-
const messages = {
26-
1: { text: 'The link is safe with no signs of harmful activity. You can go ahead and keep staying cautious online.', className: 'result safe', status: 'safe' },
27-
2: { text: 'We haven\'t found any suspicious activity with this link. However, to stay safe going forward, make sure to use reliable security software and scan your system regularly.', className: 'result safe', status: 'so_far_so_good_1' },
28-
3: { text: `This link looks safe, but the domain '${urlObject.hostname}' has been connected to harmful links in the past. To stay protected, check any other links from this domain using our tool and keep your security software updated.`, className: 'result safe', status: 'so_far_so_good_2' },
29-
4: { text: 'This link is dangerous and can compromise your personal information or harm your device. Do not click it, and ensure your security software is up-to-date to stay protected from threats.', className: 'result danger', status: 'malware & phishing' },
30-
5: { text: 'This link is known to distribute malware. Accessing it may harm your device, steal your data, or allow unauthorized access. Stay away from the site and ensure your security software is active.', className: 'result danger', status: 'malware' },
31-
6: { text: 'This URL is linked to a server used to command and control malware on infected devices. Don’t click the link and make sure your security software is up to date to keep your device safe.', className: 'result danger', status: 'c&c' },
32-
7: { text: 'This link is a threat, exposing you to malicious ads and phishing attempts that can steal your information and damage your device. Do not interact with it, and ensure your security software is updated.', className: 'result danger', status: 'malvertising & fraud & phishing' },
33-
8: { text: 'This link directs to a fraudulent site intended to trick users and steal sensitive data. Stay away from the site and ensure your security software is active.', className: 'result danger', status: 'fraud' },
34-
9: { text: 'This link leads to a phishing site designed to steal personal information like passwords or financial data. Stay away from the site and ensure your security software is active.', className: 'result danger', status: 'phishing' },
35-
10: { text: 'This link is connected to harmful ads that could affect your device and expose your personal data, such as your passwords, credit card information, email addresses, or browsing history. Avoid clicking on it and keep your security software updated to stay safe.', className: 'result danger', status: 'malvertising' },
36-
11: { text: 'This link is associated with apps that could slow down your device or compromise your privacy. It’s best to avoid the site and make sure your security settings are active.', className: 'result danger', status: 'pua' },
37-
12: { text: 'This link is designed to look like a trusted site using tricky characters. Don’t click the link and make sure your security software is updated to protect your device.', className: 'result danger', status: 'homograph' },
38-
13: { text: 'This URL is linked to cryptocurrency mining activities, which may use your device\'s resources without your consent. Avoid visiting the site and ensure your security protections are in place.', className: 'result danger', status: 'miner' },
39-
14: { text: 'This URL is linked to crypto mining activity, which could use your device\'s resources if accessed. It’s recommended not to click the link and ensure your security software is up to date.', className: 'result danger', status: 'miner-server' },
40-
15: { text: 'This link has been identified in spam emails, which often contain malicious content. Avoid clicking on it, as it may lead to harmful sites or scams. Ensure your security measures are in place.', className: 'result danger', status: 'spam' },
41-
16: { text: 'This URL is likely to contain malware, posing a significant threat. It\'s strongly advised to avoid accessing it and ensure your security protections are active and up to date.', className: 'result danger', status: 'malware-hd' },
42-
17: { text: 'This link appears suspicious and may not be trustworthy. It’s best to avoid accessing it. Keep your security software active and steer clear of the site.', className: 'result danger', status: 'untrusted' },
43-
18: { text: 'This link is unsafe and could harm your device or steal your personal information. Avoid clicking on it and keep your security software updated to stay safe.', className: 'result danger', status: 'malicious' },
44-
other: { text: 'This link is unsafe and could harm your device or steal your personal information. Avoid clicking on it and keep your security software updated to stay safe.', className: 'result danger', status: 'other' },
25+
// Manually defined mapping of number keys to status strings
26+
const numberToStatusMap = {
27+
1: 'safe',
28+
2: 'so_far_so_good_1',
29+
3: 'so_far_so_good_2',
30+
4: 'malware & phishing',
31+
5: 'malware',
32+
6: 'c&c',
33+
7: 'malvertising & fraud & phishing',
34+
8: 'fraud',
35+
9: 'phishing',
36+
10: 'malvertising',
37+
11: 'pua',
38+
12: 'homograph',
39+
13: 'miner',
40+
14: 'miner-server',
41+
15: 'spam',
42+
16: 'malware-hd',
43+
17: 'untrusted',
44+
18: 'malicious',
45+
other: 'other',
4546
};
46-
return messages[status] || { text: `Status: ${status}`, className: 'result warning' };
47+
const mappedStatus = numberToStatusMap[status] || numberToStatusMap.other;
48+
const isSafe = mappedStatus.includes('safe')
49+
|| mappedStatus.includes('so_far_so_good_1')
50+
|| mappedStatus.includes('so_far_so_good_2');
51+
let msg = statusMessages[mappedStatus.toLowerCase()];
52+
msg = msg.replace('<domain-name>', urlObject.hostname);
53+
if (msg) {
54+
return { text: msg, className: isSafe ? 'result safe' : 'result danger', status: mappedStatus };
55+
}
56+
return { text: `Status: ${mappedStatus}`, className: 'result warning' };
4757
}
4858
}
4959

50-
function changeTexts(block, result) {
51-
switch (result.status) {
52-
case 'safe':
53-
block.querySelector('h1').textContent = "You're safe";
54-
break;
55-
case 'so_far_so_good_1':
56-
block.querySelector('h1').textContent = 'So far, so good';
57-
break;
58-
case 'so_far_so_good_2':
59-
block.querySelector('h1').textContent = 'So far, so good';
60-
break;
61-
default:
62-
block.querySelector('h1').textContent = 'Definitely Don’t Go There';
63-
break;
64-
}
60+
function changeTexts(block, result, statusTitles) {
61+
const titleText = statusTitles[result.status.toLowerCase()] || statusTitles.default;
62+
block.querySelector('h1').textContent = titleText;
6563
}
6664

6765
const isValidUrl = (urlString) => {
@@ -74,7 +72,7 @@ const isValidUrl = (urlString) => {
7472
return urlPattern.test(urlString);
7573
};
7674

77-
async function checkLink(block, input, result) {
75+
async function checkLink(block, input, result, statusMessages, statusTitles) {
7876
const url = input.value.trim();
7977
if (!url || !isValidUrl(url)) {
8078
result.textContent = 'Please enter a valid URL';
@@ -117,14 +115,14 @@ async function checkLink(block, input, result) {
117115

118116
const data = await response.json();
119117
const { status } = data;
120-
const message = StatusMessageFactory.createMessage(status, url);
118+
const message = StatusMessageFactory.createMessage(status, url, statusMessages);
121119
result.textContent = message.text;
122120
result.className = message.className;
123121
block.closest('.section').classList.add(message.className.split(' ')[1]);
124122
input.setAttribute('disabled', '');
125123
document.getElementById('inputDiv').textContent = url;
126124

127-
changeTexts(block, message);
125+
changeTexts(block, message, statusTitles);
128126
input.closest('.input-container').classList.remove('loader-circle');
129127

130128
const newObject = await new PageLoadStartedEvent();
@@ -186,12 +184,70 @@ function copyToClipboard(block, caller, popupText) {
186184
}
187185
}
188186

187+
function createStatusMessages(block) {
188+
const statusMessages = {};
189+
190+
const divWithStatusMessages = Array.from(block.querySelectorAll('div')).find((div) => {
191+
const firstParagraph = div.querySelector('p');
192+
return firstParagraph && firstParagraph.textContent.includes('<status-messages>');
193+
});
194+
195+
const pElements = divWithStatusMessages.querySelectorAll('p');
196+
// Skip the first <p> if it contains a header like "<status-messages>"
197+
pElements.forEach((p, index) => {
198+
if (index === 0) {
199+
return;
200+
}
201+
202+
const parts = p.textContent.split(':');
203+
if (parts.length >= 2) {
204+
const status = parts[0].trim();
205+
const message = parts.slice(1).join(':').trim();
206+
statusMessages[status.toLowerCase()] = message;
207+
}
208+
});
209+
210+
return statusMessages;
211+
}
212+
213+
function createStatusTitles(block) {
214+
const statusTitles = {};
215+
216+
const divWithstatusTitles = Array.from(block.querySelectorAll('div')).find((div) => {
217+
const firstParagraph = div.querySelector('p');
218+
return firstParagraph && firstParagraph.textContent.includes('<titles-change>');
219+
});
220+
221+
divWithstatusTitles.classList.add('status-titles');
222+
const pElements = divWithstatusTitles.querySelectorAll('p');
223+
// Skip the first <p> if it contains a header like "<titles-change>"
224+
pElements.forEach((p, index) => {
225+
if (index === 0) {
226+
return;
227+
}
228+
229+
const parts = p.textContent.split(':');
230+
if (parts.length >= 2) {
231+
const status = parts[0].trim();
232+
const message = parts.slice(1).join(':').trim();
233+
statusTitles[status.toLowerCase()] = message;
234+
}
235+
});
236+
237+
// remove the div from the dom, as it is already parsed and we don't need it anymore
238+
divWithstatusTitles.remove();
239+
return statusTitles;
240+
}
241+
189242
export default function decorate(block) {
190243
const { clipboardText } = block.closest('.section').dataset;
191244

192245
const privacyPolicyDiv = block.querySelector(':scope > div:nth-child(3)');
193246
privacyPolicyDiv.classList.add('privacy-policy');
194247

248+
const statusMessages = createStatusMessages(block);
249+
const statusTitles = createStatusTitles(block);
250+
195251
const formContainer = document.createElement('div');
196252
formContainer.classList.add('link-checker-form');
197253

@@ -256,7 +312,7 @@ export default function decorate(block) {
256312
safeImage.classList.add('safe-image');
257313
dangerImage.classList.add('danger-image');
258314

259-
button.addEventListener('click', () => checkLink(block, input, result));
315+
button.addEventListener('click', () => checkLink(block, input, result, statusMessages, statusTitles));
260316
checkAnother.addEventListener('click', () => resetChecker(block));
261317
shareButton.addEventListener('click', (e) => {
262318
e.preventDefault();

0 commit comments

Comments
 (0)