Skip to content

Commit

Permalink
Merge branch 'master' into mute
Browse files Browse the repository at this point in the history
  • Loading branch information
marcustyphoon committed Jun 23, 2024
2 parents 4baa9d0 + 52f231a commit 6b4fd92
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 31 deletions.
1 change: 0 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ jobs:
env:
WEB_EXT_API_KEY: ${{ secrets.WEB_EXT_API_KEY }}
WEB_EXT_API_SECRET: ${{ secrets.WEB_EXT_API_SECRET }}
WEB_EXT_ID: ${{ secrets.WEB_EXT_ID }}
chrome:
name: Chrome
runs-on: ubuntu-latest
Expand Down
14 changes: 7 additions & 7 deletions src/features/collapsed_queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import { filterPostElements } from '../utils/interface.js';
import { getPreferences } from '../utils/preferences.js';
import { onNewPosts } from '../utils/mutations.js';
import { keyToCss } from '../utils/css_map.js';
import { anyQueueTimelineFilter, anyDraftsTimelineFilter } from '../utils/timeline_id.js';

const excludeClass = 'xkit-collapsed-queue-done';
const wrapperClass = 'xkit-collapsed-queue-wrapper';
const containerClass = 'xkit-collapsed-queue-container';
const footerSelector = keyToCss('footerWrapper');

let timelineRegex;
let timeline;

