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

Dark themes #332

Merged
merged 256 commits into from
Sep 1, 2020
Merged

Dark themes #332

merged 256 commits into from
Sep 1, 2020

Conversation

thomascastleman
Copy link
Member

This pull request adds support for several dark themes for the CPO editor. These are accessible from a new dropdown in the Bonnie menu.

The themes we've included so far are: base16-dark, material-darker, monokai, and panda-syntax. (these have been adapted from this list: https://codemirror.net/demo/theme.html)

Format of themes

The theme stylesheets can be found in /src/web/css/themes. We've designed the themes in a particular format, using CSS variables to make it easy to change/add new themes. There are three parts to a theme:

  1. Color palette: Variables that supply "friendly" names for the color codes used by this theme.
  2. Color assignments: This assigns specific variable names (used in overrides to control usually several elements of the editor) to colors (from the palette).
  3. Overrides: These styles reference the variables from the color assignments to re-style the editor in a consistent way. (at the moment these are identical across all themes)

Creating a new theme

  1. Copy template.css into a new file, giving it the name of your theme.
  2. Replace all instances of "template" with your new theme's name
  3. At the top, add to the color palette the colors you want to use, giving them friendly names
  4. Fill in the color assignments, deciding which colors should be used for what parts of the editor/syntax.
  5. Add a <link> to your sheet in src/web/editor.html, and an <option> to the theme selector (#theme-select).
  6. Done! (you don't need to edit the overrides unless you want to alter the groups of elements that are styled by a particular variable)

Persistence

When a user sets the theme, it is saved in localSettings, so CPO will remember which theme you used last so you don't have to keep switching to it.

Ben Lerner and others added 30 commits March 31, 2018 16:27
…ion<Color>`, and introduced `color-named` to return a color or throw an error for unknown colors -- this function can be used directly inside any image function, whereas name-to-color can't.
…too many layers of wrappers around image-type predicates
…gument marshalling as possible (and relying on richer annotations rather than coercions to get better error reports)
… to untyped API, and (breaking change!) modifying `overlay` to use pinholes instead of image centers. This is a minor breaking change, since many images will be rectangular and have their pinholes equal their centers anyway. But this change is essential to making wedges work usefully, to placing stars and triangles and odd-sided polygons by their visual centers, and generally to making the API a bit more convenient to use (if a bit more magical to explain).
* Part 1 of eliminating the x and y arguments of render() on images: These arguments don't seem to be set consistently, or used consistently.  So rather than changing the calling convention just yet, I'm uniformly setting them to zero...and yet no selenium image tests break.
* Fixing some alphaBaseline bugs, some unbound `checkReal` calls, some typos, etc
* Incorporates and obsoletes brownplt#209: extends it to work with pinholes properly, and fixes the transformation of _vertices to take negative positions into account also
* adds a `move-pinhole` function in addition to `place-pinhole`
…-list, above-align-list, below-list, below-align-list, beside-list, beside-align-list, overlay-list, overlay-align-list, underlay-list, and underlay-align-list.
Added focusCarousel field to editor, and method CPO.cycleFocus() which
moves focus to prev/next element in the carousel. Function
populateFocusCarousel() is used to initialize the carousel to the major
regions on the IDE window when ready.

Added keybindings F6 and Shift-F6 (cycle focus forward & backward),
F7 (Run), F8 (Stop), F9 (Share/Publish), F11 (Insert).
replContainer gets tabIndex=-1.

displayResult() uses updateItems() to keep track of items in history,
including results and errors.
Each prompt/interaction is spoken as it's happening.
Alt-n reports the interaction n prompts back (exception: Alt-0 is the 10th item).
Left & Right arrows on current prompt input reads character following cursor.
Helper procedures: say(), sayAndForget(), speakHistory(), speakChar().

Added aria-label for Publish button.

Added aria-labels to logo and Run dropdown.

speakChar() should say "space" for space character, instead of being mute.

updateItems(): check for replTextOutput (in addition to replOutput).

Generate aria-labels for images, numbers (rationals and non-), nothing,
booleans, strings, and collection objects (e.g., lists).

updateItems(): for errors, mention the offending snippet (input expression).

Added comment for repl interaction history: items[] and updateItems()

Interaction history is also set when clicking Run (= when loading
Definitions window). (This should also erase previous history.)
Voicing of current interaction moved to afterRun().

Recite parsing errors also (whether in int and def window).

Recite roughnum as '<num>, roughly'.

Errors from definitions window should have aria-hidden=true to avoid
error being recited twice.

Set aria-hidden=true for textarea, .output, #repl; to reduce noise.

Better aria-labels for rational numbers: read solidus as 'over'.
If output as decimal number, identify repeating digits if any.
Rational-number toggle click event was not bound: fix.

Repeating digits audio-enclosed in "with ... repeating".
If immediately following decimal point, "with" dropped.

Recite strings without the enclosing quotes.

For non-errors, interaction history data consists only of relevant
indices into the REPL DOM. This allows for history recitation to use
the current form of past output. (E.g., rational-number output formats
could have been toggled by user.)

Check blocks with failing tests should have proper audio.

Added subroutine outputText() to abstract recital of one program unit.
Recite check-block's test results more relaxedly.

Recitation for failing check-blocks improved.

Added aria-text for table values.

Added CSS for nav [ul [li]] and .lhs

Added aria for opening page.

Canonicalize HTML5 for editor page (makes for easier a11y).

Add ids #bonniemenuli and #filemenuli for menubar list items containing
the bonnie and the File menu, so submenu focusing can be triggered

When menubar submenu is made visible, do not add it to end of <body>,
as it ruins the tab order.
When a submenu is clicked, so that it either becomes visible or not,
change the tabIndex of the enclosed elements accordingly

Addes submenuFocus() which keeps track of when user focus (not the same
as JS focus) enters/leaves a submenu, and sets off concomitant tabIndex changes.

Add CSS for rewritten, ARIA-enhanced, nested <ul>-based toolbar.

Tool menubar rewritten to support ARIA navigation.

Added JS/jQuery for navigating toolbar with arrows and escape.

up/dn arrows in a submenu should wrap around on hitting the ends.

Have tabindex=0 rove within the menu system as focus moves.

- menu system should not respond to hover.
- when traversing menubar horizontally, update element's aria-expanded,
aria-hidden, .showmenu

.focus and .blur handlers on focusable elements kept separate from
arrow-traversal handlers. This allows any focus in/out (e.g., to outside
regions) to be treated correctly.

Add class .toptier to top-level menubar <li>s for easy JS/jQ manipulation.

Top-tier navbar items react to mouse click just as if they received
focus via arrowing (i.e., other submenus should be closed).
On cycling focus to navbar region (F6), any key focuses first (or
previously focused) item. Tab/esc cycle focus out.
Any and only keys not handled by a focusable item are bubbled to
navbar.
Helper function switchTopMenuItem() moves focus within navbar, taking care to
hide previous submenu and show new submenu when necessary.
Moving to Run Dropdown tab does not automatically open Run
Options submenu: click needed. (This submenu is too beta for easy
access.)
Left and right arrows on menubar wrap around the edges.
Space on a submenu item is equivalent to clicking it (or pressing Enter).

Ensure margin, padding =0 on navbar constituents.
Change background-color when focusing .focusable element.

Ensure right-flush elements on the menubar respond to arrows
in the order visible to the user.

updateItems: lastOutput could be nil for empty defn window.
speakHistory: could be a load of empty defn window, in which case history
item may not have anything to extract: say something appropriate.

Remove additional borderline alert when hovering on a menubar item

Add id for each top-tier <li> in toolbar.

Top-tier <li>s in toolbar with submenus toggle submenu visibility on click.

No need for #runDropdown click event. It's part of the general focusable element
click protocol.
When choosing something from the run dropdown, augment the hiding of the
dropdown with corresponding aria-{expanded,hidden} updates.

- "Connect to Google Drive" should retain focus after failure and
give focus to Toolbar after success.
- On entering Toolbar, Tab and Esc cycle-focus out. Any arrow key go
to first available focusable item (which could have been what was
in focus when leaving Toolbar last).
- Be diligent about closing submenus when focus veers away for any
reason, in particular clicks outside the Toolbar.
submenu it spawns becomes wide and goes under the Run button. Everything
is white/blue to match the Run button.
audio recall (via Alt-n), should not be in REPL history for repetition
(via up/dn arrow).
they can work well with aria-posinset and aria-setsize. Similarly, use
role=tree (rather than menubar) for top nav <ul>.
For checkbox #detailed-logging, use aria-pressed (initially false).
and submenus whilst navigating them.
There is one case where a submenu <li> has two focusable items.
menu items for Bonnie and Run dropdown (upon click or equivalent).
can't get aria-describedby method to work for popup-style help.
Make Run dropdown sleek again; and other issues following a11y update
@blerner
Copy link
Member

blerner commented Jul 18, 2020

Follow up from #335: When looking at the <body> class attribute, though: on the very first load of CPO into the browser, I see <body class style>, and in particular there is no theme class chosen, not even "default". You can repro this by loading CPO into an incognito window in both Chrome or Firefox. I think you're just missing a check for "if the theme is undefined, make it default"

@thomascastleman
Copy link
Member Author

Here are some updated screenshots from the latest updates to code snippets under highlights. Readability has been improved:

dark-syntax-1

Code in unfocused errors stays light, but highlighted text darkens to contrast with the added background.
dark-syntax-2

When code is highlighted, a darker version of the syntax highlighting from the theme is applied:
dark-syntax-3

dark-syntax-4

As an aside, @blerner the build has been breaking (since d6d5486) and I'm not sure why--it seems to error on npm install -g heroku-cli, but I'm not sure how that would have been affected by what I've edited.

@blerner
Copy link
Member

blerner commented Jul 27, 2020

Seems to be a travis caching issue; I've cleared the cache (I think) and am restarting the build. I don't think it's anything to do with your code.

@blerner
Copy link
Member

blerner commented Jul 27, 2020

@jpolitz have you seen this sort of error before? I searched and found nodejs/help#2874, but I tried clearing the cache and it didn't work...

@jpolitz
Copy link
Member

jpolitz commented Jul 28, 2020

I'm not sure, but this step of the build succeeds on horizon. I notice that the style-updates branch is significantly behind horizon; is that intentional? It has a number of conflicts with it, so I'm concerned about how that will shake out long-term.

@blerner
Copy link
Member

blerner commented Jul 28, 2020

It's not intentional. Realistically, the changes here are fairly self-contained (though they do touch a lot of editor.css, naturally), and could probably be rebased onto a more horizon without too much difficulty.

@blerner
Copy link
Member

blerner commented Jul 28, 2020

@thomascastleman can you try that? If not, I can't today, but hopefully will have time later in the week.

@jpolitz
Copy link
Member

jpolitz commented Jul 28, 2020

It looks like this is an issue that's new in the master build that is fixed on horizon. I'll check horizon's travis/package.json history to see if there's an obvious fix.

@thomascastleman
Copy link
Member Author

@blerner I tried rebasing style-updates onto horizon but there were a few conflicts in places I didn't edit and wasn't sure how to resolve--maybe you could have a look at it?

…-theme

NOTE: This is not a pure merge; I also had to fix some bitrotted tests and some infelicities in the UI that are made more obvious by the theme work:
- a few of the tests in test/errors.js were simply wrong; I don't know why they were ever working.  With these fixes, `npm run mocha` succeeds again
- box-plot-test.arr and image-scatter-test.arr seem to have diverged; this is keeping the horizon version
- some of the manipulations from 2d7f604 to handle hiding headers/footers were now really obviously too late, and so I've moved that code into an immediate script just inside the <body> of editor.html, so it runs before anything gets rendered to screen
- similarly, some of the jQuery-based CSS manipulations are now done as CSS style rules in editor.css and shared.css

# Conflicts:
#	src/web/css/editor.css
#	src/web/css/shared.css
#	src/web/editor.html
#	src/web/js/beforePyret.js
#	src/web/js/trove/image-lib.js
#	test-util/pyret-programs/charts/box-plot-test.arr
#	test-util/pyret-programs/charts/image-scatter-test.arr
@blerner
Copy link
Member

blerner commented Jul 30, 2020

I wasn't able to get a clean rebase, so I did a merge instead. Not ideal, but it'll do.

@blerner
Copy link
Member

blerner commented Jul 30, 2020

An additional readability issue in error highlighting, for all the dark themes:
image
image
image

The green strings are roughly impossible to read against the highlights. One possibility is to add a (non-standard, but pretty well supported) CSS property:

body:not(.default) .CodeMirror .bg-highlighted.cm-string {
  -webkit-text-stroke: 0.15px black;
}

which produces
image
instead of
image

Or, we could use text-shadow, which is standardized and supported, to simulate it:

body:not(.default) .CodeMirror .bg-highlighted.cm-string {
  text-shadow: -0.25px 0.25px 0px gray, 0.25px 0.25px 0px black, 0.25px -0.25px 0px gray, -0.25px -0.25px 0px black
}

which produces
image

@sorawee
Copy link
Contributor

sorawee commented Jul 30, 2020

I somehow find the current green string easier to read than the text-stroke/text-shadow-ed variant.

@blerner
Copy link
Member

blerner commented Jul 30, 2020

Remember that the highlights you get are randomly colored, so be sure to try it a bunch of times to decide. Also, the screenshots above are 2x normal resolution (because hidpi is still weird for computers to get right), and at larger resolutions I agree with you. But when the characters are only ~12px tall, the green-on-bluegreen combos are really hard to read.

@thomascastleman
Copy link
Member Author

@blerner Another possibility would be to significantly darken the string itself while it's under highlights, seen below:

dark1
dark2

This is 12% lightness, so I could even darken it more if you think it's still not readable enough. I'd vouch for this fix though because the outline/text-shadow appears to give the strings a "fuzzy" look at 14px size on my machine.

What do you think?

@sorawee
Copy link
Contributor

sorawee commented Jul 31, 2020

I think this is much better than outline/text-shadow, due to the absence of "fuzzy" look as you described.

@blerner
Copy link
Member

blerner commented Jul 31, 2020

Darkening strings further is fine by me.

… each theme.

Fixed green text in matching brackets in import statements.
Also, fixed padding in theme dropdown.
@jpolitz
Copy link
Member

jpolitz commented Sep 1, 2020

The horizon rebase/merge looks clean to me now. I named the default style "Ensign", which is cute because it's a name for a junior officer and also the name of the flag flown on a seafaring vessel (https://en.wikipedia.org/wiki/Ensign).

@jpolitz
Copy link
Member

jpolitz commented Sep 1, 2020

Going to deploy this on horizon now, monitor and try it out a bit there, then we can release later this week.

@jpolitz
Copy link
Member

jpolitz commented Sep 1, 2020

Great work @thomascastleman & co

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants