Previously, when a cache was invalidated and every tab/iframe issued a getStyles request, we previous needlessly accessed IndexedDB for each of these requests. It happened because 1) the global cachedStyles was created only at the end of the async DB-reading, 2) and each style record is retrieved asynchronously so the single threaded JS engine interleaved all these operations. It could easily span a few seconds when many tabs are open and you have like 100 styles.
Now, in getStyles: all requests issued while cachedStyles is being populated are queued and invoked at the end.
Now, in filterStyles: all requests are cached using the request's options combined in a string as a key. It also helps on each navigation because we monitor page loading process at different stages: before, when committed, history traversal, requesting applicable styles by a content script. Icon badge update also may issue a copy of the just issued request by one of the navigation listeners.
Now, the caches are invalidated smartly: style add/update/delete/toggle only purges filtering cache, and modifies style cache in-place without re-reading the entire IndexedDB.
Now, code:false mode for manage page that only needs style meta. It reduces the transferred message size 10-100 times thus reducing the overhead caused by to internal JSON-fication in the extensions API.
Also fast&direct getStylesSafe for own pages; code cosmetics
Switched info to `i` and found a pretty nice external link icon imo. @tophf As for pixelation on the info icons, you mentioned maybe a lighter color would help. For all icons besides external links, I made them lighter with darker hovers. Besides a really high zoom, I never saw any issue to begin with, but let me know if they're alright. I also changed them to use their exact original dimensions, so maybe that helps.
Max height is 600px for the popup, regardless of resolution (so says Google), so we can set the styles section to a max height in px and let the overflow scroll inside the div, instead of scrolling the whole popup. This way the other actions are always present at the bottom of the popup without needing to scroll to use them. I left a little breathing room for the rare instance when domain name in "write style for" is long enough to cause a line break, so there should never really be any overflow for the popup itself.
https://github.com/schomery/stylish-chrome/pull/50#issuecomment-287665085
The injection code also runs outside of onInstalled event so we check first if a content script belonging to our execution context "generation" is already injected. This can happen on browser startup: the background page is loaded in several seconds after the normal web page tabs are loaded with our content script(s) already injected. The check itself is simply a "ping" message to each tab that should return true if the content script is alive and kicking.