Add a new color palette and rework all site colors (both light mode and dark mode) to
use the new palette.
This ensures that colors are used consistently, from a carefully designed color palette,
instead of being chosen at random.
Before, colors in light mode were chosen on an ad-hoc basis, which resulted in a lot of
random colors and inconsistent design.
The new palette has 7 hues: red, orange, yellow, green, blue, azure (a lighter blue), and
purple. There's also a greyscale. Each hue has 10 shades of brightness, which (including
grey) gives us 80 total colors.
Colors are named like this:
var(--red-0); /* very light red */
var(--red-2); /* light red */
var(--red-5); /* medium red */
var(--red-7); /* dark red */
var(--red-9); /* very dark red */
var(--green-7); /* dark green */
var(--blue-5); /* medium blue */
var(--purple-3); /* light purple */
/* etc */
The color palette is designed to meet the following criteria:
* To have close equivalents to the main colors used in the old color scheme,
especially tag colors, so that changes to major colors are minimized.
* To produce a set of colors that can be used as as main text colors, as background
colors, and as accent colors, both in light mode and dark mode.
* To ensure that colors at the same brightness level have the same perceived brightness.
Green-4, blue-4, red-4, purple-4, etc should all have the same brightness and contrast
ratios. This way colors look balanced. This is actually a difficult problem, because human
color perception is non-linear, so you can't just scale brightness values linearly.
There's a color palette test page at https://danbooru.donmai/static/colors
Notable changes to colors in light mode:
* Username colors are the same as tag colors.
* Copyright tags are a deeper purple.
* Builders are a deeper purple (fixes#4626).
* Moderators are green.
* Gold users are orange.
* Parent borders are a darker green.
* Child borders are a darker orange.
* Unsaved notes have a thicker red border.
* Selected notes have a thicker blue (not green) border.
Bug: if you moused over another note while dragging a note, it would
trigger a note body popup. This would also happen when drawing out a new
note.
Also fix the drag box for new notes being drawn behind other notes.
* Raise notes when hovering over them. This is so that when dragging
embedded notes, they're not hidden behind other notes. Also so that if
two notes are overlapping, you can hover over one to raise it over the
other.
* Replace .hovering class with :hover selector.
Rewrite the notes Javascript from a procedural style to an
object-oriented style.
Before the notes Javascript had a lot of problems:
* There was hidden state everywhere, both locally and globally. We had
state in global variables, in <meta> tags, in DOM data-* attributes
(on multiple elements), and in jQuery .data() properties (which are
different from data-* attributes, because they aren't visible in the
DOM).
* Local state was hard to reason about. There was lots of direct DOM
manipulation in random places. Functions had to constantly pass around
note ids and look up elements in the DOM to get the state. State was
invisible because it was stored as jQuery .data() properties. It was
hard to follow where state was stored, how it was initialized, and how
it changed.
* Global state was also a mess. There were a lot of global flags and
variables only used in specific situations. Almost all of this state was
unnecessary. Global state also prevented us from doing things like
loading or unloading posts dynamically, or showing multiple posts with
notes on the same page.
* There was a lot of duplication of code, especially for placing notes,
and for loading or saving new notes versus saved notes.
Now the code is organized in an object-oriented fashion:
* The Note class represents a single note. A post has a list of notes,
and each note object has a Note.Box and a Note.Body. Together these
objects encapsulate the note's state.
* Notes have methods for doing things like placing note boxes, or showing
and hiding note bodies, or creating, saving, or deleting notes. This
makes the JS API cleaner.
* Global state is kept to a minimum.
This is one big patch because it was too hard to make these changes
incrementally. There are a couple minor bugfixes, but the actual
behavior of notes should remain unchanged.
Bugfixes:
* It was possible to enter translation mode, start dragging a new note,
then press N to leave translation mode while still dragging the note.
If you did this, then you would be stuck in translation mode and you
couldn't stop dragging the note.
* Placement of new notes is now pixel-perfect. Before when placing a
note, the note would shift by 1-2 pixels.
* Previewing an empty note didn't show the "Click to edit" message.
Other noteworthy changes:
* Most global state has been eliminated. There were a lot of flags and
variables stored as global variables on `Danbooru.Note`. Most of these
turned out to be either unnecessary or even unused.
* Notes now have an explicit minimum size of 10x10 pixels. Before this
limit was hardcoded and undocumented.
* A lot of the note placement and note creation code has been simplified.
* `Note.add()` and `Note.create()` have been refactored into `new Note()`.
Before `Note.add` was used to load an existing note, while `Note.create`
was used to create a new note. These did the same thing, but had
slightly different behavior.
* `Note.Box.scale()` and `Note.box.update_data_attributes` have been
refactored into `Note.Box.place_note()`. Contrary to their names,
these functions were actually both used to place notes.
Setting max-width causes notes to overflow the note body if they set a
fixed `width` or they use `white-space: nowrap` and the line is wider
than the max-width. Using `width: min-content` instead makes the note
shrink to fit but doesn't prevent it from expanding if it needs to.
* Add back "Resize to window" link.
* Add Z shortcut for resize to window link (mnemonic: Z for zoom image).
* Resize images to screen width by default on both desktop and mobile.
* Make it so that notes are nested directly inside the .image-container
element with the image, instead of inside a separate .note-container
element. This means .image-container and .note-container are now the
same element. This is so that the size of the .note-container is
driven by the size of the image, which ensures that notes are
automatically resized as the image is resized.
Change #image-container and #note-container from IDs to classes. This is
necessary so that we can use one container element for both the image
container and the note container. This may break custom CSS and
userscripts.
This is because it was messing with using line-height on the outer
element. In order to get around this, the line height had to be set
individually on every single <br> element used.
- This allows for the note boxes to be easily resized
-- Now resizing the note container resizes all of the note boxes
-- The z-index and position values had to be adjusted for this
--- So that the note/preview boxes were still visible
--- So that the image was selectable with right clicks
- All of the inner box styles have been moved to the outer box
-- Now the inner box is only a container for the note body
- The always resize image option has been removed from user settings
-- The value still exists on the model for future rename/reuse
- The max width is set at 100% for responsive mode to fit the screen
- Attributes are pulled from the first element with class "note-box-attributes"
- Transform is note box only to prevent applying the same transform twice
-- Only rotations are allowed to prevent excessive scaling of note boxes
-- Note box positions are adjusted after drag/nudge/resize to prevent out-of-bounds
-- The note body is placed on the lowest box corner that is farthest left
- Background color is inner box only since the note box is already transparent
-- Backgrounds with any transparency aren't allowed as they would interfere with the text below
- Border radius is both since they both have borders
- Add full namespaces to all event removes to prevent bad removes
- Notes must be clicked in order to engage the nudge function for that note
-- This status is indicated by a green border around the note
-- Clicking the note or another note will turn off nudging for that note
- Also prevent notes from being nudged outside of the image borders
- Use CSS classes instead of applying the styles to the elements.
-- Allows a user to override any of the default styles being applied.
- Remove the borders and handles when not hovering over the box.
- Increase the opacity for embedded notes to full to avoid conflicts with
the text underneath.
- Decrease the opacity a little when editing embedded notes.
-- Allows for better seeing of the text underneath while still being able
to see the translation text above.
-- Compensated for by showing full opacity when hovering over the note box.
Fineprint text was variously styled with `.info`, `.tn`, `.hint`, or
`.cost-footnote` css classes. Standardize on `.fineprint` instead. Use
`.hint` only for form hints and `.tn` only for <tn> tags in translation
notes.
Incidentally changes the font size of form hints to 0.8em (was 0.7em)
and the color of fineprint to #888 (was #AAA or #666).