Use parceljs to build, use TS, use CSS for hiding
This commit is contained in:
parent
22384ab498
commit
1b2d628a84
12 changed files with 3995 additions and 102 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
build/
|
||||
src/.cache
|
||||
src/node_modules
|
88
hider.js
88
hider.js
|
@ -1,88 +0,0 @@
|
|||
class TwitterHider {
|
||||
processedAttribute = 'data-twitterhider-processed';
|
||||
notProcessedSelector = `:not([${this.processedAttribute}])`;
|
||||
|
||||
selectors = {
|
||||
countText: `span.css-901oao.css-16my406.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0${this.notProcessedSelector}`,
|
||||
replyContainer: `div[data-testid="reply"]${this.notProcessedSelector}`,
|
||||
retweetContainer: `div[data-testid="retweet"]${this.notProcessedSelector},div[data-testid="unretweet"]${this.notProcessedSelector}`,
|
||||
likeContainer: `div[data-testid="like"]${this.notProcessedSelector},div[data-testid="unlike"]${this.notProcessedSelector}`
|
||||
};
|
||||
|
||||
preferences = {};
|
||||
|
||||
constructor(preferences) {
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
init() {
|
||||
if (
|
||||
!this.preferences.hideLikes
|
||||
&& this.preferences.hideRetweets
|
||||
&& this.preferences.hideReplies
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setInterval(() => this.run(), 500);
|
||||
}
|
||||
|
||||
run() {
|
||||
if (this.preferences.hideLikes) this.hideLikeCounts();
|
||||
if (this.preferences.hideRetweets) this.hideRetweetCounts();
|
||||
if (this.preferences.hideReplies) this.hideReplyCounts();
|
||||
}
|
||||
|
||||
hideLikeCounts() {
|
||||
const elements = [
|
||||
...document.querySelectorAll(this.selectors.likeContainer),
|
||||
...this.findMainTweetCountByLabelText("Likes")
|
||||
];
|
||||
|
||||
this.omitElements(elements);
|
||||
}
|
||||
|
||||
hideRetweetCounts() {
|
||||
const elements = [
|
||||
...document.querySelectorAll(this.selectors.retweetContainer),
|
||||
...this.findMainTweetCountByLabelText("Retweets")
|
||||
];
|
||||
|
||||
this.omitElements(elements);
|
||||
}
|
||||
|
||||
hideReplyCounts() {
|
||||
const elements = document.querySelectorAll(this.selectors.replyContainer);
|
||||
this.omitElements(elements);
|
||||
}
|
||||
|
||||
omitElements(elements) {
|
||||
elements.forEach((element) => {
|
||||
this.markElementAsProcessed(element);
|
||||
|
||||
const textElement = element.querySelector(this.selectors.countText);
|
||||
|
||||
if (textElement !== null)
|
||||
this.omitElement(textElement);
|
||||
});
|
||||
}
|
||||
|
||||
omitElement(element) {
|
||||
element.innerHTML = "???";
|
||||
}
|
||||
|
||||
markElementAsProcessed(element) {
|
||||
element.setAttribute(this.processedAttribute, true);
|
||||
}
|
||||
|
||||
findMainTweetCountByLabelText(labelText) {
|
||||
return [...document.querySelectorAll(this.selectors.countText)]
|
||||
.filter(element => element.innerHTML === labelText)
|
||||
.map(element => {
|
||||
const wrappingDiv = element.parentElement.parentElement.parentElement;
|
||||
const countContainer = wrappingDiv.children[0];
|
||||
|
||||
return countContainer;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
import { TwitterHider } from "./hider";
|
||||
import { Preferences } from "./interfaces/preferences";
|
||||
|
||||
|
||||
class Background {
|
||||
static async init() {
|
||||
if (await this.checkIfFirstStart()) {
|
||||
|
@ -8,20 +12,12 @@ class Background {
|
|||
}
|
||||
|
||||
static async listen() {
|
||||
const preferences = await this.getSavedPreferences();
|
||||
const preferences: Preferences = await this.getSavedPreferences();
|
||||
const hider = new TwitterHider(preferences);
|
||||
|
||||
hider.init();
|
||||
}
|
||||
|
||||
static checkIfFirstStart() {
|
||||
return new Promise(resolve => {
|
||||
chrome.storage.local.get('setup', data => {
|
||||
resolve(!data.setup);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static setup() {
|
||||
const defaults = {
|
||||
hideLikes: true,
|
||||
|
@ -31,13 +27,21 @@ class Background {
|
|||
};
|
||||
|
||||
return new Promise(resolve => {
|
||||
chrome.storage.local.set(defaults, () => resolve());
|
||||
globalThis.chrome.storage.local.set(defaults, () => resolve());
|
||||
});
|
||||
}
|
||||
|
||||
static getSavedPreferences() {
|
||||
static checkIfFirstStart(): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
chrome.storage.local.get(['hideLikes', 'hideReplies', 'hideRetweets'], data => {
|
||||
globalThis.chrome.storage.local.get('setup', data => {
|
||||
resolve(!data.setup);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static getSavedPreferences(): Promise<Preferences> {
|
||||
return new Promise(resolve => {
|
||||
globalThis.chrome.storage.local.get(['hideLikes', 'hideReplies', 'hideRetweets'], (data: Preferences) => {
|
||||
resolve(data);
|
||||
});
|
||||
})
|
43
src/hider.css
Normal file
43
src/hider.css
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Feed tweets
|
||||
*/
|
||||
|
||||
body[data-hidereplies]
|
||||
div[data-testid="reply"]
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body[data-hideretweets]
|
||||
div[data-testid="retweet"]
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body[data-hidelikes]
|
||||
div[data-testid="like"]
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Single tweet (example: https://twitter.com/AstronoMegD/status/1248141555589951488)
|
||||
*/
|
||||
|
||||
body[data-hideretweets]
|
||||
div.css-1dbjc4n.r-1ila09b.r-qklmqi.r-1adg3ll
|
||||
div.css-1dbjc4n.r-1kfrmmb.r-1efd50x.r-5kkj8d.r-18u37iz.r-9qu9m4
|
||||
a[href$="retweets"]
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-vw2c0b.r-ad9z0x.r-bcqeeo.r-d3hbe1.r-1wgg2b2.r-axxi2z.r-qvutc0
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body[data-hideretweets]
|
||||
div.css-1dbjc4n.r-1ila09b.r-qklmqi.r-1adg3ll
|
||||
div.css-1dbjc4n.r-1kfrmmb.r-1efd50x.r-5kkj8d.r-18u37iz.r-9qu9m4
|
||||
a[href$="likes"]
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-vw2c0b.r-ad9z0x.r-bcqeeo.r-d3hbe1.r-1wgg2b2.r-axxi2z.r-qvutc0
|
||||
span.css-901oao.css-16my406.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0 {
|
||||
display: none;
|
||||
}
|
84
src/hider.ts
Normal file
84
src/hider.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import { Preferences } from "./interfaces/preferences";
|
||||
|
||||
export class TwitterHider {
|
||||
private preferences: Preferences;
|
||||
|
||||
constructor(preferences: Preferences) {
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
public init() {
|
||||
this.setLikesVisibility(this.preferences.hideLikes);
|
||||
this.setRetweetsVisibility(this.preferences.hideRetweets);
|
||||
this.setRepliesVisibility(this.preferences.hideReplies);
|
||||
}
|
||||
|
||||
private setLikesVisibility(visiblity: boolean) {
|
||||
this.setAttributeOrRemoveIfNull(document.body, "data-hidelikes", this.trueStringOrNull(visiblity));
|
||||
}
|
||||
|
||||
private setRetweetsVisibility(visiblity: boolean) {
|
||||
this.setAttributeOrRemoveIfNull(document.body, "data-hideretweets", this.trueStringOrNull(visiblity));
|
||||
}
|
||||
|
||||
private setRepliesVisibility(visiblity: boolean) {
|
||||
this.setAttributeOrRemoveIfNull(document.body, "data-hidereplies", this.trueStringOrNull(visiblity));
|
||||
}
|
||||
|
||||
private setAttributeOrRemoveIfNull(element: HTMLElement, attributeName: string, value: string) {
|
||||
if (!value) {
|
||||
element.removeAttribute(attributeName);
|
||||
return;
|
||||
}
|
||||
|
||||
element.setAttribute(attributeName, value);
|
||||
}
|
||||
|
||||
private trueStringOrNull(value: boolean) {
|
||||
return value ? "true" : null;
|
||||
}
|
||||
|
||||
// hideRetweetCounts() {
|
||||
// const elements = [
|
||||
// ...document.querySelectorAll(this.selectors.retweetContainer),
|
||||
// ...this.findMainTweetCountByLabelText("Retweets")
|
||||
// ];
|
||||
|
||||
// this.omitElements(elements);
|
||||
// }
|
||||
|
||||
// hideReplyCounts() {
|
||||
// const elements = document.querySelectorAll(this.selectors.replyContainer);
|
||||
// this.omitElements(elements);
|
||||
// }
|
||||
|
||||
// omitElements(elements) {
|
||||
// elements.forEach((element) => {
|
||||
// this.markElementAsProcessed(element);
|
||||
|
||||
// const textElement = element.querySelector(this.selectors.countText);
|
||||
|
||||
// if (textElement !== null)
|
||||
// this.omitElement(textElement);
|
||||
// });
|
||||
// }
|
||||
|
||||
// omitElement(element) {
|
||||
// element.innerHTML = "???";
|
||||
// }
|
||||
|
||||
// markElementAsProcessed(element) {
|
||||
// element.setAttribute(this.processedAttribute, true);
|
||||
// }
|
||||
|
||||
// findMainTweetCountByLabelText(labelText) {
|
||||
// return [...document.querySelectorAll(this.selectors.countText)]
|
||||
// .filter(element => element.innerHTML === labelText)
|
||||
// .map(element => {
|
||||
// const wrappingDiv = element.parentElement.parentElement.parentElement;
|
||||
// const countContainer = wrappingDiv.children[0];
|
||||
|
||||
// return countContainer;
|
||||
// });
|
||||
// }
|
||||
}
|
5
src/interfaces/preferences.ts
Normal file
5
src/interfaces/preferences.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export interface Preferences {
|
||||
hideLikes: boolean;
|
||||
hideRetweets: boolean;
|
||||
hideReplies: boolean;
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
{
|
||||
"name": "Twitter Metric Hider",
|
||||
"description": "Hides twitter like, reply and retweet counts.",
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.0",
|
||||
"manifest_version": 2,
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["http://twitter.com/*", "https://twitter.com/*"],
|
||||
"js": ["hider.js", "content.js"]
|
||||
"js": ["hider.js", "content.js"],
|
||||
"css": ["hider.css"]
|
||||
}
|
||||
],
|
||||
"browser_action": {
|
3823
src/package-lock.json
generated
Normal file
3823
src/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
18
src/package.json
Normal file
18
src/package.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"cssnano": "^4.1.10",
|
||||
"typescript": "^3.8.3",
|
||||
"cpx": "1.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cpx manifest.json ../build/ && parcel build content.ts hider.ts popup.html hider.css --no-source-maps -d ../build/"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 3 Chrome versions",
|
||||
"Firefox 63",
|
||||
"Node 11"
|
||||
],
|
||||
"browser": {
|
||||
"process": false
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue