Skip to content

Commit 17e3e16

Browse files
authored
Merge pull request #36 from horihiro/bump-0.1.9
Bump 0.1.9
2 parents e82746a + 43a7215 commit 17e3e16

7 files changed

Lines changed: 109 additions & 14 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ If you can try a development version, the following steps are needed.
3838

3939
# Change logs
4040

41+
## [0.1.9](https://github.com/horihiro/TextBlurrer-ChromeExtension/releases/tag/0.1.9)
42+
43+
- New features
44+
- Add title masking by the keywords
45+
- Bug fixes
46+
- Improve misalignment of mask position for input element
47+
48+
## [0.1.8](https://github.com/horihiro/TextBlurrer-ChromeExtension/releases/tag/0.1.8)
49+
50+
- Bug fixes
51+
- Fix misalignment of mask position for input element with `box-sizing` set to `border-box` ([#32](https://github.com/horihiro/TextBlurrer-ChromeExtension/issues/32))
52+
4153
## [0.1.7](https://github.com/horihiro/TextBlurrer-ChromeExtension/releases/tag/0.1.7)
4254

4355
- Bug fixes

content/js/main.js

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const exElmList = ['html', 'title', 'script', 'noscript', 'style', 'meta', 'link', 'head', 'textarea', '#comment'];
44
const blurredClassName = 'tb_blurred_class';
55
const keepClassName = 'tb_keep_this_class';
6+
const originalTitleAttributeName = 'data-tb-original-title';
67
const maskContainerClassName = 'tb_mask_container_class';
78
const textLayerClassName = 'tb_mask_text_layer_class';
89
const inputCloneId = 'tb_input_clone';
@@ -338,7 +339,8 @@
338339
}px`);
339340
mask.style.setProperty('top', `${input.offsetTop + input.offsetHeight - blurredSpan.offsetHeight
340341
- (verticalGap > 0 ? verticalGap / 2 : 0)
341-
- (isBorderBox ? 0 : parseFloat(inputStyle.getPropertyValue('border-bottom-width')) + parseFloat(inputStyle.getPropertyValue('padding-bottom')))
342+
- (isBorderBox ? - parseFloat(inputStyle.getPropertyValue('border-top-width')) : parseFloat(inputStyle.getPropertyValue('border-bottom-width')) )
343+
- parseFloat(inputStyle.getPropertyValue('padding-bottom'))
342344
}px`);
343345
const maskBoundingBox = mask.getBoundingClientRect();
344346
const tmpWidth = inputBoundingBox.width + inputBoundingBox.left - maskBoundingBox.left - parseFloat(inputStyle.getPropertyValue('border-left-width'));
@@ -348,7 +350,7 @@
348350
? tmpWidth
349351
: 0}px`);
350352
mask.style.setProperty('height', `${blurredBoundingBox.height}px`);
351-
mask.style.setProperty('z-index', `${parseInt(inputStyle.getPropertyValue) + 1}`);
353+
mask.style.setProperty('z-index', `${parseInt(inputStyle.getPropertyValue('z-index')) + 1}`);
352354
mask.style.setProperty('border', 'none');
353355

