MrOtherGuy / fx-autoconfig

Load custom javascript in browser context
Mozilla Public License 2.0
173 stars 11 forks source link

Theme API #51

Open aminought opened 3 months ago

aminought commented 3 months ago

Hello, I love your project. Can I access Theme API?

MrOtherGuy commented 3 months ago

If you mean the Webextension Theme API then no, at least not directly. I have not added any interfaces or helpers to use any extension APIs. It might be possible to create such interface somehow, but this might turn out to be quite difficult.

I understand that having access to extension APIs could be useful at least in some cases, but I would recommend writing an actual extension if what you are doing can more easily be done by using extension APIs.

aminought commented 3 months ago

@MrOtherGuy I'm still new to Firefox modding, I can't figure out how to implement what I want. I created uc.js mod that calculates the color of the favicon and put it a in css variable that my other mod uses. And I want to somehow pass the same color to the Sidebery in order to color the active tab with it. The problem is that the extension is a separate document that does not have access to Firefox css variables. I learned from the VivaldiFox code that this can be done by patching the theme. Please tell me, is it possible to do this without using the Webxtension Theme API?

MrOtherGuy commented 3 months ago

Huh. Sounds like an interesting use-case. I'm not sure if it would work. I kinda think that you would actually need webextension Theme API tor this. And while you vould write a "mock-up" API with same interface that could be used fromparent process .uc.js scripts it will probably not be able to have access to same values that are actually used by extensions.

But that's just my hunch, I would need to dig into this more to say anything definite.

aminought commented 3 months ago

Thanks for the reply. I've been trying to find suitable objects and functions that can be used in .uc.js scripts, but unsuccessfully. It seems that the Theme API directly uses code written in Rust, and there are no alternatives... Do you have time to help me figure this out, what if there is still some way?

aminought commented 3 months ago

Maybe it's a stupid idea, but can I somehow change the userContent.css from .uc.js script and immediately apply the changes?

aminought commented 3 months ago

@MrOtherGuy I managed to copy some code from ext-theme.js and integrate into my script:

const { LightweightThemeManager } = ChromeUtils.importESModule(
    "resource://gre/modules/LightweightThemeManager.sys.mjs"
);
const { EventEmitter } = ChromeUtils.importESModule(
  "resource://gre/modules/EventEmitter.sys.mjs"
);

const onUpdatedEmitter = new EventEmitter();

var themeData = LightweightThemeManager.themeData;
themeData.theme.tab_selected = "red";
const theme = {
    details: { colors: themeData.theme, images: null, properties: null },
};
onUpdatedEmitter.emit("theme-updated", theme);
Services.obs.notifyObservers(themeData, "lightweight-theme-styling-update");

Now I can change theme (color is changing in the native tab bar), but the line onUpdatedEmitter.emit("theme-updated", theme); doesn't work. I'm not a JS-developer, so I don't understand how this EventEmitter actually works, but Sidebery doesn't see this event. What am I doing wrong?

MrOtherGuy commented 3 months ago

That's actually just about what I was toying with a bit. No extension is going to see that change, at best they could see onUpdated event.

I believe what's happening here is exactly what I was saying before; you can create a new instance of this EventEmitter and get correctly structured data from LightWeightThemeManager, but these won't be the same instances of these objects that the extension Theme API is using internally. So you can indeed change the properties of these new objects, but the mechanism that forwards that info to the extension doesn't have a clue that you changed anything because you are.

I don't know if there is any way to access the actual instance of the LightWeightThemeManager that is talking to extensions. Or perhaps there is some other way to achieve what you want, but I can't think of any at the moment. Modifying userContent.css is certainly possible, but that isn't super nice and besides, I've found that userContent.css seems to be sort of "cached" in some way at least for web content processes (and I would guess for extension process as well).