Skip to content

Commit

Permalink
Merge branch 'master' into vanilla-video-safari
Browse files Browse the repository at this point in the history
  • Loading branch information
marcustyphoon authored Jun 23, 2024
2 parents 28f47b7 + b7ba85b commit b8712b0
Show file tree
Hide file tree
Showing 36 changed files with 221 additions and 354 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"root": true,
"env": {
"browser": true,
"es2021": true,
Expand Down
6 changes: 2 additions & 4 deletions src/action/render_scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ const configSection = document.getElementById('configuration');
const configSectionLink = document.querySelector('a[href="#configuration"]');
const scriptsDiv = configSection.querySelector('.scripts');

const { getURL } = browser.runtime;

const getInstalledScripts = async function () {
const url = getURL('/features/_index.json');
const url = browser.runtime.getURL('/features/_index.json');
const file = await fetch(url);
const installedScripts = await file.json();

Expand Down Expand Up @@ -137,7 +135,7 @@ const renderScripts = async function () {
const disabledScripts = installedScripts.filter(scriptName => enabledScripts.includes(scriptName) === false);

for (const scriptName of [...orderedEnabledScripts, ...disabledScripts]) {
const url = getURL(`/features/${scriptName}.json`);
const url = browser.runtime.getURL(`/features/${scriptName}.json`);
const file = await fetch(url);
const {
title = scriptName,
Expand Down
24 changes: 17 additions & 7 deletions src/content_scripts/main.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
'use strict';

{
const { getURL } = browser.runtime;
const redpop = [...document.scripts].some(({ src }) => src.includes('/pop/'));
const isReactLoaded = () => document.querySelector('[data-rh]') === null;

const restartListeners = {};

const runScript = async function (name) {
const scriptPath = getURL(`/features/${name}.js`);
const scriptPath = browser.runtime.getURL(`/features/${name}.js`);
const { main, clean, stylesheet, onStorageChanged } = await import(scriptPath);

main().catch(console.error);

if (stylesheet) {
const link = Object.assign(document.createElement('link'), {
rel: 'stylesheet',
href: getURL(`/features/${name}.css`)
href: browser.runtime.getURL(`/features/${name}.css`)
});
document.documentElement.appendChild(link);
}
Expand All @@ -38,13 +37,13 @@
};

const destroyScript = async function (name) {
const scriptPath = getURL(`/features/${name}.js`);
const scriptPath = browser.runtime.getURL(`/features/${name}.js`);
const { clean, stylesheet } = await import(scriptPath);

clean().catch(console.error);

if (stylesheet) {
document.querySelector(`link[href="${getURL(`/features/${name}.css`)}"]`)?.remove();
document.querySelector(`link[href="${browser.runtime.getURL(`/features/${name}.css`)}"]`)?.remove();
}

browser.storage.onChanged.removeListener(restartListeners[name]);
Expand All @@ -70,16 +69,27 @@
};

const getInstalledScripts = async function () {
const url = getURL('/features/_index.json');
const url = browser.runtime.getURL('/features/_index.json');
const file = await fetch(url);
const installedScripts = await file.json();

return installedScripts;
};

const initMainWorld = () => {
const { nonce } = [...document.scripts].find(script => script.getAttributeNames().includes('nonce'));
const script = document.createElement('script');
script.type = 'module';
script.nonce = nonce;
script.src = browser.runtime.getURL('/main_world/index.js');
document.documentElement.append(script);
};

const init = async function () {
$('style.xkit').remove();

initMainWorld();

browser.storage.onChanged.addListener(onStorageChanged);

const installedScripts = await getInstalledScripts();
Expand All @@ -89,7 +99,7 @@
* fixes WebKit (Chromium, Safari) simultaneous import failure of files with unresolved top level await
* @see https://github.com/sveltejs/kit/issues/7805#issuecomment-1330078207
*/
await Promise.all(['css_map', 'language_data', 'user'].map(name => import(getURL(`/utils/${name}.js`))));
await Promise.all(['css_map', 'language_data', 'user'].map(name => import(browser.runtime.getURL(`/utils/${name}.js`))));

installedScripts
.filter(scriptName => enabledScripts.includes(scriptName))
Expand Down
2 changes: 1 addition & 1 deletion src/features/postblock/options/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ header {

appearance: none;
background-color: transparent;
color: rgb(var(--deprecated-accent));
color: rgb(var(--accent));
cursor: pointer;
font-weight: bold;
}
2 changes: 1 addition & 1 deletion src/features/quote_replies.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ let newTab;

const processNotifications = notifications => notifications.forEach(async notification => {
const { notification: notificationProps, tumblelogName } = await inject(
'/features/quote_replies/get_notification_props.js',
'/main_world/get_notification_props.js',
[],
notification
);
Expand Down
29 changes: 0 additions & 29 deletions src/features/quote_replies/get_notification_props.js

This file was deleted.

5 changes: 5 additions & 0 deletions src/main_world/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"jsdoc/require-jsdoc": "off"
}
}
35 changes: 35 additions & 0 deletions src/main_world/api_fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export default function apiFetch (resource, init = {}) {
// add XKit header to all API requests
init.headers ??= {};
init.headers['X-XKit'] = '1';

// convert all keys in the body to snake_case
if (init.body !== undefined) {
const objects = [init.body];

while (objects.length !== 0) {
const currentObjects = objects.splice(0);

currentObjects.forEach(obj => {
Object.keys(obj).forEach(key => {
const snakeCaseKey = key
.replace(/^[A-Z]/, match => match.toLowerCase())
.replace(/[A-Z]/g, match => `_${match.toLowerCase()}`);

if (snakeCaseKey !== key) {
obj[snakeCaseKey] = obj[key];
delete obj[key];
}
});
});

objects.push(
...currentObjects
.flatMap(Object.values)
.filter(value => value instanceof Object)
);
}
}

return window.tumblr.apiFetch(resource, init);
}
21 changes: 21 additions & 0 deletions src/main_world/control_tags_input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export default function controlTagsInput ({ add, remove }) {
add = add.map(tag => tag.trim()).filter((tag, index, array) => array.indexOf(tag) === index);

const selectedTagsElement = document.getElementById('selected-tags');
if (!selectedTagsElement) { return; }

const reactKey = Object.keys(selectedTagsElement).find(key => key.startsWith('__reactFiber'));
let fiber = selectedTagsElement[reactKey];

while (fiber !== null) {
let tags = fiber.stateNode?.state?.tags;
if (Array.isArray(tags)) {
tags.push(...add.filter(tag => tags.includes(tag) === false));
tags = tags.filter(tag => remove.includes(tag) === false);
fiber.stateNode.setState({ tags });
break;
} else {
fiber = fiber.return;
}
}
}
1 change: 1 addition & 0 deletions src/main_world/css_map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => window.tumblr.getCssMap();
14 changes: 14 additions & 0 deletions src/main_world/get_notification_props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function getNotificationProps () {
const notificationElement = this;
const reactKey = Object.keys(notificationElement).find(key => key.startsWith('__reactFiber'));
let fiber = notificationElement[reactKey];

while (fiber !== null) {
const props = fiber.memoizedProps || {};
if (props?.notification !== undefined) {
return props;
} else {
fiber = fiber.return;
}
}
}
30 changes: 30 additions & 0 deletions src/main_world/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const moduleCache = {};

document.documentElement.addEventListener('xkitinjectionrequest', async event => {
const { detail, target } = event;
const { id, path, args } = JSON.parse(detail);

try {
moduleCache[path] ??= await import(path);
const func = moduleCache[path].default;

const result = await func.apply(target, args);
target.dispatchEvent(
new CustomEvent('xkitinjectionresponse', { detail: JSON.stringify({ id, result }) })
);
} catch (exception) {
target.dispatchEvent(
new CustomEvent('xkitinjectionresponse', {
detail: JSON.stringify({
id,
exception: {
message: exception.message,
name: exception.name,
stack: exception.stack,
...exception
}
})
})
);
}
});
1 change: 1 addition & 0 deletions src/main_world/language_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => window.tumblr.languageData;
1 change: 1 addition & 0 deletions src/main_world/navigate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default location => window.tumblr.navigate(location);
9 changes: 9 additions & 0 deletions src/main_world/post_request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function postRequest (resource, body) {
return fetch(resource, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body
}).then(async response =>
response.ok ? response.json() : Promise.reject(await response.json())
);
}
13 changes: 13 additions & 0 deletions src/main_world/test_header_element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default function testHeaderElement (selector) {
const menuElement = this;
const reactKey = Object.keys(menuElement).find(key => key.startsWith('__reactFiber'));
let fiber = menuElement[reactKey];

while (fiber !== null) {
if (fiber.elementType === 'header') {
return fiber.stateNode.matches(selector);
} else {
fiber = fiber.return;
}
}
}
14 changes: 14 additions & 0 deletions src/main_world/unbury_blog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function unburyBlog () {
const element = this;
const reactKey = Object.keys(element).find(key => key.startsWith('__reactFiber'));
let fiber = element[reactKey];

while (fiber !== null) {
const { blog, blogSettings } = fiber.memoizedProps || {};
if (blog ?? blogSettings) {
return blog ?? blogSettings;
} else {
fiber = fiber.return;
}
}
}
14 changes: 14 additions & 0 deletions src/main_world/unbury_notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function unburyNotification () {
const notificationElement = this;
const reactKey = Object.keys(notificationElement).find(key => key.startsWith('__reactFiber'));
let fiber = notificationElement[reactKey];

while (fiber !== null) {
const { notification } = fiber.memoizedProps || {};
if (notification !== undefined) {
return notification;
} else {
fiber = fiber.return;
}
}
}
14 changes: 14 additions & 0 deletions src/main_world/unbury_timeline_object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function unburyTimelineObject () {
const postElement = this;
const reactKey = Object.keys(postElement).find(key => key.startsWith('__reactFiber'));
let fiber = postElement[reactKey];

while (fiber !== null) {
const { timelineObject } = fiber.memoizedProps || {};
if (timelineObject !== undefined) {
return timelineObject;
} else {
fiber = fiber.return;
}
}
}
2 changes: 1 addition & 1 deletion src/utils/css_map.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { inject } from './inject.js';

export const cssMap = await inject('/utils/inject/css_map.js');
export const cssMap = await inject('/main_world/css_map.js');

/**
* @param {...string} keys - One or more element source names
Expand Down
Loading

0 comments on commit b8712b0

Please sign in to comment.