Inwerpsel / use-theme-editor

A React theme editor
GNU General Public License v3.0
4 stars 0 forks source link

Fully create and describe at least one way to use this repository #36

Open Inwerpsel opened 1 year ago

Inwerpsel commented 1 year ago

For now the question of how to exactly use this theme editor in a given existing application has been left pretty much completely open.

Only the bare essentials of creating changes and saving them under a name were implemented, along with a few extras that were easy to implement (such as JSON/CSS export/import). Even a component that visualizes the current set of changes was removed because it had too many unknowns about how to treat and display custom properties entered under different selectors.

While this helped a lot keeping the complexity of other changes low, these parts of the experience feel more and more notably missing.

It would be nice to have at least one end-to-end application described and implemented on a demo site.

There's a few options with different focus/implications.

Options (not mutually exclusive)

The current "eat the page" model

Currently the script will replace the page content with the editor + an iframe with the page URL.

It was an easy solution and so far there was no immediate reason to change it, though it's far from optimal and depends on quite a lot of script running identically both in the main window and the frame. What makes it easy is that both end up with the same complex data, rather than having to send a whole lot of messages to send each entity, or very large ones. Sending large messages could actually be slower as well. Then again, potentially the frame doesn't need to be involved with most of the data it's currently managing.

Run on a dedicated page of an existing app (WordPress)

One big unknown: what to do with the changes depends on the app. It would be most sensible to do this in the form of a WordPress plugin: many sites would be covered with this.

In fact it already works as a WordPress plugin, however actually using the editor result would require extra server side code.

WordPress also has its own way of handling site-wide styles, which makes heavy use of inline style tags and largely overlaps in functionality. Though it does give IDs on these style tags, which possibly can be used to target the right entity with the editor updates. Still it has to be mapped to a custom format in a JSON file (if it even still works like that).

The markup created by WP's post editor also has inline styles which can complicate things.

On top of that, this system has been changing a lot and still has many open issues that will probably result in more re-architecting. So it's hard to tell how much work it will be to make it play well.

On the plus side, it does seem to result in a correct UI for each WordPress site I tested with (both saved as static HTML and locally running WP instances).

Searching other pages

This would also allow for functionality across multiple pages. For instance, a selector that is not found on the current page could be looked for in the database by finding a pattern for matching HTML.

While it can work on a regular DB, it probably needs something like ElasticSearch to be efficient on large bodies of lengthy content.

Another option is indexing the occurrence of selectors, the amount of them seems manageable for this.

As a public page that can edit any HTML page style somehow

Currently you can pick a page from any site, save it, and then serve it locally. It's still a manual process, making use of the browser's "Save page as..." dialog.

A lot of this behavior is actually pretty good. It snapshots the page and neatly puts it in a folder with other downloaded resources. All Most URLs point to the right thing and you're protected from the most important resources disappearing/changing. There's a few exceptions, like icons, where it doesn't download and you run into CORS issues when it uses the original domain.

All that needs to happen after that is include the script and style tags of the editor. To maximally keep things simple, I'm just copy-pasting these in every time I add a new test page, ensuring the directory levels are the same on each page.

I also check what each script tag is doing, and remove it if it's analytics or other garbage that would likely be throwing errors because it can't call home from localhost.

Would be nice to automate this to a 1-click process. However doing it locally would not save that much time, it would only really make sense to build this in a way that it can be consumed on a public page.

I guess this has only 1 challenge: CORS. Once we have access to the content of all resources, the page can be constructed from local "proxies", and not much changes compared to how it works now. Unfortunately CORS is quite omnipresent and it's unlikely you'll be able to request all you need for any site unless you're on its domain.

Probably the only cheap and "easy" way around this is a browser extension. Perhaps some form of proxying can also get rid of the CORS headers, but I don't know if there's a free general solution.

Light version: paste markup

In a hybrid between this and the next option, you could have the ability to paste in your site markup (assuming it uses similar CSS). In fact, you can totally do this already using dev tools.

As a public page where you can create a theme, then save it as a file

This use case is the closest, it needs only small improvements to the "export CSS" functionality. For Bootstrap and Halfmoon it already has a wide range of markup.

Inwerpsel commented 9 months ago

Assumptions around different themes

The original idea

Some of the initial assumptions on how the code of the inspected page treats a theme are still in place. Mainly, it is assumed that there is a single "main" theme, which is either a dark or a light mode, written like normal CSS, where the variables are all left at their default value.

The other themes (e.g. dark theme if light theme is the main theme), would then be implemented as the CSS of the base theme + a set of variable values that are "inserted" into slots (var(--main-background-color, #fff)). These variables can be applied either by serving an additional sheet on top of the main theme CSS, or by running a build script where all these values are substituted to produce a sheet without variables.

The end result is that any theme will use the same CSS selectors and properties, and only plugs different values into the slots. This makes styling a lot more predictable compared to the traditional "throw more full CSS rules at it" style of creating themes.

General applicability

While the approach has worked well and is probably still a good choice, after testing the editor on many different sites I found that a lot of times another approach is chosen, or at least the "slots" technique is mixed with one or more other techniques.

However there's also examples of such an approach being followed consistently, such as Halfmoon. Sites built like this will have the best editor experience, often to the point it's a complete theming solution already.

Dealing with existing dark modes

Besides those matching assumptions, though, most also ship with a dark theme implementation. To keep things simple, the code is now configured to ignore all CSS rules targeting the dark color scheme. In the demos, I tried to remove dark theme toggle handlers whenever I could so that it doesn't lead to an inconsistent result.

The handling of different variations present in the CSS of the inspected page can definitely be improved, but this is left out for now as it's not essential for developing the other things, and there's also many different ways CSS can achieve this, often many of those ways are intermingled. So properly splitting out dark and light mode rules is quite challenging and error prone.