1658 Commits

Author SHA1 Message Date
ff406d4edc js: Convert space after tick in menus to a space character
Older Firefox versions don't support "-moz-appearance: none" on radio
buttons, which seems to mean that the specifies padding for them
doesn't appear.  Using a space character instead works fine, so do that
everywhere.  This seems to move the text slightly closer to the tick on
browsers that do support "appearance: none", but the result is quite
acceptable.

This also makes the focus outline on the ticks slightly less weird.
2022-11-15 01:31:01 +00:00
a55c0c188b js: Use -moz-appearance and -webkit-appearance
The "appearance" property is newer than WebAssembly, but major browsers
have much older namespaced versions that we can support as well.
2022-11-15 01:06:35 +00:00
a90bb4a4ef js: Better handling of games without presets and/or solve
Games with neither presets nor configuration (which may only be the Null
Game) have been slightly broken since the introduction of hierarchical
preset menus, in that the code to remove the "Type..." menu stopped
being called then.  My switch to using radio buttons in menus then broke
them utterly because it's not possible to set the value of an empty
radio group, causing a crash at startup.

Fix this by detected when there's no preset menu, removing the item from
the menu bar, and setting the variable that's meant to indicate this has
been done.

The solve button problem was more subtle, in that only the <button> was
being hidden and not the <li> containing it, which led to the right border of the menu bar being two pixels thick.  Switch to fully removing
the <li> from the DOM, like we now do with the presets menu, since that
also makes my keyboard handler (in another branch) simpler.
2022-11-13 14:05:55 +00:00
5a225bf585 js: Substantially simplify timer code
The C code in the Emscripten front-end already keeps a timer_active
variable to ensure that the timer can be activated only when it's
inactive, and deactivated only when it's active.  Adjusting the
JavaScript side to rely on this makes the code much simpler.  The only
oddity is that it now requests a new animation frame before calling the
callback so that it's ready to be cancelled if the callback decides to
deactivate the timer.
2022-11-13 00:15:00 +00:00
5a90dd9312 js: Give keyboard focus to the puzzle canvas at startup again
I think this has been broken since a752e73, when the canvas changed to
being hidden, and hence unable to receive keyboard focus, when the page
loaded.  I've now moved the focus() call to after the canvas gets
displayed.
2022-11-12 17:21:03 +00:00
8ef28a4fd6 js: Remove class="text/css" from <style> element
This is the wrong attribute, and the correct type="text/css" is
deprecated by MDN.  Since it's never worked, the deprecated attribute
presumably isn't needed either.
2022-11-12 15:32:18 +00:00
208e2508d3 js: Add a way to have environment variables
They can now be specified by sticking some JSON in a <script> element in
the Web page:

<script id="environment" type="application/json">
   { "LOOPY_DEFAULT": "20x10t11dh" }
</script>

This isn't brilliantly useful, but it does allow for changing settings
without recompiling.
2022-11-12 15:03:40 +00:00
4e3bb8f257 js: Use <li role="separator"> in place of <li class="separator">
ARIA has a "separator" role that has the semantics we want, so let's use
it.
2022-11-12 12:18:59 +00:00
a9c783ed4e js: Label all form controls and put controls inside labels
This should help with accessibility and means we don't need to give IDs
to tick-boxes.
2022-11-12 12:07:35 +00:00
8f40128f08 js: Prettify menu HTML
Now that we're using flex layout, whitespace in the menu isn't scary and
we can use it to make the HTML readable.

Also finally remove the "afterseparator" class that's long obsolete.
You can always use ".separator + *" as a selector instead.
2022-11-12 11:28:39 +00:00
27d41e7cf0 js: Simplify menu CSS a little
Mostly removing redundant rules and simplifying selectors.
2022-11-12 11:22:43 +00:00
60d2bf5930 js: Convert menus to use semantically appropriate HTML elements
Presets are now radio buttons with labels, and menu items that take
actions are now buttons.  The <li> representing each menu item is now a
thin wrapper around another element: a <label> for radio buttons, a
<button> for other buttons, and a <div> for submenu headings.  All of
the things that previously applied to the <li> now apply to that inner
element instead.

This means that presets can now use the standard "checked" attribute to
indicate which one is selected, and buttons can be disabled using the
standard "disabled" attribute.  It also means that we can query and set
the state of all the presets at once through their RadioNodeList.

I think this should also make the menus more accessible, and make it
easier to make them keyboard-controllable.
2022-11-12 09:48:31 +00:00
22c4cad50e Correct a comment: draw_rect_outline() uses draw_polygon() 2022-11-10 23:39:08 +00:00
73f4edb09f Remove setting of indent-tabs-mode from filling.c
Simon said that the continued presence of tabs for indentation in
Puzzles is unintentional, so we should at least discourage the
addition of new ones.
2022-11-10 23:39:08 +00:00
2a02547755 Remove a couple of unused variables.
These broke the overnight build, due to -Werror.
2022-11-10 12:37:10 +00:00
00e4d79db1 js: Enable STRICT_JS in Emscripten
This turns on "use strict" in JavaScript, which enforces declaring
variables among other things, and may allow better optimisations.
2022-11-10 00:40:52 +00:00
2115799094 js: Add various missing variable declarations 2022-11-10 00:13:59 +00:00
f7957d3aa0 js: Reinstate a missing variable declaration
... and then decide there was no excuse for renaming the variable, so
now it has the same name it had before I started using
Window.requestAnimationFrame().
2022-11-09 23:44:26 +00:00
7982002a64 js: Switch to window.requestAnimationFrame() for timing
This is an API specifically designed for the purposes of timing
animations.  Unlike setInterval, it tries to synchronise with the screen
refresh rate.  It naturally passes us timing information, saving the
need to construct a Date object every frame.  It has the nice feature
that browsers (at least Firefox 91) will call it less frequently when
the puzzle page isn't visible, which saves CPU time in puzzles that run
a timer continuously.
2022-11-09 21:40:27 +00:00
c5a2446fae js: Cancel UI events when the mid end says they've been handled
This means that if a key doesn't do anything in a puzzle, it can operate
the browser instead.
2022-11-08 10:27:19 +00:00
4a37f7cf78 Add a way for midend_process_key() to report whether it handled a keypress
This adds a new bool * argument, which can be NULL if front ends don't
care whether the keypress was handled.  Currently they all do that.

Currently, "undo" and "redo" keys are treated as not handled if there's
no move to undo or redo.  This may be a little too strict.
2022-11-08 10:27:19 +00:00
4fdcc54975 js: Make SoftRight act as CURSOR_SELECT2 as well
This way, the front end can intercept one of SoftLeft and SoftRight as a
menu key and leave the other one for the puzzle.  And while we don't
have a working menu, I can use whichever is more convenient.
2022-11-08 10:27:19 +00:00
ee5b02b0ca js: Map the "SoftLeft" key to CURSOR_SELECT2
This is the left soft key on KaiOS phones.  The centre soft key
already sends "Enter", which eventually becomes CURSOR_SELECT.  The
right soft key I'm planning to use to open the menu.
2022-11-08 10:27:19 +00:00
ad9ee5a524 js: Move much of the handling of device pixel ratios to the mid-end
Now that the mid-end knows how to do it, we can remove some complexity
from the front end.
2022-11-08 10:27:02 +00:00
e45cd43aaa Teach the mid-end about device pixel ratios
The device pixel ratio indicates how many physical pixels there are in
the platonic ideal of a pixel, at least approximately.  In Web browsers,
the device pixel ratio is used to represent "retina" displays with
particularly high pixel densities, and also to reflect user-driven
zooming of the page to different text sizes.

