diff --git a/README.md b/README.md index 66f2a1ad..d2dcf919 100644 --- a/README.md +++ b/README.md @@ -78,9 +78,11 @@ Everything is designed and engineered following my taste and vision. This is a p ![Hashtag stuffing collapsing](readme-assets/hashtag-stuffing-collapsing.jpg) -- Any paragraphs, except the first one, with more than 3 hashtags will be collapsed. +- First paragraph of post content with more than 3 hashtags will be collapsed to max 3 lines. +- Subsequent paragraphs after first paragraph with more than 3 hashtags will be collapsed to 1 line. +- Adjacent paragraphs with more than 1 hashtag after collapsed paragraphs will be collapsed to 1 line. - If there are text around or between the hashtags, they will not be collapsed. -- Collapsed hashtags will be a single line with `...` at the end. +- Collapsed hashtags will be appended with `...` at the end. - They are also slightly faded out to reduce visual noise. - Opening the post view will reveal the hashtags uncollapsed. diff --git a/src/utils/enhance-content.js b/src/utils/enhance-content.js index 2d2586d6..1a6d70ce 100644 --- a/src/utils/enhance-content.js +++ b/src/utils/enhance-content.js @@ -174,35 +174,49 @@ function enhanceContent(content, opts = {}) { // ================ // Get the
that contains a lot of hashtags, add a class to it
if (enhancedContent.indexOf('#') !== -1) {
- const hashtagStuffedParagraph = Array.from(dom.querySelectorAll('p')).find(
- (p) => {
- let hashtagCount = 0;
- for (let i = 0; i < p.childNodes.length; i++) {
- const node = p.childNodes[i];
+ let prevIndex = null;
+ const hashtagStuffedParagraphs = Array.from(
+ dom.querySelectorAll('p'),
+ ).filter((p, index) => {
+ let hashtagCount = 0;
+ for (let i = 0; i < p.childNodes.length; i++) {
+ const node = p.childNodes[i];
- if (node.nodeType === Node.TEXT_NODE) {
- const text = node.textContent.trim();
- if (text !== '') {
- return false;
- }
- } else if (node.tagName === 'A') {
- const linkText = node.textContent.trim();
- if (!linkText || !linkText.startsWith('#')) {
- return false;
- } else {
- hashtagCount++;
- }
- } else {
+ if (node.nodeType === Node.TEXT_NODE) {
+ const text = node.textContent.trim();
+ if (text !== '') {
return false;
}
+ } else if (node.tagName === 'BR') {
+ // Ignore
+ } else if (node.tagName === 'A') {
+ const linkText = node.textContent.trim();
+ if (!linkText || !linkText.startsWith('#')) {
+ return false;
+ } else {
+ hashtagCount++;
+ }
+ } else {
+ return false;
}
- // Only consider "stuffing" if there are more than 3 hashtags
- return hashtagCount > 3;
- },
- );
- if (hashtagStuffedParagraph) {
- hashtagStuffedParagraph.classList.add('hashtag-stuffing');
- hashtagStuffedParagraph.title = hashtagStuffedParagraph.innerText;
+ }
+ // Only consider "stuffing" if:
+ // - there are more than 3 hashtags
+ // - there are more than 1 hashtag in adjacent paragraphs
+ if (hashtagCount > 3) {
+ prevIndex = index;
+ return true;
+ }
+ if (hashtagCount > 1 && prevIndex && index === prevIndex + 1) {
+ prevIndex = index;
+ return true;
+ }
+ });
+ if (hashtagStuffedParagraphs?.length) {
+ hashtagStuffedParagraphs.forEach((p) => {
+ p.classList.add('hashtag-stuffing');
+ p.title = p.innerText;
+ });
}
}