354356
mask.style.setProperty('background-color', getBackgroundColorAlongDOMTree(input));
@@ -361,7 +363,7 @@
361363
if (element == document) return '';
362364
const computedStyle = getComputedStyle(element);
363365
return (!/(?:^| )rgba *\( *\d+ *, *\d+ *, *\d+ *, *0 *\)(?:$| )/.test(computedStyle.getPropertyValue('background-color')))
364-
? computedStyle.getPropertyValue('background-color')
366+
? computedStyle.getPropertyValue('background-color').replace(/rgba *\( *(\d+) *, *(\d+) *, *(\d+) *, *[^)]+ *\)/, 'rgb($1, $2, $3)')
365367
: getBackgroundColorAlongDOMTree(element.parentNode);
366368
}
367369
const inputOnFocus = (e) => {
@@ -456,10 +458,10 @@
456458
m.forEach((n) => {
457459
if (n.classList.contains(blurredClassName) && n.classList.contains(keepClassName)) {
458460
// restore title
459-
const originalTitle = n.getAttribute('data-tb-original-title');
461+
const originalTitle = n.getAttribute(originalTitleAttributeName);
460462
if (originalTitle) {
461463
n.setAttribute('title', originalTitle);
462-
n.removeAttribute('data-tb-original-title');
464+
n.removeAttribute(originalTitleAttributeName);
463465
}
464466
else n.removeAttribute('title');
465467

@@ -504,6 +506,50 @@
504506
console.debug(`Took ${Date.now() - now} ms`)
505507
};
506508

509+
const unblurTabTitle = (title) => {
510+
if (!title) return;
511+
if (title.getAttribute(originalTitleAttributeName)) {
512+
title.textContent = title.getAttribute(originalTitleAttributeName);
513+
title.removeAttribute(originalTitleAttributeName);
514+
}
515+
if (!w.__titleObserver) return;
516+
w.__titleObserver.disconnect();
517+
delete w.__titleObserver;
518+
};
519+
520+
const blurTabTitleCore = (pattern, target) => {
521+
const title = target.textContent;
522+
let result = title.match(pattern);
523+
while (result) {
524+
const mask = new Array(result[0].length).fill('*').join('');
525+
target.textContent = target.textContent.replace(result[0], mask);
526+
result = target.textContent.match(pattern);
527+
if (!target.getAttribute(originalTitleAttributeName)) {
528+
target.setAttribute(originalTitleAttributeName, title);
529+
}
530+
}
531+
};
532+
533+
const blurTabTitle = (pattern, title) => {
534+
if (!title) return;
535+
blurTabTitleCore(pattern, title);
536+
if (!w.__titleObserver) {
537+
w.__titleObserver = new MutationObserver((records) => {
538+
w.__titleObserver.disconnect();
539+
title.removeAttribute(originalTitleAttributeName);
540+
records.forEach((record) => {
541+
blurTabTitleCore(pattern, record.target);
542+
});
543+
w.__titleObserver.observe(title, {
544+
characterData: true, childList: true
545+
});
546+
});
547+
}
548+
w.__titleObserver.observe(title, {
549+
characterData: true, childList: true
550+
});
551+
};
552+
507553
const escapeRegExp = (str) => {
508554
return str.replace(/([\(\)\{\}\+\*\?\[\]\.\^\$\|\\])/g, '\\$1');
509555
};
@@ -515,19 +561,25 @@
515561
);
516562
};
517563

564+
const title = document.querySelector('title');
518565
chrome.storage.onChanged.addListener(async (changes, area) => {
519566
if (area !== 'local') return;
520-
const { status, keywords, mode, matchCase, showValue, blurInput } = (await chrome.storage.local.get(['status', 'keywords', 'mode', 'matchCase', 'showValue', 'blurInput']));
567+
const { status, keywords, mode, matchCase, showValue, blurInput, blurTitle } = (await chrome.storage.local.get(['status', 'keywords', 'mode', 'matchCase', 'showValue', 'blurInput', 'blurTitle']));
521568
unblur();
569+
unblurTabTitle(title);
522570
if (status === 'disabled' || !keywords || keywords.trim() === '') return;
523-
blur(keywords2RegExp(keywords, mode, !!matchCase), { showValue, blurInput });
571+
const pattern = keywords2RegExp(keywords, mode, !!matchCase);
572+
blur(pattern, { showValue, blurInput });
573+
blurTitle && blurTabTitle(pattern, title);
524574
});
525-
const { status, keywords, mode, matchCase, showValue, blurInput } = (await chrome.storage.local.get(['status', 'keywords', 'mode', 'matchCase', 'showValue', 'blurInput']));
575+
const { status, keywords, mode, matchCase, showValue, blurInput, blurTitle } = (await chrome.storage.local.get(['status', 'keywords', 'mode', 'matchCase', 'showValue', 'blurInput', 'blurTitle']));
526576
if (status === 'disabled' || !keywords || keywords.trim() === '') return;
527577
window.addEventListener('resize', () => {
528578
inputs.forEach((input) => {
529579
input.element.dispatchEvent(new InputEvent('input', { data: input.value }));
530580
});
531581
})
532-
blur(keywords2RegExp(keywords, mode, !!matchCase), { showValue, blurInput });
582+
const pattern = keywords2RegExp(keywords, mode, !!matchCase);
583+
blur(pattern, { showValue, blurInput });
584+
blurTitle && blurTabTitle(pattern, title)
533585
})();

manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"manifest_version": 3,
33
"name": "Text Blurrer",
4-
"version": "0.1.8",
5-
"version_name": "0.1.8",
4+
"version": "0.1.9",
5+
"version_name": "0.1.9",
66
"description": "Blurring sensitive specified text/keyword.",
77
"permissions": [
88
"storage"

popup/css/main.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,15 @@ input[type="checkbox"]:checked.blur-input+span::before {
157157
background-image: url("../img/symbol-string.svg");
158158
}
159159

160+
input[type="checkbox"].blur-title+span::before {
161+
-webkit-mask: url("../img/tab-title.svg") no-repeat center center;
162+
mask: url("../img/tab-title.svg") no-repeat center center;
163+
}
164+
165+
input[type="checkbox"]:checked.blur-title+span::before {
166+
background-image: url("../img/tab-title.svg");
167+
}
168+
160169
#applyButton {
161170
margin-top: 10px;
162171
display: flex;

popup/img/tab-title.svg

Lines changed: 5 additions & 0 deletions
Loading

popup/js/main.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
document.addEventListener('DOMContentLoaded', async (e) => {
2-
const { status, keywords, mode, matchCase, showValue, blurInput } = (await chrome.storage.local.get(['status', 'keywords', 'mode', 'matchCase', 'showValue', 'blurInput']));
2+
const { status, keywords, mode, matchCase, showValue, blurInput, blurTitle } = (await chrome.storage.local.get(['status', 'keywords', 'mode', 'matchCase', 'showValue', 'blurInput', 'blurTitle']));
33

44
const applyButton = document.querySelector('#applyButton');
55
const patternInput = document.querySelector('#patternInput');
@@ -8,6 +8,7 @@ document.addEventListener('DOMContentLoaded', async (e) => {
88
const regexpCheckbox = document.querySelector('#regexpCheckbox');
99
const showValueCheckbox = document.querySelector('#showValueCheckbox');
1010
const blurInputCheckbox = document.querySelector('#blurInputCheckbox');
11+
const blurTitleCheckbox = document.querySelector('#blurTitleCheckbox');
1112
const _bufferTextArea = document.querySelector('#_bufferTextArea');
1213

1314
const COLOR_DEFAULT = getComputedStyle(_bufferTextArea).getPropertyValue('background-color');
@@ -25,6 +26,7 @@ document.addEventListener('DOMContentLoaded', async (e) => {
2526
let savedMode = false;
2627
let savedShowValue = false;
2728
let savedBlurInput = false;
29+
let savedBlurTitle = false;
2830
let validationResults = [];
2931
let pointedRow = -1;
3032

@@ -122,7 +124,8 @@ document.addEventListener('DOMContentLoaded', async (e) => {
122124
caseCheckbox.checked === savedMatchCase &&
123125
showValueCheckbox.checked === savedShowValue &&
124126
regexpCheckbox.checked === savedMode &&
125-
blurInputCheckbox.checked === savedBlurInput
127+
blurInputCheckbox.checked === savedBlurInput &&
128+
blurTitleCheckbox.checked === savedBlurTitle
126129
);
127130
const re = /\*(\d+)( - [\d.]+px\))$/;
128131
const bgColors = validationResults.reduce((prev, curr, pos, array) => {
@@ -161,20 +164,23 @@ textarea#${patternInput.id} {
161164
'matchCase': caseCheckbox.checked,
162165
'showValue': showValueCheckbox.checked,
163166
'blurInput': blurInputCheckbox.checked,
167+
'blurTitle': blurTitleCheckbox.checked,
164168
});
165169
patternInput.focus();
166170
savedKeywords = patternInput.value;
167171
savedMode = regexpCheckbox.checked;
168172
savedMatchCase = caseCheckbox.checked;
169173
savedShowValue = showValueCheckbox.checked;
170174
savedBlurInput = blurInputCheckbox.checked;
175+
savedBlurTitle = blurTitleCheckbox.checked;
171176
e.target.disabled = true;
172177
});
173178

174179
statusCheckbox.addEventListener('change', async (e) => {
175180
caseCheckbox.disabled =
176181
showValueCheckbox.disabled =
177182
blurInputCheckbox.disabled =
183+
blurTitleCheckbox.disabled =
178184
regexpCheckbox.disabled =
179185
patternInput.disabled = !e.target.checked;
180186
applyButton.disabled = !e.target.checked || !validationResults.every(r => r.isValid);
@@ -213,6 +219,11 @@ textarea#${patternInput.id} {
213219
patternInput.focus();
214220
});
215221

222+
blurTitleCheckbox.addEventListener('change', async (e) => {
223+
await renderBackground();
224+
patternInput.focus();
225+
});
226+
216227
patternInput.addEventListener('scroll', renderBackground);
217228
patternInput.addEventListener('scroll', () => {
218229
if (patternInput.scrollLeft < textAreaPaddingLeft) patternInput.scrollLeft = 0;
@@ -243,12 +254,14 @@ textarea#${patternInput.id} {
243254
savedMatchCase = caseCheckbox.checked = matchCase;
244255
savedShowValue = showValueCheckbox.checked = showValue;
245256
savedBlurInput = blurInputCheckbox.checked = blurInput;
257+
savedBlurTitle = blurTitleCheckbox.checked = blurTitle;
246258
savedMode = regexpCheckbox.checked = mode === 'regexp';
247259
savedKeywords = patternInput.value = keywords || '';
248260

249261

250262
caseCheckbox.disabled =
251263
blurInputCheckbox.disabled =
264+
blurTitleCheckbox.disabled =
252265
showValueCheckbox.disabled =
253266
regexpCheckbox.disabled =
254267
patternInput.disabled =

popup/main.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@
2727
<div class="settings-conainer">
2828

2929
<div class="checkbox-container">
30+
<label>
31+
<input type="checkbox" class="custom-checkbox blur-title" id="blurTitleCheckbox">
32+
<span title="Blur title of tabs"></span>
33+
</label>
3034
<label>
3135
<input type="checkbox" class="custom-checkbox blur-input" id="blurInputCheckbox">
32-
<span title="Blue value of `input` tag"></span>
36+
<span title="Blur value of `input` tag"></span>
3337
</label>
3438
<label>
3539
<input type="checkbox" class="custom-checkbox show-value" id="showValueCheckbox">

0 commit comments

Comments
 (0)