The mid-end uses the device pixel ratio to adjust the tile size at
startup, and can also respond to changes in device pixel ratio by
adjusting the time size later.  This is accomplished through a new
argument to midend_size() which can simply be passed as 1.0 in any front
end that doesn't care about this.
2022-11-08 00:57:36 +00:00
fba22f04d6 js: Make update_pixel_ratio() more robust
With very small tile sizes, js_canvas_find_font_midpoint() can throw an
exception.  When it was called from update_pixel_ratio(), this prevented
the new MediaQueryList from being created, which meant that the puzzle
stopped noticing changes of device pixel ratio.

Now update_pixel_ratio() establishes a new MediaQueryList before calling
rescale_puzzle(), so the exception can't break it.  Catching the
exception properly would be even better, of course.
2022-11-08 00:57:32 +00:00
289342ec33 js: Adjust z-indices of sub-menus and resize handle
The sub-menus should appear in front of the resize handle (but still
behind any dialogue box).
2022-11-01 09:23:41 +00:00
06f6e878a0 js: Tolerate the non-existence of some HTML elements
Specifically, the permalinks, the apology, and the resizable div.
2022-10-29 11:58:37 +01:00
ea4ba47662 Loopy: adjust clip rectangle for new line thickness.
It would have helped in the previous commit if I'd tried actually
_playing_ the game, not just admiring it in its initial state. When I
did, I found that lines weren't being fully overdrawn, which turned
out to be because the clip rectangle was being set too narrow.
2022-10-28 22:35:22 +01:00
ebb079eca0 Loopy: make line thicknesses scale with the canvas.
This is now important due to Ben's changes in the web frontend. On
high-DPI displays, the canvas is the same overall size as before, but
it's scaled up by increasing the game's tilesize rather than the
browser scaling the image after the game redraws.

Loopy ought to have been scaling its line thicknesses all along, but
forgot. Easily fixed.
2022-10-28 21:32:14 +01:00
1e8169ea94 js: Take device pixel ratio into account when setting default size
This is a bit of a hack.  When setting the puzzle to its default size,
either at startup or from a right-click on the resize handle, we now
scale the default size from midend_size() by the device pixel ratio,
and then pass that back to midend_size().  This does more or less the
right thing, in that the puzzle now starts up at a size that scales
with the font size.

There are still some slight inconsistencies, where sequences of DPR
changes and puzzle parameter changes can have order-dependent effects
on the size of the puzzle.  Happily these effects are small and fairly
hard to observe.
2022-10-27 22:51:54 +01:00
fa58dd85b7 js: Distinguish manual resizes from device pixel ratio changes
This adds a new callback, rescale_puzzle(), that's called when the
device pixel ratio changes.  This means that resize_puzzle() can safely
set the nominal canvas size, which means that manual resizing of the
puzzle now sticks.

Still missing: paying attention to the device pixel ratio when choosing
the initial (or reset) size.
2022-10-27 22:51:54 +01:00
9783bbfbc0 js: Split setting nominal and actual canvas size
Now zooming in and out repeatedly doesn't cause the canvas to wither
away, but user resizes don't stick any more.  Still more to do.
2022-10-27 22:51:54 +01:00
532d662722 js: Very bad attempt at making puzzles change size when zooming
This has the entertaining consequence that repeatedly zooming in and out
causes puzzles to gradually shrink, thus demonstrating that recording
the nominal size correctly will be necessary.
2022-10-27 22:51:48 +01:00
5af0cd4ac1 js: Add a CMake variable to control whether Emscripten emits WASM
I've finally got bored of keeping (and occasionally losing) a patch
that turns it off unconditionally.
2022-10-27 09:59:04 +01:00
6f5debe417 js: Make update_pixel_ratio more backward-compatible
Despite my stylistic downgrades, it still used two features not present
in Firefox 48, and hence KaiOS 2.5: passing options to addEventListener,
and calling addEventListener on a MediaQueryList at all.  Now it uses
the older addListener method and explicitly removes each listener as
soon as it's called.
2022-10-26 21:57:53 +01:00
7354790ca4 js: Use String.replace() in place of .replaceAll()
The latter turns out to be a little too new for KaiOS 2.5, but
.replace() will do global replacements if fed a RegExp.
2022-10-26 21:23:54 +01:00
5fae5ca0db js: Be more subtle about cancelling keydown events
Now we only cancel a keydown event if the C keyboard handler recognises
the key and passes it on to the midend.  This doesn't necessarily mean
that the midend has actually done anything with it, of course.  Still,
this is enough to allow F12 to open the developer tools even when the
input focus is on the puzzle.  It also allows for tabbing out of the
puzzle into the links below it.
2022-10-25 20:38:37 +01:00
e6faebeb9a js: Remove keypress handler
At least in modern browsers (and I suspect in all browsers), cancelling
a keydown event ensures that the subsequent keypress event doesn't fire.
See <https://w3c.github.io/uievents/#keys-cancelable-keys>.

So there's no point in having a handler on keypress events that just
tries to cancel them as well.  Removing the handler doesn't do much now,
but it opens the possibility of being a bit more selective about which
keydown events we cancel.
2022-10-25 20:13:59 +01:00
43c89dd5e1 js: Add a comment explaining the two halves of the key-matching code 2022-10-25 00:50:47 +01:00
d94d671bf9 js: Handle KeyboardEvent.key == "Spacebar"
This is apparently generated in place of " " by Internet Explorer.
2022-10-25 00:48:58 +01:00
35d382019f js: Recognise KeyboardEvent.key == "Escape" 2022-10-24 23:33:09 +01:00
f5ac13c847 js: Add mapping for UI_REDO based on KeyboardEvent.key 2022-10-24 23:19:56 +01:00
768ef770a3 js: Use KeyboardEvent.key for ASCII keystrokes
This requires passing in KeyboardEvent.location from JavaScript so
that we can detect the numeric keypad properly.  Out of caution we
currently only set MOD_NUM_KEYPAD on numbers, like we always have,
but we have enough information to set it on arrow keys, Enter, "+",
etc.

This finally gets '/' and '\' working in Slant again.
2022-10-24 23:13:33 +01:00
0db5fb525b js: Remove the charCode argument from key()
It hasn't been used in a while.
2022-10-24 22:37:30 +01:00
9698732d65 js: Add modern "key" values for Delete and arrow keys
Firefox has emitted "Delete", "ArrowDown" etc since 2015.
2022-10-24 22:22:33 +01:00
322a439d80 js: Use KeyboardEvent.keyCode and .char only as fallbacks
KeyboardEvent.keyCode is a platform-dependent mess.
KeyboardEvent.char is better-defined, but in my browser it's always
null.  KeyboardEvent.key is the right thing to use when we want to
know the semantics of a key.

This commit just re-organises the big "else if" chain in key() so
that all the tests on "key" come first.  That way at least if key and
keyCode disagree, we'll use the more trustworthy one.
2022-10-24 22:07:12 +01:00
c1059c07fb js: Remove braces from big else-if chain in keyboard handler
If there's ever a case where they're unnecessary noise, it's a long
chain of "else if"s guarding single assignment statements.
2022-10-24 21:57:53 +01:00
a62217e9b4 js: Use less-modern syntax in update_pixel_ratio
Stealing code from the MDN has the consequence that it uses shiny ES6
features like "const", "let", and "=>".  This looks a bit odd among
the more conservative style of the rest of Puzzles, so I've
downgraded it to "var" and "function".  I'll let the template string
stay because that actually helps readability.
2022-10-23 11:15:31 +01:00
0254a163ff js: Make resizing of puzzles work properly again
This requires looking at the CSS size of the puzzle canvas rather than
its internal size, and then adjusting the new size to account for the
device pixel ratio.
2022-10-22 18:50:34 +01:00