Page Proxy v0.2.x: the boring "polishing" work and why I think it matters

typescript dev.to

This is the second devlog for my Chrome/Firefox userscript manager extension, Page Proxy! Here I'm gonna cover v0.2.x, where I'm still trying to figure out what direction I'm planning to take the extension in.

Refining and QOL work

This is what I would normally call "polishing" work. It gives the extension much-needed features and fixes long-standing bugs. This stage, I would say, comes after the "minimum viable product" stage, where you just need to get something working as idea validation.

After you get your initial users who are interested in your idea, keeping them becomes very important. This is where usability comes in, and to make a product with good usability, it must have adequate features and minimal bugs.

Extension early stage

At this point, I had a solid main idea of what I wanted the extension to do: turn page interactions into reusable userscripts.
But the extension was lacking a lot of features, so I had to find the order which I wanted to implement them in.

Roadmap

  • Website homepage
  • Create tool:
    • Create a settings UI for your script (or any UI) easily
    • Create components
  • Settings page for the extension
  • Multi-file scripts
  • Local scripts
  • Export to Tampermonkey userscript, CSS stylesheet, WXT extension
  • Import/export with Figma
  • Sync to cloud storage (Appwrite backend)
  • Userscript discovery, sharing, and collaboration

Now I had a good idea for what I wanted the extension to do.

But for v0.2.x, I started with the missing features.

The inconvenience I wanted to solve

While pq.selector could do a lot, sometimes it is simpler to just write CSS instead.

Using JS would be a waste for doing things that CSS can do already. Worst of all would be using a JS pq.selector just to inject styles on every matching element.

So I made a CSS inspector!

CSS Inspector

The CSS Inspector (above) works similarly to the selector popup added in the previous version, but it directly allows you to apply CSS rules to a pregenerated selector for the element.

And there's a nice dropdown that allows you to switch between this and the selector popup.

On the right side of the CSS inspector is a properties list, similar to the one from the other selector. Placing the mouse caret over any part of the main CSS selector will provide documentation for what that CSS keyword does, which essentially acts like built-in documentation.

As the tooltip says, you can also hold z to highlight matching elements in lime or x to preview styles applied in the editor.

I also added a button that can bring you to the CSS inspector page directly from the Select Tool.

There's also some other features. Like, you can view the computed styles for the selected element! It's very similar to the computed styles in DevTools. If there are :nth-of-type selectors in the selector, a link appears to remove them easily. The CSS selector syncs with the baseSelector field in the selector popup as well! Anything to avoid repetitive copying.

Upon hitting Save, it adds a ps.injectCSS snippet into the editor, which will directly inject a style tag into the document head upon script run.

Other QOL features

run-on-page-load grant

Before the update, the script wouldn't even be able to run on page load, and you'd have to click the run button manually every time. Fortunately, I added a @grant field to the metadata. It only accepts one value as of now, run-on-page-load, but it allows the script to execute automatically. A much needed feature.

// @grant run-on-page-load
Enter fullscreen mode Exit fullscreen mode

Upon reload, it will create a dialog asking the user to grant permissions, like this:

Then it will ask the user to reload to apply updated permissions.

Help tool

Previously it was hardcoded into the extension. Now it fetches from the Github repository's HELP.md file, and rendered nicely in markdown.

DevTools integration

Added a wrench button in the select tool panel that appears when DevTools is open on the active tab. When clicking it, the selected element will match the selected element in DevTools. Highly useful for when the select tool can't select the element you want, like for example if its bounding box is covered by the bounding box of another element.

New APIs

  • pa.moveNode to move a node elsewhere, such as to a parent node, or before or after another node.
  • pv.pressKey to press keys programmatically using JS.

Editor persistence

Previously if a script was unsaved, switching to another tab without saving would cause you to lose your changes. Not anymore. Now a warning message appears and forces you to manually save before continuing.

It does not handle the extension sidepanel being closed, though, as there is no way to prevent it. The only solution in that case would be to autosave, which is risky as if there are bugs in the implementation someone's userscript can get overriden with the default script, causing them to lose it entirely.

Selectors tool

I gave it functionality by displaying highlighted elements upon hover.

Error handling

Errors are less likely to be silently swallowed now, and surface more clearly. It still needs a bit of work though.

Moving on to v0.3.x

v0.2.x added some much needed polish and a crucial CSS Inspector. It wasn't much, and ended up only being three versions, v0.2.0 to v0.2.2. That just means there were less features.

Oh and I also changed the storage format, which ended up causing some scripts to be lost. It was okay as I still don't have that many users, but I definitely need to be more careful with that next time.

Final thoughts

I think it's okay to be still figuring things out, and not just for your project either, this probably could work as life advice too. Changing directions in software development or in general is perfectly okay, and it allows one to refine and test their designs, and also throw out ideas that just don't quite work.

Of course, I definitely could have planned my features more thoroughly. The CSS Inspector as the main feature in v0.2.x is probably fine, but the rest of the polish would probably make more sense to be done in v0.1.x. Like having a method to inject CSS (ps.injectCSS) should have been like one of the main features of the custom pp-api. And making a breaking change to the storage format was definitely not a good idea. Could have used some planning beforehand.

Also, I started to use AI for coding a lot for this project. My AI setup is just Codex and some basic skills like superpowers, but it works pretty well. AI-generated code certainly isn't as clean as handwritten code, but it handles edge cases pretty well. Previously I found myself spending a lot more time passing states between components and fixing type objects, than spending time implementing actual functionality. So it's nice that AI allows me to go back to focusing on features, rather than type errors.

But the great thing about agentic engineering is that the product is still the output of my creative work. All the designs, the raw flow chart, and all my ideas are all me, and I've documented them in the Figma file and my devlogs. AI is just speeding up the implementation of those ideas, in a controlled manner.

The landing page is still looking pretty barren... definitely need to do that earlier next time.

I think that's it for this devlog. If you want to stick around, maybe I'll see you for v0.3.x?

Try out Page Proxy, and maybe give me some feedback? I'd also be interested to hear about your thoughts on AI and whatnot.

Source: dev.to

arrow_back Back to Tutorials