Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FireMonkey] Support UserCSS custom settings #293

Open
pintassilgo opened this issue Mar 12, 2021 · 51 comments
Open

[FireMonkey] Support UserCSS custom settings #293

pintassilgo opened this issue Mar 12, 2021 · 51 comments
Labels
addon: FireMonkey done ✓ Completed feature request 💡 New feature or request more feedback needed Extra attention is needed

Comments

@pintassilgo
Copy link

pintassilgo commented Mar 12, 2021

Some userStyles offer the ability to customize the style. For example:
https://userstyles.org/styles/107316/vk-plus
Mirror (converted as UserCSS): https://33kk.github.io/uso-archive/?style=107316

Here's how Stylus deals with it:
image

Apparently, there's no way to customize style settings in FM.

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

Where does the dialogue data come from?
Where does it get the names and values?

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

UserStyles.org:
image

Thus, when you click to Install, UserStyles.org generates a dynamic URL with parameters accordingly to customized settings, like
https://userstyles.org/styles/107316/vk-plus.css?ik-background=ik-none&ik-page=ik-white&ik-sidebar=ik-fixed&ik-topbar=ik-fixed&ik-images=ik-square&ik-reply=ik-fixed&ik-overlay=ik-no

So that when the style is updated, your customization is respected.

But this approach creates complete dependence on the unreliable userstyles.org. So now we have UserCSS:
https://github.com/openstyles/stylus/wiki/Writing-UserCSS#var

Newer version of Stylus automatically converts styles with installURL from userstyles.org to UserCSS, so that dynamic URL doesn't matter anymore and you can change customized settings after installing the script, which was not possible before. Also, giving the current status of userstyles.org, uso-archive was created mirroring us.o and also converting styles to UserCSS format. Click this link to see how UserCSS handles user settings:
https://cdn.jsdelivr.net/gh/33kk/uso-archive@flomaster/data/usercss/107316.user.css

Stylus:
image

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

