Skip to content

Commit

Permalink
wip: menu
Browse files Browse the repository at this point in the history
  • Loading branch information
arnog committed Nov 18, 2023
1 parent b1056ec commit 211a48e
Show file tree
Hide file tree
Showing 26 changed files with 2,328 additions and 159 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## [Unreleased]

### New Features

- A menu is available when right-clicking on a mathfield or when clicking
the menu glyph next to the virtual keyboard glyph. The menu allows
toggling the virtual keyboard, changing the mathfield mode (math, text)
and inserting and editing matrixes.


## 0.96.2 (2023-11-16)

### Bugs Fixed
Expand Down
46 changes: 20 additions & 26 deletions css/mathfield.less
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
width: 100%;
}

.ML__virtual-keyboard-toggle {
.ML__virtual-keyboard-toggle, .ML__menu-toggle {
box-sizing: border-box;
display: flex;
align-self: center;
Expand Down Expand Up @@ -275,28 +275,23 @@ with this style */

/* Add an attribute 'data-tooltip' to automatically show a
tooltip over a element on hover.
Use 'data-position="top"' to place the tooltip above the
element rather than below.
Use 'data-delay' to delay the triggering of the tooltip.
*/
[data-tooltip] {
position: relative;
&[data-placement='top']::after {
top: inherit;
bottom: 100%;
}
&::after {
content: attr(data-tooltip);
position: absolute;
display: none;
display: block;
z-index: 2;
pointer-events: none;

right: auto; // center tooltip
top: calc(-100% - 4px); // place tooltip above element

right: 110%;
left: calc(100% + 8px);
width: max-content;
max-width: 200px;
padding: 8px 8px;
border-radius: 2px;
border-radius: 4px;

background: #616161; // Grey 700
color: #fff;
Expand All @@ -308,7 +303,7 @@ with this style */
font-family: @system;
font-style: normal;
font-weight: 400;
font-size: 12px;
font-size: 13px;

/* Phone */
@media only screen and (max-width: 767px) {
Expand All @@ -318,33 +313,32 @@ with this style */

opacity: 0;
transform: scale(0.5);
// animation: .150s tooltipFadeOut cubic-bezier(0.4, 0.0, 1, 1) forwards;
transition: all 0.15s cubic-bezier(0.4, 0, 1, 1);
}
}

:not(.tracking) [data-tooltip]:hover {
[data-tooltip]:hover {
position: relative;
&::after {
visibility: visible; // Visible triggers the animation...
display: inline-table;
opacity: 1; // ... but we start fully transparent to
// give ourselves a delay before showing
transform: scale(1);
}
transition-property: opacity, scale;
transition-duration: 0.15s;
// give ourselves a delay before showing
transition-delay: 1s;
transition-timing-function: cubic-bezier(0.4, 0, 1, 1)
}
}

[data-tooltip][data-delay]::after {
// On fade out, we don't want a delay
transition-delay: 0s;
}
[data-tooltip][data-delay]:hover::after {
// But we do want a delay on fade in
transition-delay: 1s; /* attr(data-delay); Should work. But doesn't. */
.tracking [data-tooltip]:hover {
&::after {
display: none
}
}




.ML__prompt {
border-radius: 2px;
}
Expand Down
12 changes: 12 additions & 0 deletions src/common/stylesheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ import KEYSTROKE_CAPTION_STYLESHEET from '../../css/keystroke-caption.less';
// @ts-ignore-error
import VIRTUAL_KEYBOARD_STYLESHEET from '../../css/virtual-keyboard.less' assert { type: 'css' };

import UI_STYLESHEET from '../ui/style.less' assert { type: 'css' };

import MENU_STYLESHEET from '../ui/menu/style.less' assert { type: 'css' };

type StylesheetId =
| 'ui'
| 'menu'
| 'core'
| 'mathfield-element'
| 'mathfield'
Expand Down Expand Up @@ -69,6 +75,12 @@ export function getStylesheetContent(id: StylesheetId): string {
case 'virtual-keyboard':
content = VIRTUAL_KEYBOARD_STYLESHEET;
break;
case 'ui':
content = UI_STYLESHEET;
break;
case 'menu':
content = MENU_STYLESHEET;
break;
default:
debugger;
}
Expand Down
6 changes: 2 additions & 4 deletions src/editor-mathfield/keyboard-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import type { Selector } from '../public/commands';
import { splitGraphemes } from '../core/grapheme-splitter';
import { Atom } from '../core/atom';

import {
keyboardEventToChar,
mightProducePrintableCharacter,
} from '../editor/keyboard';
import { keyboardEventToChar } from '../editor/keyboard';
import { getInlineShortcut } from '../editor/shortcuts';
import { getCommandForKeybinding } from '../editor/keybindings';
import { SelectorPrivate } from '../editor/commands';
Expand All @@ -28,6 +25,7 @@ import type { ParseMode, Style } from 'public/core-types';
import type { ModelPrivate } from 'editor-model/model-private';
import { LeftRightAtom } from 'core-atoms/leftright';
import { RIGHT_DELIM, LEFT_DELIM } from 'core/delimiters';
import { mightProducePrintableCharacter } from 'ui/events/utils';

/**
* Handler in response to a keystroke event (or to a virtual keyboard keycap
Expand Down
39 changes: 39 additions & 0 deletions src/editor-mathfield/mathfield-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import {
getDefault as getDefaultOptions,
get as getOptions,
effectiveMode,
getDefaultMenuItems,
} from '../editor/options';
import { normalizeKeybindings } from '../editor/keybindings';
import {
Expand Down Expand Up @@ -119,11 +120,16 @@ import {
hideEnvironmentPopover,
updateEnvironmentPopover,
} from 'editor/environment-popover';
import { Menu } from 'ui/menu/menu';

const DEFAULT_KEYBOARD_TOGGLE_GLYPH = `<svg style="width: 21px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" role="img" aria-label="${localize(
'tooltip.toggle virtual keyboard'
)}"><path d="M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm16 336c0 8.823-7.177 16-16 16H48c-8.823 0-16-7.177-16-16V112c0-8.823 7.177-16 16-16h480c8.823 0 16 7.177 16 16v288zM168 268v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm-336 80v-24c0-6.627-5.373-12-12-12H84c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm384 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zM120 188v-24c0-6.627-5.373-12-12-12H84c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm-96 152v-8c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z"/></svg>`;

const MENU_GLYPH = `<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512" role="img" aria-label="${localize(
'tooltip.menu'
)}"><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg>`;

/** @internal */
export class _Mathfield implements Mathfield, KeyboardDelegateInterface {
readonly model: ModelPrivate;
Expand Down Expand Up @@ -173,6 +179,8 @@ export class _Mathfield implements Mathfield, KeyboardDelegateInterface {

private blurred: boolean;

private _menu: Menu;

// The value of the mathfield when it is focussed.
// If this value is different when the field is blured
// the `change` event is dispatched
Expand Down Expand Up @@ -305,6 +313,13 @@ export class _Mathfield implements Mathfield, KeyboardDelegateInterface {
markup.push('</div>');
}

// 2.2// The menu toggle
markup.push(
`<div part=menu-toggle class=ML__menu-toggle role=button data-l10n-tooltip="tooltip.menu">`
);
markup.push(MENU_GLYPH);
markup.push('</div>');

markup.push('</span>'); // end container

// 3.1/ The aria-live region for announcements
Expand Down Expand Up @@ -374,6 +389,30 @@ If you are using Vue, this may be because you are using the runtime-only build o
{ signal: this.eventController.signal }
);

this._menu = new Menu(getDefaultMenuItems(this));

const menuToggle =
this.element!.querySelector<HTMLElement>('[part=menu-toggle]')!;
menuToggle?.addEventListener(
'pointerdown',
(ev) => {
if (ev.currentTarget !== menuToggle) return;
if (this._menu.state !== 'closed') return;
this.element!.classList.add('tracking');
this._menu.show({
parent: menuToggle,
location: {
x: menuToggle.offsetLeft,
y: menuToggle.offsetHeight + menuToggle.offsetTop,
},
onDismiss: () => this.element!.classList.remove('tracking'),
});
ev.preventDefault();
ev.stopPropagation();
},
{ signal: this.eventController.signal }
);

this.ariaLiveText = this.element.querySelector('[role=status]')!;
// this.accessibleMathML = this.element.querySelector('.accessibleMathML')!;

Expand Down
6 changes: 2 additions & 4 deletions src/editor-mathfield/smartmode.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import {
keyboardEventToChar,
mightProducePrintableCharacter,
} from '../editor/keyboard';
import { keyboardEventToChar } from '../editor/keyboard';
import type { _Mathfield } from './mathfield-private';

import { ModelPrivate } from '../editor-model/model-private';
import { Atom } from '../core/atom-class';
import { LeftRightAtom } from '../core-atoms/leftright';
import { joinLatex } from '../core/tokenizer';
import { mightProducePrintableCharacter } from 'ui/events/utils';

/**
* Convert the atoms before the anchor to 'text' mode
Expand Down
12 changes: 12 additions & 0 deletions src/editor-model/model-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,18 @@ export class ModelPrivate implements Model {
return parent as ArrayAtom;
}

/** Return the cell (row, col) that the current selection is in */
get cell(): [number, number] | undefined {
let atom: Atom | undefined = this.at(this.position);
if (!atom) return undefined;

while (atom && atom.parent?.type !== 'array') atom = atom.parent;

if (!atom?.parent || atom.parent.type !== 'array') return undefined;

return atom.parentBranch as [number, number];
}

contentWillChange(options: ContentChangeOptions = {}): boolean {
// The mathfield could be undefined if the mathfield was disposed
// while the content was changing
Expand Down
94 changes: 2 additions & 92 deletions src/editor/keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
*/

import { normalizeKeyboardEvent } from './keyboard-layout';
import { Scrim } from './scrim';
import { Scrim } from '../ui/utils/scrim';
import { mightProducePrintableCharacter } from 'ui/events/utils';

export interface KeyboardDelegate {
cancelComposition: () => void;
Expand All @@ -38,97 +39,6 @@ export interface KeyboardDelegate {
dispose: () => void;
}

const PRINTABLE_KEYCODE = new Set([
'Backquote', // Japanese keyboard: hankaku/zenkaku/kanji key, which is non-printable
'Digit0',
'Digit1',
'Digit2',
'Digit3',
'Digit4',
'Digit5',
'Digit6',
'Digit7',
'Digit8',
'Digit9',
'Minus',
'Equal',
'IntlYen', // Japanese Keyboard. Russian keyboard: \/

'KeyQ', // AZERTY keyboard: labeled 'a'
'KeyW', // AZERTY keyboard: labeled 'z'
'KeyE',
'KeyR',
'KeyT',
'KeyY', // QWERTZ keyboard: labeled 'z'
'KeyU',
'KeyI',
'KeyO',
'KeyP',
'BracketLeft',
'BracketRight', // On the Windows Swedish keyboard, this is the `¨` key, which is a dead key
'Backslash', // May be labeled #~ on UK 102 keyboard
'KeyA', // AZERTY keyboard: labeled 'q'
'KeyS',
'KeyD',
'KeyF',
'KeyG',
'KeyH',
'KeyJ',
'KeyK',
'KeyL',
'Semicolon',
'Quote',
'IntlBackslash', // QWERTZ keyboard '><'
'KeyZ', // AZERTY: 'w', QWERTZ: 'y'
'KeyX',
'KeyC',
'KeyV',
'KeyB',
'KeyN',
'KeyM',
'Comma',
'Period',
'Slash',
'IntlRo', // Japanese keyboard '\ろ'

'Space',

'Numpad0',
'Numpad1',
'Numpad2',
'Numpad3',
'Numpad4',
'Numpad5',
'Numpad6',
'Numpad7',
'Numpad8',
'Numpad9',
'NumpadAdd',
'NumpadComma',
'NumpadDecimal',
'NumpadDivide',
'NumpadEqual',
'NumpadHash',
'NumpadMultiply',
'NumpadParenLeft',
'NumpadParenRight',
'NumpadStar',
'NumpadSubstract',
]);

export function mightProducePrintableCharacter(evt: KeyboardEvent): boolean {
// Ignore ctrl/cmd-combinations but not shift/alt-combinations
if (evt.ctrlKey || evt.metaKey) return false;

// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
if (['Dead', 'Process'].includes(evt.key)) return false;

// When issued via a composition, the `code` field is empty
if (evt.code === '') return true;

return PRINTABLE_KEYCODE.has(evt.code);
}

/**
* Create a normalized representation of a keyboard event,
* i.e., key code and modifier keys. For example:
Expand Down
5 changes: 3 additions & 2 deletions src/editor/l10n-strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ export const STRINGS = {
'tooltip.paste from clipboard': 'Paste from Clipboard',
'tooltip.redo': 'Redo',
'tooltip.toggle virtual keyboard': 'Toggle Virtual Keyboard',
'tooltip.menu': 'Menu',
'tooltip.undo': 'Undo',
'menu.insert matrix': 'Insert Matrix',
'menu.insert vector': 'Insert Vector',
'menu.insert table': 'Insert Table',
'submenu.array.matrix delimiters': 'Matrix Delimiters',
'menu.array.add row above': 'Add Row After',
'menu.array.add row below': 'Add Row Before',
'menu.array.add row above': 'Add Row Before',
'menu.array.add row below': 'Add Row After',
'menu.array.add column after': 'Add Column After',
'menu.array.add column before': 'Add Column Before',
'menu.array.delete row': 'Delete Row',
Expand Down
Loading

0 comments on commit 211a48e

Please sign in to comment.