rpwoodbu / mosh-chrome

Mosh for Chrome
GNU General Public License v3.0
371 stars 59 forks source link

Support web fonts (via user-html similar to user-css)? #121

Open colemickens opened 8 years ago

colemickens commented 8 years ago

I've reverted back to stable and turned off developer mode. As a result, I don't think I have any avenues for using a custom font with mosh (other than re-activating dev mode).

With web fonts I could insert this html:

<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700' rel='stylesheet' type='text/css'>

and then use the font normally.

Would you support "user-html" the same as you support "user-css" today?

rpwoodbu commented 8 years ago

The terminal emulator is hterm, and that user-css setting comes from there. Does hterm support user-html? If so, I'll accept a pull request to add that to the configuration.

colemickens commented 8 years ago

No. Interestingly, it seems that user-css is supposed to be a link to a CSS file, rather than inline CSS. https://github.com/chromium/hterm/blob/23300c0308d9e4ea9bd784807a4e40b1fb1ac69e/js/hterm_scrollport.js#L437

Not the impression I had gotten from the way it's shown in the Preferences dialog.

I might try to add it (user-html) to hterm and then revisit it here. I'll close this for now. Thanks @rpwoodbu

rpwoodbu commented 8 years ago

Yeah, getting it in hterm is definitely the way to go. I'll be more than happy to upgrade to a new hterm once it is upstream. Thanks for driving this; I suspect this'll help some others, too.

colemickens commented 8 years ago

I experimented with this and ran into issues. Just using the inspector I tried injecting the relevant html but it violates cross origin policies. Probably abandoning this for now. Cousine isn't so bad.

rpwoodbu commented 8 years ago

I just did a little digging. It would seem that this actually should be done with the user-css field, and shouldn't require user-html. E.g., you could get one of the monospace Google Fonts by putting this into user-css:

https://fonts.googleapis.com/css?family=VT323

... and putting this into font-family:

'VT323', monospace

This works in the Secure Shell app (for which hterm was written). But as you noted, it causes this error in Mosh for Chrome:

hterm.js:3658 Refused to load the stylesheet 'https://fonts.googleapis.com/css?family=VT323' because it violates the following Content Security Policy directive: "style-src 'self' blob: filesystem: data: chrome-extension-resource: 'unsafe-inline'".

Here's a breadcrumb to the Content Security Policy (CSP) page for Chrome extensions. It further links to an overview of CSP, which may be helpful. A cursory glance suggests that we may be able to add something like this to the manifest.json.template file:

 "content_security_policy": "style-src 'unsafe-eval'"

However, more research is required:

tdilo commented 7 years ago

I dug a little more and it is actually possible to (base64-)encode a web font into a data URI. The data URI containing the font can then be embedded into a CSS file. The CSS file in turn can again be encoded as a data URI and set as user-css preference. In my experiment I used the Go Mono font, which results in a user-css data URI string of around 68 kB.

Setting the user-css preference does not work from the GUI, but when set from the JavaScript console, it almost produces the desired result (and an error). The font is used (yay!) but not persisted across app restarts.

The error message shows that the encoded CSS file exceeds the Chrome sync storage quota (QUOTA_BYTES_PER_ITEM) of 8192 bytes, which is probably also why setting the preference through the GUI does not work properly.

While ugly, this approach would at least not rely on an internet connection for setting the font. It might be safe to embed known CSS with the Content Security Policy in place.

rpwoodbu commented 7 years ago

Interesting. My feeling is still that this needs to be solved at the hterm level. Anything done at the Mosh for Chrome level is going to be a hack on or around hterm. For example, using local storage for user-css would require patching hterm. As another example, adding a dropdown for user-css on the preferences page, which actually comes from hterm directly (in the latest code), would be a significant hack. I recommend bringing up your findings with the hterm folks; after all, this applies just as much to Secure Shell users (which includes me, as I can't use Mosh for All The Things).

BTW, there are some problems with the preferences GUI in the stable version. The preferences page has been completely redone, so be sure to try the dev version when editing stuff there and encountering problems. I hope to get a new stable release out next week.

colemickens commented 7 years ago

Where is the official hterm project page? How does one most easily get in contact with "the hterm folks"?

tdilo commented 7 years ago

I agree that adding a facility to supply fonts would best be added to hterm itself, but then I'd rather do it properly instead of hijacking the user-css field - and avoid base64(base64(blob)).

According to https://chromium.googlesource.com/apps/libapps/+show/master/hterm/doc/embed.md#60 setting of storage location is already supported. I'm not sure however what the consequences of changing the storage location are. If it is feasible (looks like a simple change), it could allow further experimentation with fonts before going upstream.

In any case thanks for your work on this awesome app!

rpwoodbu commented 7 years ago

@colemickens See the link in @tdilo's most recent comment, which points to their code repo. There isn't an official project page per se AFAIK. But there is a mailing list.

@tdilo I don't want to change the storage location for all of hterm's settings. I might consider making an option for the user to switch it per-machine (or more precisely, per Chrome profile). But it is confusing to say the least if certain features are not available when using sync storage.

I totally understand wanting to use Mosh for Chrome as your basis for experimenting with fonts in hterm. I recommend building the app yourself so you can hack on it. It's actually quite easy to build; it is even documented! And I am happy to provide guidance on how to work with the build system to allow you to hack on the hterm code.

Just be aware of two things:

  1. The hterm folks care primarily about how hterm works with nassh (aka Secure Shell), so you'll eventually need to have things working well in that context to get it upstream.
  2. I'm very apprehensive about maintaining patches against upstream projects, so I'll push really hard to get this upstream before it ever lands in a released version of Mosh for Chrome.
tdilo commented 7 years ago

@rpwoodbu thanks for the detailed explanation. If switching over to local storage completely is not an option, then upstream is indeed the way to go. I'll have a look at hterm some day, but for now it's rather low priority on the list of things I want to get done.

rpwoodbu commented 7 years ago

According to Issue #145, it would appear that hterm has added support for web fonts. So this might be as simple as opening up the CSP, but that needs to be considered carefully (see previous comment on CSP).

vapier commented 6 years ago

fwiw: https://chromium.googlesource.com/apps/libapps/+/master/nassh/doc/FAQ.md#How-do-I-use-web-fonts

jgallen23 commented 6 years ago

@rpwoodbu shouldn't be any security risks with adding that line to the manifest. It's just for styles. If it was scripts, then I could understand there would be risks. I'm not sure unsafe-eval is needed, I think we just need to allow remote instead of self. If you wanted to be a little more secure, you could only allow google fonts. Something like this

style-src 'self' fonts.google.com
vapier commented 6 years ago

that's not entirely accurate: https://stackoverflow.com/questions/3607894/

I'm not sure how much you need to protect users from themselves though

jgallen23 commented 6 years ago

Yeah, agree with that. You could put a little disclaimer on that field

plurry commented 6 years ago

+1 for loading web fonts with user-css like in Secure Shell and Crosh.

FWIW, it looks like the CSP of the current version of Secure Shell is style-src: 'self' and web fonts still work fine.

JamesBelchamber commented 6 years ago

Is there no reason we can't just bundle in the fonts people want? There aren't actually going to be that many of them, Termux have this approach and they bundle 20 fonts, with one request outstanding in the issue tracker.

Just offering up an alternative, I know there will be a concern around maintenance but it's probably not that much of an issue, fonts don't often change and applications using extended fonts have de-facto standardised around the powerline extensions.

gordol commented 6 years ago

just adding your site, or fonts.google.com, or whatever, as a CSP header doesn't work...

when you attempt to install the extension, this happens:

'content_security_policy' is only allowed for extensions and legacy packaged apps, but this is a packaged app.

rpwoodbu commented 6 years ago

@gordol I doubt there's anything we can do to work around that error. Secure Shell is an extension, not an app, thus it is not restricted in this way. Mosh for Chrome must be a Packaged App in order to use UDP sockets (unless that's changed).

@JamesBelchamber While bundling the fonts seems like a decent idea, I am worried it might become a maintenance issue, with everyone wanting their favorite font included, and having to deal with font updates.

I wonder if perhaps we could provide a way for folks to download the fonts they want and provide them to the app. This way they're not "web fonts", and thus don't violate Content Security Policy.