The use of @var and logic in CSS if font-enable {.... is not standard CSS and requires a separate processor.

ATM, FireMonkey only supports the standard CSS and remain as slim as possible.

If the aim is to override or add some custom CSS settings to another userCSS so that the custom settings will remain after userCSS update, that can be done with @require in userCSS.

  • make all custom settings in a separate userCSS
  • use @require to inject above with the target userCSS
  • the order of injection can be controlled by deciding which CSS is the primary and which comes with @require

PS. I will add a guide to the Help

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

OK. I just think this is an important drawback. An UserScript can implement its own settings using storage. UserStyles need to be customizable too. And userstyles.org has that feature since... always?

If you have a better idea to format that in UserStyle code, maybe you could discuss with folks from Stylus and uso-archive. I just think it's really important to allow UserStyles writers to define a set of customized options per style.

If the aim is to override or add some custom CSS settings to another userCSS so that the custom settings will remain after userCSS update, that can be done with @require in userCSS.

The aim is to be user friendly, so that you don't need to know CSS to use a style with some customized preferences.

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

How do you customs a 3rd party userStyle that doesn't have @var?

In any case, each manager has its own features and as the tables in the Help show, they are not 100% identical.

Let's see if there is a popular demand.

@pintassilgo
Copy link
Author

How do you customs a 3rd party userStyle that doesn't have @var?

I fork it, keeping the original disabled (to periodically get updated code), pasting the original code on top of my version and adding my customs at the end.

Now that UserCSS is becoming mainstream (as I said, both Stylus and uso-mirror are converting styles from us.o to UserCSS), maybe I'll switch to the @require you suggested (if Stylus supports it, since apparently I will not be able to migrate my styles to FM).

But I don't think this is related to the issue, I'm talking about UserStyle writers being able to set custom options to users, so that they don't need to understand CSS.

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

I use the style I linked as example. And I don't use default settings. How am I supposed to handle it with FM?

Let's imagine... I install the style and it comes in default settings. Then I need to inspect the code searching for these @advanced tags, which ones match the customs I want... so I copy these parts, create a new UserCSS with @require and append the customs at the end.

But... maybe one of the default it's not exatcly the opposite to what I chose, so I need to manually write code to reverse the default instructions.

Then the style update. And I would need to do a whole diff to know if something changed in my customs, or in the defaults that I don't use...

It's a big mess. So I have no choise but to stay with Stylus, where it handles custom settings super easily even for the user who doesn't know anything about CSS.

Of course I'm not saying you need to convince me to use FM, I'm just trying to explain my situation, which is certainly not unique.

Edit: I just noticed the defaults aren't added to the code, so it's less worse than what I said. But still...

In summary, is like forking anything. Is doable, and in many cases it's the only way, cause usually the dev doesn't provide us the customs we want. But I think it makes sense to have a way to allow explicit customs.

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

I'm talking about UserStyle writers being able to set custom options to users, so that they don't need to understand CSS.

It is the same principal as userScript. Should there be custom options for people who don't understand JavaScript to enable them to customise the code?

There are a umber of CSS Preprocessors such as LESS, SCSS, SASS etc. Firefox only supports standard CSS. The method used by Stylus is not standard CSS.

Nonetheless, let's see if there is a popular demand.

A quote from VM developer...

https://github.com/violentmonkey/violentmonkey/issues/869#issuecomment-584746320
Just because TM has something doesn't mean we should copy it.

image
CSS Preprocessors – Sass vs LESS vs Stylus

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

Should there be custom options for people who don't understand JavaScript to enable them to customise the code?

It's up to UserScripts devs. They can implement options popup in page with endless settings that will stay stored by GM.setValue. Some may even provide import/export functions.

But for styles in FM there is simply no practical way for devs to offer custom settings. UserStyles.org/Stylish always supported styles custom settings, Stylus too.

But I totally understand you in this, there is probably no popular demand and this is not so simple to implement, so it’s questionable if it’s worth it.

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

I will keep this open and see if there are other feedbacks on it.

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

If the aim is to override or add some custom CSS settings to another userCSS so that the custom settings will remain after userCSS update, that can be done with @require in userCSS

Does FM perform regular updates to @require'd URLs?

Edit: we can set a userStyle name in @require, so the answer is yes, the @require'd file will check for updates because it is just an ordinary style.

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

You can include another userCSS (not userStyle) in @require.

As a rough guide ......
(I will work on it to see if it needs improving)

Original 3rd party userCSS

  • Disable the userCSS
    Note: Disabled userScript/userCSS will not auto-update, click update to update manually.
/*
==UserCSS==
@name           1CSS
@match          *://example.com/*
@version        1.0
==/UserCSS==
*/

body {
  border-top: 2px solid grey;
}

Custom UserCSS for above

  • Copy metadata block
  • Add @require
  • Add custom CSS
/*
==UserCSS==
@name           1CSS Custom
@match          *://example.com/*
@version        1.0
@require        1CSS
==/UserCSS==
*/

body {
  border-top-color: blue;
}

@erosman
Copy link
Owner

erosman commented Mar 13, 2021

I was thinking about previous post and this is another method which allows auto-update

Original 3rd party userCSS

  • Keep the userCSS enabled
  • By default userCSS will be injected at document-start
/*
==UserCSS==
@name           1CSS
@match          *://example.com/*
@version        1.0
==/UserCSS==
*/

body {
  border-top: 2px solid grey;
}

Custom UserCSS for above

  • Copy metadata block
  • No @require
  • Add custom CSS
  • Set run-at to later that previous one
/*
==UserCSS==
@name           1CSS Custom
@match          *://example.com/*
@version        1.0
@require        1CSS
@run-at         document-end
==/UserCSS==
*/

body {
  border-top-color: blue;
}

Another method
You can also use !important for everything to override the Original 3rd party.

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

Thanks.

The first method, as you said, has the downside of not being able to get the style to auto-update. The second, as the styles will be injected at very different times (depending on the page), may cause an ugly and annoying flickering (think if the forked style changes the background color of the page, for instance).

You can include another userCSS (not userStyle) in @require.

The style I'm requiring is a ==UserStyle== and it's working. It's disabled, only my fork is enabled, but the required style is being applied (and I like that).


I understand the reasoning behind "disabled userScript/userCSS will not auto-update", but I think there should be a way to circumvent that, be it a global setting or per script. As I'm already getting to know you, I guess this will be rejected, so I'll propose a different approach:

When FM checks for update in a userS*, it should check for script.require.length. If there is a required file that is another userS* that is disabled, FM should check for update for it. I think this logic is obvious, because a disabled required userS* in a enabled userS* is, in the end, enabled, so it should auto-update.

Edit: my pull request to fix this, background.js:

        pref.content[item].version && installer.cache.push(item);
+     doUpdate && pref.content[item].enabled && pref.content[item].require.forEach(req => {
+       pref.content[req] && !pref.content[req].enabled && installer.cache.push(req);
+     });

@pintassilgo
Copy link
Author

Also, in app.js:

case /^https:\/\/userstyles\.org\/styles\/\d+\/.+\.css$/.test(item.updateURL):

You should remove $, because as I said in a previous comment there are styles with important query string. getStlylishVersion works the same way, you can see an example here:
https://userstyles.org/styles/userjs/107316/vk-plus.user.js?ik-background=ik-none&ik-page=ik-white&ik-sidebar=ik-fixed&ik-topbar=ik-fixed&ik-images=ik-square&ik-reply=ik-fixed&ik-overlay=ik-no&ik-footer=ik-hidden&ik-text=ik-visible&ik-topfix=ik-right&ik-ads=ik-no
so there's no reason to use that $ in regex.

image

@pintassilgo
Copy link
Author

pintassilgo commented Mar 13, 2021

installer.stylish() should consider the possibility that you aren't in the main page of the style, but in a direct link like
https://userstyles.org/styles/107316/vk-plus.css?ik-background=ik-none&ik-page=ik-white&ik-sidebar=ik-fixed&ik-topbar=ik-fixed&ik-images=ik-square&ik-reply=ik-fixed&ik-overlay=ik-no&ik-footer=ik-hidden&ik-text=ik-visible&ik-topfix=ik-right&ik-ads=ik-no

In this case, context-menu "Install Stylish Style" is silently failing because the code looks for non-existent elements to get metadata like name, version and description. If location.pathname matches /\/\d+\/.+\.css$/ like in that case, it should instead fetch the user.js URL to get style metadata, just as it's done in getStlylishVersion().

@erosman
Copy link
Owner

erosman commented Mar 14, 2021

When FM checks for update in a userS*, it should check for script.require.length.

Let's see what is the best way to handle this situation and update the code accordingly.

You should remove $, because as I said in a previous comment there are styles with important query string.

I see.... I didnt know they can have query strings.... fixed for v2.19 👍

installer.stylish() should consider the possibility that you aren't in the main page of the style,

TBH, I don't use USO and the process was added for convenience of users. I didn't know all the possibilities. I will work on updating the process.

@elena-v2
Copy link

But I totally understand you in this, there is probably no popular demand and this is not so simple to implement, so it’s questionable if it’s worth it.

I, at least, would definitely like @var-based option setting to be supported. Workarounds like forking and editing it by hand to set pre-offered settings is less than ideal, IMO.

@erosman
Copy link
Owner

erosman commented May 21, 2021

I, at least, would definitely like @var-based option setting to be supported.

The standard var() is part of CSS and can be used.

:root {
  --bg: #f9f9fa;
  --border: #ddd;
  --color: #000;
  --hover: #eee;
}

body {
  color: var(--color);
  background: var(--bg);
  padding: 0;
  margin: 0;
}

The @var implementation of Stylus

@var text   myBorder "Border style" 3px dotted blue

@preprocessor default - use standard CSS variables external link:
#exampleID { border: var(--myBorder) !important; } 

Stylus then converts ...

@var text   myBorder "Border style" 3px dotted blue

to ...

:root {
  --myBorder: 3px dotted blue;
}

So, why not use the proper CSS --myBorder: 3px dotted blue; in the first place?

Compatibility

At the moment, the 3 main user-style managers Stylish | Stylus | xStyle are not 100% compatible.

xStyle compatibility
The xStyle extension external link also provides UserCSS metadata which differs slightly from our specification.

@erosman
Copy link
Owner

erosman commented May 7, 2022

I am going to work on implementing @var for both userScript & userCSS.

@erosman erosman added the done ✓ Completed label May 8, 2022
@erosman
Copy link
Owner

erosman commented May 8, 2022

v2.56

  • Added experimental @var support for userScript & userCSS

@erosman erosman closed this as completed May 8, 2022
@pintassilgo
Copy link
Author

I couldn't get it to work.

I'm not much into userstyles world, but I believe there are two major repositories:

  1. userstyles.org (USO)
  2. userstyles.world (USW)

FM can't install styles from USO. Should I open a new issue for that?

Regarding USW, I searched for a random style with custom variables and found this one:
https://userstyles.world/style/292/youtube-retrowave

It's compatible with both Stylus and Stylish and is hosted on the two main repositories. Here are videos showing installation in different scenarios:
https://drive.google.com/file/d/1oq1UqCJVSiPubdwwi9qS55ygWaBzsCmc/view
https://drive.google.com/file/d/16SRUILhzQgnFqTqxWPlskD9UBVNPc73l/view

As I said, FM can't install styles from USO. From USW it installs, but apparently it can't handle user settings. I clicked to edit the style, clicked User Variables button and it's empty:

image

@erosman
Copy link
Owner

erosman commented May 9, 2022

FM can't install styles from USO. Should I open a new issue for that?

Why not? I tested now and it installed fine.
https://userstyles.org/styles/144028/google-clean-dark

userstyles.world (USW)

I didn't know about it. I will check it out.

Regarding USW, I searched for a random style with custom variables and found this one:
https://userstyles.world/style/292/youtube-retrowave

Above uses @preprocessor uso which is not standard CSS.
It also uses @advanced and not @var

Please Read the FireMonkey Help under @var.
See Also: Writing UserCSS

@preprocessor

Stylus supports default (standard CSS), uso, less, & stylus. Besides the default, the rest require additional libraries to convert quasi-CSS into standard CSS.

FireMonkey only supports standard CSS.

Examples

These are examples of @var that can be tested for @var processing in FM. However, if they use any @preprocessor other than the default, the resulting CSS will not workout as expected.

https://greasyfork.org/en/scripts/415378-duolingo-dark-mode
https://greasyfork.org/en/scripts/407679-cloudflare-error-dark-mode-hide-ip
https://greasyfork.org/en/scripts/395346-google-search-old-style
https://greasyfork.org/en/scripts/406046-filmweb-megatweak
https://greasyfork.org/en/scripts/395868-dark-super-mario-maker-bookmark

These ones have @var on multiple lines. FM like GM|TM|VM require all @*** to be on one line.
Those on multiple lines will be ignored.

https://greasyfork.org/en/scripts/395180-greasyfork-dark-theme
https://greasyfork.org/en/scripts/422840-dh3-compact-magic-fix
https://greasyfork.org/en/scripts/402954-youtube-controls-highlighting
https://greasyfork.org/en/scripts/402635-youtube-progress-bar-highlighting
https://greasyfork.org/en/scripts/412326-google-search-tools-to-sidebar
https://userstyles.world/style/144/greasyfork-dark-theme

@pintassilgo
Copy link
Author

pintassilgo commented May 9, 2022

Why not? I tested now and it installed fine.

With Stylus or Stylish: "Install Style":
image
Clicking this button installs the style.

With FM: "Install with Stylish":
image
Clicking this button tries to install Stylish extension, not the style.

FM only works if you install as UserScript. But this is inappropriate, it's a style and should be installed as such.

Edit: right, I got it, it's needed to right-click the page and select "Install Stylish Style". But custom settings ("Customize") don't work.

Stylus supports default (standard CSS), uso, less, & stylus. Besides the default, the rest require additional libraries to convert quasi-CSS into standard CSS.

FireMonkey only supports standard CSS.

OK.

Here we go again about broad compatibility. FM historically was incompatible with many many scripts. If I'm not mistaken, in the past many issues about incompatibilities were treated like "FM is different, it is what it is, you can't expect a clone of other managers". But this is improving a lot lately, it's way better! It will never be 100%, because of technical aspects of userScripts API, but I'm seeing your efforts to make things better, thank you.

Maybe someday this will also come to CSS custom settings. I don't have data to support, but I fear that the implemented "default" won't fix things for anyone who wanted CSS custom settings support because maybe "default preprocessor" is a rarity in UserStyles world. I hope I'm wrong.

@erosman
Copy link
Owner

erosman commented May 9, 2022

Maybe someday this will also come to CSS custom settings. I don't have data to support, but I fear that the implemented "default" wouldn't fix things for anyone who wanted CSS custom settings support because maybe "default preprocessor" is a rarity in UserStyles world. I hope I'm wrong.

The old segmented system has issues

The traditional UserStyle system of using segments has many issues.

UserStyle Anatomy

Name
-------------
segment 1
Applies to sites a, b, c
-------------
segment 2
Applies to sites e, f, g
-------------
segment 3
Applies to sites h, i, j

In reality, there are 3 distinct styles that have been written under one name.
Why not have 3 individual separate styles which would give more control & clarity?

UserStyle Processing

  • Read UserStyle
  • Break each segment into separate code
  • Apply each separated code individually

Once again, the one UserStyle is going to be taken apart and broken into 3 styles anyway.
Why not do that in the first place?

UserStyle Insertion

Once a UserStyle is broken into its segments, then each segment has to be manually inserted, instead of using the efficient native API.

The issue of processors

Writing UserCSS

Within the style, refer to the above variable as follows:

Less is a JavaScript + CSS, which is not native. The code has to be processed by JavaScript and then converted into standard CSS. Why not write standard CSS in the first place?

Admittedly, Less has a few nice features that are missing from CSS3 (some are planned in CSS4), but that means extra JavaScript processing of converting to CSS.

Pure CSS is a lot more efficient than JavaScript + CSS.

uso (by Stylish) & stylus (from Stylus) are made-up set of functions which like Less require JavaScript processing of CSS with the same drawback in performance.

Finally, xStyle (328 users) made its own JavaScript + CSS processor using @advanced & --bg-custom: /*[[bg-custom]]*/;

Like UserScript managers, UserStyle mangers all do similar job but there are a lot of differences.

FireMonkey concentrates more on performance & security. FM tries, as much as possible, to be compatible with the older scripts & styles but it is also worth setting new trends, especially where performance is a factor.

If there are enough users following the new formats, it will become a trend that would benefit users in performance.

Reinventing the Wheel

CSS already has a built-in Using CSS custom properties (variables). Why make up another process to do what is already available natively?

The @var support was added as a useful feature to be used by developers, and not purely for compatibly with older styles.

FireMonkey supports @var for both userscript (uniquely) & userstyles. It can be used as a replacement for script/CSS user-config interface. The result is native code without the need for additional processing & processers.

In most cases, it should be easy to adapt other @var to FM compatible @var.

Footnote

Extensions were once written in XUL in legacy Firefox, then bootstrap and after that changed to SDK (& then JPM). Finally it changed to the current API, some of which are changing again in manifest v3. As an extension developer who has gone through all above changes, in each stage, I had to re-write the extension using the new and improved format.
Many of the formats used in userscripts & userstyles were created for the legacy Firefox. Userscript & userstyle developers could also consider the new developments.

@pintassilgo
Copy link
Author

pintassilgo commented May 9, 2022

I probably agree with everything, but I believe the main thing is: userstyles.org has always been and still is the most popular place to share userstyles and it uses USO preprocessor. Even Stylus uses an USO mirror as the main search engine. In USW, the alternative shared by Stylus, I see that like ~90% of the popular styles use @preprocessor stylus.

I'm not a style writer, can't say the differences between preprocessors, but the fact seems to be that not supporting uso and stylus preprocessors is like not supporting custom CSS properties at all.

Unfortunately FM has so few users to make a difference in promoting other formats. The only practical consequence in your decision, besides less work for you of course, is that some users may end up refusing to adopt FM because of that.

@erosman
Copy link
Owner

erosman commented May 9, 2022

Let's see how much demand there is for it.

@erosman
Copy link
Owner

erosman commented May 10, 2022

After a lot of processing & extra code

v2.57

  • Added null support in @var
  • Added sort misplaced "unit" support in @var (better avoid)
  • Added multiline support in @var (better avoid)
  • Added @var @preprocessor support in UserStyle only (not userCSS) ('uso', 'less', 'stylus')

@erosman erosman reopened this May 10, 2022
@erosman erosman added the more feedback needed Extra attention is needed label May 10, 2022
@pintassilgo
Copy link
Author

Thanks! Have you confirmed it's working for styles with custom options from userstyles.org and userstyles.world?

Examples:

@erosman
Copy link
Owner

erosman commented May 10, 2022

Writing UserCSS

⚠ because we're parsing the meta data as JSON, all fractional values must include an integer value, e.g. [.5] will cause a parse error, so use [0.5]


https://userstyles.org/styles/107316/vk-plus

No @var

https://userstyles.world/style/17/wikipedia-dark

Above uses 'dropdown' ... no plan for support

Also not valid JSON

@advanced dropdown bg-options "Background image type" {
  Tiled "Tiled" <<<EOT
  background-repeat: repeat !important;
  background-size: auto !important;
  background-position: left top !important; EOT;
  Fit "Fit Window" <<<EOT
  background-repeat: no-repeat !important;
  background-size: cover !important;
  background-position: center top !important; EOT;
}

https://userstyles.world/style/4/dark-whatsapp

The CSS uses JavaScript ...

c(x, y = 0, z = 0, xi = 1, yi = 1, zi = 1) {
    if x != 0 && x != '_' {            color: xi is 0 ? x : x i }
    if y != 0 && y != '_' {     border-color: yi is 0 ? y : y i }
    if z != 0 && z != '_' { background-color: zi is 0 ? z : z i }
}

// Raw RGB mixin.
/// Convert RGBA (if t = 1) or HEX to raw rrr-ggg-bbb format.
to_rgb(input, t = 0) {
    if (t) {
        unquote(substr(join(',', slice(split(',', s('%s', input)), 0, -1)), 5))
    } else {
        unquote(slice(s('%s', rgba(input, 0)), 5, -3))
    }
}

....

Also not valid JSON

@var select   theme      'Base color-scheme toggle' {
    'Custom colors   *': 'custom',
    'Dark blue (old)  ': 'old',
    'Dark gray (new)  ': 'new',
}

@pintassilgo
Copy link
Author

Hm... so sadly it looks compatibility remains the same, almost none in real world.

@erosman
Copy link
Owner

erosman commented May 10, 2022

Hm... so sadly it looks compatibility remains the same, almost none in real world.

The feature was added to be used by FireMonkey users and not to copy other managers.

It gives developers more option to write for FireMonkey.

@erosman
Copy link
Owner

erosman commented May 10, 2022

Please check if there are any userstyle that uses pure CSS (without logical Java Script).

If there are not any, then I will remove the @preprocessor code as it would be useless and may cause issues later.

@pintassilgo
Copy link
Author

pintassilgo commented May 10, 2022

Posting again:

217k installs, 7k this week
63k installs, 1k this week

Nobody uses xStyle. People uses Stylish (>3KK in Chromium) and Stylus (>500K in Chromium).

Stylish owns userstyle.org and of course supports custom options offered in the page, like my first example.

Stylus supports all examples, it's very popular and it's the preferred among user that know what they are doing (like style writers).

People write styles for those two extensions, just them.

FM doesn't support virtually any custom CSS settings you can find in real world, and v2.57 doesn't change that.

@erosman
Copy link
Owner

erosman commented May 10, 2022

@preprocessor

  • default: supported by FM
  • uso: (userstyles.org) supported by FM (dropdown not supported)
  • less: requires Less library, supported by FM for @var only
  • stylus: supported by FM if it doesn't use non-CSS content (e.g. condition if)

Many use @preprocessor default but no @var
https://greasyfork.org/en/scripts/code-search?c=@preprocessor

Some compatible examples (I will add more when I find them)

https://gist.github.com/akeeton/c99a0a92ed327ddb64e99dd79fc11cc2
https://gitlab.com/GrantMoyer/collapsing-sidebars-for-discord/-/blob/master/collapsing_sidebars.user.css
https://userstyles.org/styles/163619/testos
https://greasyfork.org/en/scripts/395024-dark-minimalistic-scrollbar/code

// after adding @advanced support
https://greasyfork.org/en/scripts/394908-xda-developers-dark-theme/code

@erosman
Copy link
Owner

erosman commented May 11, 2022

v2.57 update

  • Added null support in @var
  • Added multiline support in @var select
  • Added sort misplaced "unit" support in @var
  • Added @var @preprocessor support in UserStyle (not userCSS)
  • Added @advanced support as @var alias
  • Added dropdown support in @advanced

@erosman
Copy link
Owner

erosman commented May 11, 2022

It is strange that many userstyles that have @preprocessor stylus don't follow Stylus rules.

Writing UserCSS

select

  • Use a JSON format for the values set in the select's options.

Example:
Dark-WhatsApp by vednoc

/* ==UserStyle==
@name         Dark-WhatsApp
@description  Dark and light, very customizable theme for WhatsApp.
@namespace    github.com/vednoc/dark-whatsapp
@homepageURL  https://github.com/vednoc/dark-whatsapp
@supportURL   https://github.com/vednoc/dark-whatsapp/issues
@updateURL    https://userstyles.world/api/style/4.user.css
@author       vednoc <vednoc@pm.me> (https://github.com/vednoc)
@version      3.7.0
@license      MIT
@preprocessor stylus

@var select   theme      'Base color-scheme toggle' {
    'Custom colors   *': 'custom',
    'Dark blue (old)  ': 'old',
    'Dark gray (new)  ': 'new',
}

...

Above @var select is not a valid JSON.

@pintassilgo
Copy link
Author

Userstyles follow examples in the same documentation you linked:

@var select fontBkgd "Background" {
  "near_black:Near Black": "#222",
  "near_white:Near White": "#ddd"
}
@var select fontBkgd "Background" {
  "Near Black": "#111",
  "Near White": "#eee"
}

Except that those examples don't have trailing commas, which are not allowed in JSON but Stylus seems to support.

@erosman
Copy link
Owner

erosman commented May 11, 2022

Except that those examples don't have trailing commas, which are not allowed in JSON but Stylus seems to support.

That is right. training commas are not allowed, as well as single quotes.
However, many userstyles use them and make @var select with an object that is not a valid JSON, like the example above.

The problem is converting that into an object.

  • If it is a valid JSON, then it is easy.
  • If it is not a valid JSON, it runs into all sorts of problem and requires a lot of code to parse, without using eval() which is not allowed in the addons.

I have written the code to parse that but that is not 100% reliable.

More invalid JSON examples:

https://userstyles.world/style/30/dark-instagram

@pintassilgo
Copy link
Author

Have you looked into Stylus source to see how they deal with it?

@erosman
Copy link
Owner

erosman commented May 11, 2022

They made a node.js module

https://github.com/openstyles/usercss-meta

Also......

range

  • The units value - framed in (double)quotes - may be added in at any position since it's non-numeric; but the default, min, max and step values are set in order, e.g. ['px', 5, 0, 10, 1], [5, 0, 'px', 10, 1] or [5, 0, 10, 'px', 1], etc, will all set the default to 5, min to 0, max to 10, step to 1 and the units to px.
  • Only the first units value entry will be used, any additional (non numeric) entries will be ignored, e.g. [5, 0, 10, 1, 'px', 'em'] will only set the units to px. The em entry is removed.
  • ⚠ because we're parsing the meta data as JSON, all fractional values must include an integer value, e.g. [.5] will cause a parse error, so use [0.5]

However, ['px', 5, 0, 10, 1] is not a valid JSON. It should be ["px", 5, 0, 10, 1]. 🤷‍♂️

@erosman
Copy link
Owner

erosman commented May 14, 2022

PS. Stylus doesn't currently get @var values on userstyles.org

@pintassilgo
Copy link
Author

pintassilgo commented Aug 31, 2024

Any news on this? I'm about to drop FM as my user CSS manager because it doesn't support this.

Example:
https://userstyles.world/style/16058/vk-plus

I can't even install this with FM.

With Stylus, I can define my user style settings as expected:

image

@erosman
Copy link
Owner

erosman commented Sep 1, 2024

Any news on this? I'm about to drop FM as my user CSS manager because it doesn't support this.

Support for custom settings was added long time ago.

https://userstyles.world/style/16058/vk-plus

There is an error/bug when when processing empty settings. I will fix that.
(if you remove them it should work for now, lines 10, 91, 97, 110, 118, 138, 158)

yes "Yes (default)*" <<<EOT  EOT;

image

@pintassilgo
Copy link
Author

(if you remove them it should work for now, lines 10, 91, 97, 110, 118, 138, 158)

Please, what exactly should I do to test?

I see from your screenshot some options are missing (Ads, Reply box position in topics and Topic icon position (fixed/closed)).

When you have the fixed meta.js, if you please share it here I can test. Thanks.

@erosman
Copy link
Owner

erosman commented Sep 1, 2024

When you have the fixed meta.js, if you please share it here I can test. Thanks.

Temporarily, you can change this line which will eliminate the error but it would disregard those values.
I will do a proper fix later.

meta.js line 444

const [, id, label, valueString] = item.match(/(\S+)\s+"([^<]+)"\s+<<<EOT\s*([\S\s]+)/);

change to:

const [, id, label, valueString] = item.match(/(\S+)\s+"([^<]+)"\s+<<<EOT\s*([\S\s]*)/);

@pintassilgo
Copy link
Author

Thank you. I was able to install, now it's the same as your screenshot: it's showing 7 options, but there should be 10 (compare with my screenshot in my earlier comment).

@erosman
Copy link
Owner

erosman commented Sep 1, 2024

Try this and let me know...

meta.zip

@pintassilgo
Copy link
Author

pintassilgo commented Sep 1, 2024

Thanks.

  • The second option, "Background (for light tab)" is showing only one value: Default. There should be many options: Default, Black grid, Light blue, Dark, Dark blue, Gray, Green, Metal, Pink, Red lightning and White.

  • For the option "Overlay (back/top) on the left" there should be 3 values, but FM is displaying only two, missing "Visible and small".

  • Option "Sidebar position" is displaying a single option, missing "Fixed (no ads)".

  • Option "Top bar position" is also displaying a single option, missing "Scrollable".

Example of the issue:

FM:
image

Stylus:
image

@pintassilgo
Copy link
Author

Also, just saying, I saw you changed private properties to normal properties, but you created an extra space to the left by doing this, misaligning the indentation.

Example:

  // --- @preprocessor
   static preprocessor(str, pp, userVar = {}) {
    const re = {
      less: (r) => new RegExp('@' + r + '\\b', 'g'),
      stylus: (r) => new RegExp('\\b' + r + '\\b', 'g'),
      uso: (r) => new RegExp('/\\*\\[\\[' + r + '\\]\\]\\*/', 'g'),
    };

    Object.keys(userVar).forEach(i => str = str.replace(re[pp](i), `var(--${i})`));
    return str;
  }

Noticed you should remove one space to the left of static preprocessor? There are many lines like this.

@erosman
Copy link
Owner

erosman commented Sep 1, 2024

Noticed you should remove one space to the left of static preprocessor? There are many lines like this.

Right... it is work in progress. I will fix it. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addon: FireMonkey done ✓ Completed feature request 💡 New feature or request more feedback needed Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants