All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
The API is unstable, and Semantic Versioning does not yet apply.
Changes in master that are not yet released. Click to see more.
Nothing here yet.
0.6.0 - 2021-11-01
$window.task
way of interfacing with a taskbar; use$window.setMinimizeTarget(taskbarButtonElement)
instead, and eventsicon-change
andtitle-change
to update the button.
MenuBar
methodcloseMenus()
to close any open menus.MenuBar
methodsetKeyboardScope(...elements)
to control hotkey handling$Window
methodsetMenuBar(menuBar)
to set the menu bar, and set up the keyboard scope.$Window
methodsetMinimizeTarget(taskbarButtonElement)
to set the element representing the window when minimized, which will be used when animating.$Window
propertyelement
to get the DOM element.element.$window
to get the$Window
instance from the DOM element.$Window
eventsicon-change
andtitle-change
- Top level menus support accelerator keys without holding Alt, if the menu bar is focused. (You can not yet tap Alt to focus the menu bar, so you're probably still going to need to hold Alt in practice for now.)
makeBlackToInsetFilter()
inparse-theme.js
to initialize an SVG filter for disabled button icons
- If you close a menu by clicking the menu button, the containing window will now be re-focused.
- Menus no longer close when encountering a synthetic
blur
event, to facilitate a hack in Pinball, where ablur
is triggered to trick the game into pausing. - Windows that are not
resizable
can no longer be maximized. The maximize button will be grayed out.
- Fixed error when pressing arbitrary (unhandled) keys with menu bar focused
- Menus now ignore Alt+(hotkey) if the event is already handled. (For instance, on the demo page there's a menu bar without a window which has global hotkeys, as well as menu bars with identical hotkeys in windows. Hotkeys will now affect the appropriate menu bar depending on whether a window is focused.)
- Window titlebar buttons now use
ButtonText
theme color instead of always black.
0.5.0 - 2021-10-29
$Window
's terribleoptions.icon
API; use the new, versatileoptions.icons
instead. No more ugly globals you have to define! Example:new $Window({icons: {16: 'app-16x16.png', any: 'app-icon.svg'}})
setIconByID()
, usesetIcons(icons)
instead (with same format asoptions.icons
)getIconName()
, use$window.icons
instead perhaps, or avoid it entirely
applyCSSProperties
now takes an options object instead of an element as the second argument. Useoptions.element
to specify the root element. Default isdocument.documentElement
(i.e.<html>
,:root
).applyCSSProperties
now accepts aCSSStyleDeclaration
interchangeably with a plain object of CSS properties, same asrenderThemeGraphics
does. I don't know if this is useful, but it's good to be consistent, and this doesn't cost much.- Page scrolling is prevented when the window is re-focused. (Browsers by default scroll controls into view, and re-focusing the window focuses the last focused control.)
touch-action: none
is now applied to the menu bar, so the page doesn't scroll if you're trying to access the menus.- Menus now close on pointer down, not pointer up, for menu buttons.
- When windows are minimized without a taskbar, the minimize button now shows a restore icon.
- Taskbar height calculation now includes padding/border (of
.taskbar
element) - When a menu item is clicked and the menu closes, the containing window is re-focused.
$Window
'sclosed
event wasn't fired because the element was removed from the DOM.- A non-
toolWindow
window withparentWindow
defined now shows as focused. aria-owns
attribute now correctly uses element IDs (not stringified elements like[object HTMLDivElement]
)- Super minor: if a menu bar is contained in a selection, it will no longer show access key underlines as white. This bothered me. What can I say, I'm a compulsive highlighter.
- Handle older jQuery for
pointerId
((e.pointerId ?? e.originalEvent.pointerId)
); affects the cursor during window resizing (which usessetPointerCapture
to keep a consistent cursor). - Fix restore from minimize (to taskbar) going to top left corner of screen (if the window had previously been dragged). (This does not apply to taskbarless minimization, which seems to be fine.)
- Word wrap is now prevented in flying titlebar text.
- Menu bar behavior with touch (menus not opening, dialogs blurring after opening via menu, etc.)
- Prevented showing multiple menu buttons as hovered (e.g. if you press Esc and left/right and then hover a different item with the mouse)
- Prevented focus ring showing on menu items when clicking and then using the keyboard, or when using touch. (Menu item highlight effect is separate from focus ring.)
- Prevented resizing window while minimized to bottom of screen (in the case that there's no taskbar).
- Prevented titlebar from shrinking and disappearing (especially when minimized without taskbar), for some window layouts.
- Fixed animation of window restoring if window was minimized without taskbar and then dragged.
- Fixed titlebar button active state not working in Chrome 95.
- Don't show padding around window when window is maximized.
- Windows are now shown as focused when focus is within an iframe, even for nested iframes! Unfortunately this can't work for cross-origin iframes in all cases. (For 98.js.org this was a regression in v0.4.0 due to focus handling changes, but now it's handled in the library)
- Focus can now be restored to the last focused control within (same-origin) iframes, even nested iframes! (when refocusing windows, e.g. clicking on the titlebar)
options.iframes.ignoreCrossOrigin
to silence warnings about cross-origin iframes (which can't be seamlessly integrated).applyCSSProperties
now supportsoptions.recurseIntoIframes
(defaults tofalse
).$Window
methodsmaximize()
,minimize()
, andrestore()
$Window
optionicons
which can specify icons of different sizes. Pass an object with keys that are sizes in pixels (or "any"), and values that are the URL of an image, or an object withsrcset
if you want support different pixel densities, or a DOM node if you want full control (e.g. to use an<svg>
or a font icon or an emoji text node).$Window
methodsetTitlebarIconSize
to set the icon size, picking the nearest size fromicons
.$Window
methodgetTitlebarIconSize
to get the current icon size.$Window
methodgetIconAtSize
to pick an icon for the given size, for use in a taskbar. Returns an element ornull
.$Window
now exposesicons
property based on theoptions.icons
option..pressing
class to show buttons as pressed (when triggering via the keyboard for example).
0.4.1 - 2021-10-20
- Ability to use
MenuBar
without$Window.js
(TypeError: Assignment to constant variable.
) - Handle
document.body
not existing if you create aMenuBar
beforeDOMContentLoaded
- Compatibility with older jQuery
- Removed some redundant event listeners
- More elements are considered tabbable (
object
,embed
,video
,audio
,iframe
,[contenteditable]
) - Greatly improved performance while hovering menu items! Focus is now only set on the menu popup, not the menu item.
- Menu item height no longer changes based on checkbox state
- Menu items that have a submenu open are now highlighted unless another item is hovered at that level.
- If you hover to open a submenu, and then press right (in LTR layout, or left in RTL), it will no longer go to the next top level menu. The submenu is already focused, so you can use up/down to navigate it.
- SVG is now used for checkbox menu items, instead of text.
- SVG for submenu arrow is now more accurate to Windows 98.
- Menu item and divider height is now accurate to Windows 98.
- Menu bars are now screen-reader-friendly!
info
events (for status bar updates) are now sent when using the arrow keys to navigate.- If a submenu is empty, it is shown with "(Empty)", grayed out.
0.4.0 - 2021-10-15
minWidth
option; useminOuterWidth
instead.minHeight
option; useminOuterHeight
instead.- global
window.focusedWindow
(not part of API)
$MenuBar.js
; useMenuBar.js
instead. jQuery is no longer used by the menu bar module.$MenuBar(menus)
; usenew MenuBar(menus).element
instead.- The extra parameter to menu bar's
info
event; useevent.detail?.description
instead.
parseThemeFileString
can now returnundefined
if the theme file is not valid.- HTML
dir
attribute / CSSdirection
property is now respected at the level of the window/menu bar, rather than just the document body, so you can have individual windows with different directions. - Menu bar's buttons and top level menus are no longer contained in a
<div class="menu-container">
element. Top level menus are now children of<body>
, as submenus already were. - Clicking on window will now focus not just the last focused element, but if there wasn't one, it will focus a control with
class="default"
, and if that doesn't exist, the first control, and if there's no controls, the window itself (specifically$window.$content
) or a tool window's parent window. $window.focus()
now actually focuses something, rather than just bringing the window to the top and making it appear active. It will focus the last focused control within the window, or else a control withclass="default"
, or else, if it's a tool window, the parent window, and otherwise the window itself (specifically$window.$content
).$window.blur()
now removes focus from any focused control within the window. If focus is outside the window, it's not changed.- Windows can now be positioned freely when the
<body>
element is smaller than the viewport. The boundary is considered to be the maximum of the document's scrollable area and the viewport. - Window focus is now based around DOM focus. Focusing a control within the window will automatically focus the window. Special logic for preventing blur for taskbars is removed. To prevent blur you must now listen for
mousedown
orpointerdown
on your element and callevent.preventDefault()
, the standard way to prevent blur. - Tool windows that have no parent window are now shown as focused as long as the browser window is focused. This is useful for web applications where the browser window takes the place of the parent application window.
- Window method
setDimensions({ innerWidth, innerHeight, outerWidth, outerHeight })
to set the size of the window. - Window options
innerWidth
,innerHeight
,outerWidth
,outerHeight
to set the initial size of the window. - Window options
minInnerWidth
,minInnerHeight
,minOuterWidth
,minOuterHeight
to set the minimum size of the window. - Windows can now be minimized without a taskbar.
- Menu bar's
info
event now works with submenus as well. (Previously items that contain submenus were assumed to not have descriptions, simply because Paint's one submenu does not a have a description. But for instance Explorer has descriptions for all of its menus (except Favorites, which is a bit special, what with drag and drop and context menus and all.)) - Greatly improved menu navigation:
- Menus can now be opened with Enter and exited with Escape.
- Menus can now be navigated with accelerators, and the first letters of items without accelerators defined.
- Pressing Escape an extra time will unfocus the menu bar, focusing the last focused control within the window.
- Submenus can now be navigated with the arrow keys.
- Submenus stay open more easily. It's a little buggy still, but they're not constantly trying to close themselves on you.
- Menus wrap around when navigating up and down or left and right.
- The default action of scrolling the page with arrow keys is now prevented when menus are focused.
- Improved accuracy of the titlebar styles, especially for tool windows.
- Fixed active state of the titlebar buttons in Firefox.
- Disabled buttons no longer show active state if you try to click on them.
- In demo: When loading a theme file, do not apply any styles if it is not a valid theme file.
- For right-to-left languages, submenus are now opened with the left arrow key, matching the arrow direction shown, and menus are navigated with left/right arrow keys spatially (before it was swapped because the order of elements was reversed but the key bindings were not).
- Titlebar gradient is flipped for RTL languages.
- Submenus have correct RTL layout. (Top level menus were previously descendants of the window (so I didn't notice the problem), but now all menus are children of the document body, and
dir
attribute is propagated from the menu bar element'sdirection
CSS property to the floating menus.) - Focused disabled menu items are distinguished from enabled menu items.
0.3.0 - 2021-09-04
- Added window options
toolWindow
,parentWindow
,maximizeButton
,minimizeButton
,closeButton
,resizable
,minWidth
,minHeight
, andconstrainRect(rect, x_axis, y_axis)
. - Added window method
bringTitleBarInBounds()
. - Added window event
closed
, which should be used instead ofclose
for detecting when the window is closed. Useclose
only for preventing the window from closing. - Added window event
window-drag-start
. - Focus wrapping now works with Shift+Tab in addition to Tab, and handles more types of focusable elements.
- Focus is now restored to the last focused element within the window when the window is focused again.
- Focus is now given to the next-topmost window when the window is closed.
- Loosened constraints on windows when releasing a drag. You can now drag a window out of the screen, except the titlebar is kept in bounds. (This still doesn't match the behavior of Windows, but in Windows you can recover a window from offscreen with Alt+Space or the taskbar context menu.)
- Increased thickness of the window frame to match the look of Windows 98.
- Window overflow is now hidden by default, with
contain: layout paint;
on.window-content
in the layout CSS. - Window content now flexes to fill the window, with
flex: 1;
in the layout CSS. The$content
element still uses the default box model (i.e.display: block
), but is stretched within its parent which usesdisplay: flex;
.
- Use standard
touch-action
CSS property instead of obsolete PEP polyfill's attribute. The PEP library was never included or documented as a dependency. - Keyboard shortcuts using the meta key are no longer swallowed by the window.
- Allow setting title to empty string. Not very useful.
0.2.2 - 2020-04-30
- Added a Blue color scheme for use in JS Paint for the Winter theme.
- The menu bar is now a fixed height, which should help with automated visual regression testing in JS Paint.
- Submenu popups are now offset correctly on scrollable pages (such as the demo)
- Windows are now clamped to the bounds of a scrollable page instead of an area the size of the view at the top of the page
- Windows are now centered correctly in view when the page is scrolled
- Windows are now dragged correctly while scrolling the page
- Unwanted globals
$G
andE
are no longer exported
- Windows are bounded to the screen at the end of a drag operation. This doesn't match behavior of windows in Windows 98, but in lieu of OS features for getting windows back on screen like Alt+Space, I think this makes sense for now.
- Dragging over iframes is fixed
- Some layout-important CSS is moved to
layout.css
- Some titlebar-related styles are scoped in to
.os-window *
to fix conflicts in jspaint, where I'm trying to use a separate window class temporarily for tool windows. - Colors:
- Menu bar dividers now correctly use the theme colors
- Disabled buttons now correctly use the theme colors
- Disabled menu items now correctly use the theme colors except that sometimes it should just show GrayText and not a 3D effect
- Menu bar button text uses the correct colors now
0.2.0 - 2020-03-12
- Rewrote using PostCSS
- Everything is now themeable, by dragging and dropping
.theme
and.themepack
files - Maximize and Minimize, with flying titlebar effect
- Default buttons
- Toggle buttons
- Button borders are now based on SVG
border-image
, instead of using pseudo elements,border
andbox-shadow
.- Metrics for buttons are changed, they're simpler now, because it's not extending visibly outside the border-box.
- (
::after
is now free to use for other things, altho::before
is still used for showing focus.)
- Window component is now an app window instead of a tool window, to aid reintegration with 98.js.org; jspaint will come later.
- Window component is styled with
.os-window
now, altho it includes both classesos-window
andwindow
.