const processPosts = async function (postElements) {
filterPostElements(postElements, { excludeClass, timeline: timelineRegex }).forEach(async postElement => {
filterPostElements(postElements, { excludeClass, timeline }).forEach(async postElement => {
const headerElement = postElement.querySelector('header');
const footerElement = postElement.querySelector(footerSelector);

Expand All @@ -30,11 +31,10 @@ export const main = async function () {
const { runInQueue, runInDrafts } = await getPreferences('collapsed_queue');
if (![runInQueue, runInDrafts].some(Boolean)) return;

const regexGroup = [
...runInQueue ? ['queue'] : [],
...runInDrafts ? ['draft'] : []
].join('|');
timelineRegex = new RegExp(`/v2/blog/[^/]+/posts/(${regexGroup})`);
timeline = [
runInQueue && anyQueueTimelineFilter,
runInDrafts && anyDraftsTimelineFilter
].filter(Boolean);

onNewPosts.addListener(processPosts);
};
Expand Down
3 changes: 2 additions & 1 deletion src/features/mutual_checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { onNewPosts, onNewNotifications, pageModifications } from '../utils/muta
import { dom } from '../utils/dom.js';
import { getPreferences } from '../utils/preferences.js';
import { translate } from '../utils/language_data.js';
import { followingTimelineSelector } from '../utils/timeline_id.js';

const mutualIconClass = 'xkit-mutual-icon';
const hiddenAttribute = 'data-mutual-checker-hidden';
Expand Down Expand Up @@ -34,7 +35,7 @@ const styleElement = buildStyle(`
margin-right: 0.5ch;
}
[data-timeline="/v2/timeline/dashboard"] [${hiddenAttribute}] article {
${followingTimelineSelector} [${hiddenAttribute}] article {
display: none;
}
Expand Down
3 changes: 2 additions & 1 deletion src/features/no_recommended/hide_recommended_posts.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { buildStyle, getTimelineItemWrapper, filterPostElements, postSelector } from '../../utils/interface.js';
import { onNewPosts } from '../../utils/mutations.js';
import { timelineObject } from '../../utils/react_props.js';
import { followingTimelineFilter } from '../../utils/timeline_id.js';

const excludeClass = 'xkit-no-recommended-posts-done';
const hiddenAttribute = 'data-no-recommended-posts-hidden';
const unHiddenAttribute = 'data-no-recommended-posts-many';
const timeline = /\/v2\/timeline\/dashboard/;
const timeline = followingTimelineFilter;
const includeFiltered = true;

const styleElement = buildStyle(`
Expand Down
5 changes: 3 additions & 2 deletions src/features/seen_posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { filterPostElements, getTimelineItemWrapper, postSelector } from '../uti
import { getPreferences } from '../utils/preferences.js';
import { onNewPosts } from '../utils/mutations.js';
import { keyToCss } from '../utils/css_map.js';
import { followingTimelineFilter, followingTimelineSelector } from '../utils/timeline_id.js';

const excludeAttribute = 'data-seen-posts-done';
const timeline = '/v2/timeline/dashboard';
const timeline = followingTimelineFilter;
const includeFiltered = true;

const dimAttribute = 'data-seen-posts-seen';
Expand Down Expand Up @@ -45,7 +46,7 @@ const markAsSeen = (element) => {
};

const lengthenTimelines = () =>
[...document.querySelectorAll(`[data-timeline="${timeline}"]`)].forEach(timelineElement => {
[...document.querySelectorAll(followingTimelineSelector)].forEach(timelineElement => {
if (!timelineElement.querySelector(keyToCss('manualPaginatorButtons'))) {
timelineElement.classList.add(lengthenedClass);
}
Expand Down
15 changes: 7 additions & 8 deletions src/features/show_originals.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { onNewPosts } from '../utils/mutations.js';
import { keyToCss } from '../utils/css_map.js';
import { translate } from '../utils/language_data.js';
import { userBlogs } from '../utils/user.js';
import { followingTimelineFilter, anyBlogTimelineFilter, blogTimelineFilter, blogSubsTimelineFilter, timelineSelector } from '../utils/timeline_id.js';

const hiddenAttribute = 'data-show-originals-hidden';
const lengthenedClass = 'xkit-show-originals-lengthened';
const controlsClass = 'xkit-show-originals-controls';

const blogTimelineRegex = /^\/v2\/blog\/[a-z0-9-]{1,32}\/posts$/;
const channelSelector = `${keyToCss('bar')} ~ *`;

const storageKey = 'show_originals.savedModes';
Expand Down Expand Up @@ -65,21 +65,20 @@ const addControls = async (timelineElement, location) => {
};

const getLocation = timelineElement => {
const { timeline, which } = timelineElement.dataset;

const isBlog = blogTimelineRegex.test(timeline) && !timelineElement.matches(channelSelector);
const isBlog =
anyBlogTimelineFilter(timelineElement) && !timelineElement.matches(channelSelector);

const on = {
dashboard: timeline === '/v2/timeline/dashboard',
disabled: isBlog && disabledBlogs.some(name => timeline === `/v2/blog/${name}/posts`),
dashboard: followingTimelineFilter(timelineElement),
disabled: isBlog && disabledBlogs.some(name => blogTimelineFilter(name)(timelineElement)),
peepr: isBlog,
blogSubscriptions: timeline.includes('blog_subscriptions') || which === 'blog_subscriptions'
blogSubscriptions: blogSubsTimelineFilter(timelineElement)
};
return Object.keys(on).find(location => on[location]);
};

const processTimelines = async () => {
[...document.querySelectorAll('[data-timeline]')].forEach(async timelineElement => {
[...document.querySelectorAll(timelineSelector)].forEach(async timelineElement => {
const location = getLocation(timelineElement);

const currentControls = [...timelineElement.children]
Expand Down
3 changes: 2 additions & 1 deletion src/features/tag_tracking_plus.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { onNewPosts, pageModifications } from '../utils/mutations.js';
import { dom } from '../utils/dom.js';
import { addSidebarItem, removeSidebarItem } from '../utils/sidebar.js';
import { getPreferences } from '../utils/preferences.js';
import { tagTimelineFilter } from '../utils/timeline_id.js';

const storageKey = 'tag_tracking_plus.trackedTagTimestamps';
let timestamps;
Expand Down Expand Up @@ -116,7 +117,7 @@ const processPosts = async function (postElements) {
const currentTag = decodeURIComponent(encodedCurrentTag);
if (!trackedTags.includes(currentTag)) return;

const timeline = new RegExp(`/v2/hubs/${encodedCurrentTag}/timeline`);
const timeline = tagTimelineFilter(currentTag);

let updated = false;

Expand Down
3 changes: 2 additions & 1 deletion src/features/tweaks/caught_up_line.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { keyToCss } from '../../utils/css_map.js';
import { buildStyle, getTimelineItemWrapper } from '../../utils/interface.js';
import { pageModifications } from '../../utils/mutations.js';
import { followingTimelineSelector } from '../../utils/timeline_id.js';

const hiddenAttribute = 'data-tweaks-caught-up-line-title';
const borderAttribute = 'data-tweaks-caught-up-line-border';
Expand All @@ -23,7 +24,7 @@ const styleElement = buildStyle(`
`);

const listTimelineObjectSelector = keyToCss('listTimelineObject');
const tagChicletCarouselLinkSelector = `[data-timeline="/v2/timeline/dashboard"] ${listTimelineObjectSelector} ${keyToCss('tagChicletLink')}`;
const tagChicletCarouselLinkSelector = `${followingTimelineSelector} ${listTimelineObjectSelector} ${keyToCss('tagChicletLink')}`;

const createCaughtUpLine = tagChicletCarouselItems => tagChicletCarouselItems
.map(getTimelineItemWrapper)
Expand Down
3 changes: 2 additions & 1 deletion src/features/tweaks/hide_liked_posts.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { onNewPosts } from '../../utils/mutations.js';
import { buildStyle, getTimelineItemWrapper, filterPostElements } from '../../utils/interface.js';
import { isMyPost, timelineObject } from '../../utils/react_props.js';
import { followingTimelineFilter } from '../../utils/timeline_id.js';

const timeline = /\/v2\/timeline\/dashboard/;
const timeline = followingTimelineFilter;

const hiddenAttribute = 'data-tweaks-hide-liked-posts-hidden';
const styleElement = buildStyle(`[${hiddenAttribute}] article { display: none; }`);
Expand Down
3 changes: 2 additions & 1 deletion src/features/tweaks/hide_my_posts.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { onNewPosts } from '../../utils/mutations.js';
import { buildStyle, getTimelineItemWrapper, filterPostElements } from '../../utils/interface.js';
import { isMyPost } from '../../utils/react_props.js';
import { followingTimelineFilter } from '../../utils/timeline_id.js';

const excludeClass = 'xkit-tweaks-hide-my-posts-done';
const timeline = /\/v2\/timeline\/dashboard/;
const timeline = followingTimelineFilter;

const hiddenAttribute = 'data-tweaks-hide-my-posts-hidden';
const styleElement = buildStyle(`[${hiddenAttribute}] article { display: none; }`);
Expand Down
4 changes: 4 additions & 0 deletions src/utils/inject.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/**
* Runs a script in the page's "main" execution environment and returns its result.
* This permits access to variables exposed by the Tumblr web platform that are normally inaccessible
* in the content script sandbox.
* See the src/main_world directory and [../main_world/index.js](../main_world/index.js).
* @param {string} path - Absolute path of script to inject (will be fed to `runtime.getURL()`)
* @param {Array} [args] - Array of arguments to pass to the script
* @param {Element} [target] - Target element; will be accessible as the `this` value in the injected function.
Expand Down
20 changes: 14 additions & 6 deletions src/utils/interface.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { keyToCss } from './css_map.js';
import { dom } from './dom.js';
import { timelineSelector } from './timeline_id.js';

export const postSelector = '[tabindex="-1"][data-id]';
export const blogViewSelector = '[style*="--blog-title-color"] *';
Expand All @@ -19,7 +20,9 @@ const targetWrapperSelector = keyToCss(
* @returns {Element | null} The timeline item wrapper
*/
export const getTimelineItemWrapper = element =>
element.closest(cellSelector) || element.closest(listTimelineObjectSelector);
(element.closest('[data-timeline-id]') && element.closest(listTimelineObjectSelector)?.parentElement) ||
element.closest(cellSelector) ||
element.closest(listTimelineObjectSelector);

/**
* @param {Element} element Element within a popover wrapper
Expand All @@ -35,7 +38,7 @@ export const getPopoverWrapper = element => {
/**
* @typedef {object} PostFilterOptions
* @property {string} [excludeClass] - Classname to exclude and add
* @property {RegExp|string} [timeline] - Filter results to matching [data-timeline] children
* @property {Function|Function[]} [timeline] - Filter results to matching timeline element children
* @property {boolean} [noBlogView] - Whether to exclude posts in the blog view modal
* @property {boolean} [includeFiltered] - Whether to include filtered posts
*/
Expand All @@ -51,10 +54,15 @@ export const filterPostElements = function (postElements, { excludeClass, timeli
.map(element => element.closest(postSelector))
.filter(Boolean);

if (timeline instanceof RegExp) {
postElements = postElements.filter(postElement => timeline.test(postElement.closest('[data-timeline]')?.dataset.timeline));
} else if (timeline) {
postElements = postElements.filter(postElement => timeline === postElement.closest('[data-timeline]')?.dataset.timeline);
if (timeline) {
const timelineFilters = [timeline].flat().filter(Boolean);
postElements = postElements.filter(postElement => {
const timelineElement = postElement.closest(timelineSelector);
return (
timelineElement &&
timelineFilters.some(timelineFilter => timelineFilter(timelineElement))
);
});
}

if (noBlogView) {
Expand Down
7 changes: 6 additions & 1 deletion src/utils/modals.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ export const showErrorModal = exception => {
showModal({
title: 'Something went wrong.',
message: [
[exception.body?.errors?.[0]?.detail, exception.errors?.[0]?.detail, exception.message]
[
exception.body?.errors?.[0]?.detail,
exception.errors?.[0]?.detail,
exception.message,
browser.runtime?.id === undefined && 'Please refresh this browser tab!'
]
.filter(Boolean)
.join('\n\n')
],
Expand Down
43 changes: 43 additions & 0 deletions src/utils/timeline_id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const createSelector = (...components) => `:is(${components.filter(Boolean).join(', ')})`;

export const timelineSelector = ':is([data-timeline], [data-timeline-id])';

const anyBlog = '[a-z0-9-]{1,32}';

export const followingTimelineFilter = ({ dataset: { timeline, timelineId } }) =>
timeline === '/v2/timeline/dashboard' ||
timelineId === '/dashboard/following';

export const followingTimelineSelector = createSelector(
`[data-timeline="${'/v2/timeline/dashboard'}"]`,
`[data-timeline-id="${'/dashboard/following'}"]`
);

// includes "channel" user blog view page
export const anyBlogTimelineFilter = ({ dataset: { timeline, timelineId } }) =>
timeline?.match(`/v2/blog/${anyBlog}/posts`) ||
timelineId?.match(`peepr-posts-${anyBlog}-undefined-undefined-undefined-undefined-undefined-undefined`) ||
timelineId?.match(`blog-view-${anyBlog}`);

// includes "channel" user blog view page
export const blogTimelineFilter = blog =>
({ dataset: { timeline, timelineId } }) =>
timeline === `/v2/blog/${blog}/posts` ||
timelineId === `peepr-posts-${blog}-undefined-undefined-undefined-undefined-undefined-undefined` ||
timelineId === `blog-view-${blog}`;

export const blogSubsTimelineFilter = ({ dataset: { timeline, which, timelineId } }) =>
timeline === '/v2/timeline?which=blog_subscriptions' ||
which === 'blog_subscriptions' ||
timelineId === '/dashboard/blog_subs';

export const anyDraftsTimelineFilter = ({ dataset: { timeline, timelineId } }) =>
timeline?.match(`/v2/blog/${anyBlog}/posts/draft`);

export const anyQueueTimelineFilter = ({ dataset: { timeline, timelineId } }) =>
timeline?.match(`/v2/blog/${anyBlog}/posts/queue`);

export const tagTimelineFilter = tag =>
({ dataset: { timeline, timelineId } }) =>
timeline === `/v2/hubs/${encodeURIComponent(tag)}/timeline` ||
timelineId?.startsWith(`hubsTimeline-${tag}-recent-`);

0 comments on commit 6b4fd92

Please sign in to comment.