mmo-app
1 symbol · generated 5 Oct 2026
mmo-app
mmo-app.jhs:1The application shell. One element, three templates, chosen by the host's class: <mmo-app class="admin">, class="landing" or class="blog".
- Extends
- CustomShadowElement
Index
| template | the template to use (admin, landing, blog). | |
| template accessor | The active template. | |
| constructor() | ||
| init() | ||
| initPanelResize() | Let the side panel be dragged wider or narrower by its left edge. | |
| resizePanelByKey(event) | Resize the panel from the keyboard: left and right by 16px, 4px with shift, Home back to its default width. | |
| setPanelWidth(width) | ||
| fitPanel() | Give the panel the width its shown panel asks for (showPanel's width), unless the user chose one by dragging its edge. | |
| resetPanelWidth() | Put the panel back to the width the stylesheet gives it. | |
| updateRegions() | Reflect which optional regions the page filled, as host classes: a hero, a page header or a rail that no slot fills is removed from the layout instead of holding empty space. | |
| load(config) | Load the application configuration, the object the theme writes into MMO.config. | |
| addBreadcrumb(label, url, index) | Add a breadcrumb, closest to the root first. | |
| clearTabs() | Remove every page tab. | |
| getTabs() | Every page tab currently in the strip. | |
| addTab(label, url, icon, order) | Add a page tab. | |
| scrollTabs(direction) | Scroll the tab strip. | |
| updateTabsOverflow() | Show the tab scrollers only when the strip actually overflows. | |
| getMenu(url) | Find a rail entry by the url it points at. | |
| setActiveMenu(url) | Mark a menu entry, and every accordion above it, as active. | |
| revealMenu(node) | Scroll a rail entry into view, in the rail's own scroller. | |
| addMenu(group, label, url, icon, order) | Add a menu entry, creating the accordion hierarchy its url implies. | |
| bindAccordionToggle(accordion) | Keep an accordion's open state across pages, and keep its title a link. | |
| toggleMenu() | Collapse or expand the rail. | |
| shortcut(event) | Global shortcuts: alt+/ opens the palette, escape closes what is open. | |
| initCommands() | The commands the shell always has: what its own buttons do, when the template has those buttons. | |
| addCommand(label, run, icon, keywords) | Add a command to the palette, listed under « Commandes ». | |
| addSearchSource(source) | Add a remote source to the palette: its results are listed under their own heading, after the pages and the commands. | |
| openPalette(query) | Open the command palette, on the whole menu or already searching. | |
| paletteBackdrop(event) | Close the command palette when the click is on the veil around it, not in its box. | |
| closePalette() | Close the command palette. | |
| filterPalette(query) | Filter the palette on what has been typed, one group per category: the text of the page itself first (searchPage), then the pages of the menu, the commands, and each remote source (addSea… | |
| searchPage(query, limit) | Find a text in the page: accents and case do not count. | |
| indexPage() | Read the text of the page once, when the palette opens, so a search is a lookup rather than a walk through the whole document at every key. | |
| pageMatch(entry, at, length) | One match in the page, as a palette item: the words around it, the match marked. | |
| revealPageMatch(node, at, length) | Scroll to a match in the page, and select it: the selection is the browser's own highlight, and nothing is written into the page. | |
| fold(text) static | Fold a text for searching: lower case, accents dropped -- one character for one character, so an offset in the folded text is the same offset in the original. | |
| searchRemote(source, query) | Ask a remote source, and read its answer as palette items. | |
| appendPaletteGroup(parent, title, items) | Add a group of results to the palette. | |
| updatePaletteEmpty(query) | Keep one result selected, and say so when there is none left -- once no source is still searching. | |
| paletteKey(event) | Move through the results, across the groups, and follow the selected one. | |
| showPanel(title, body, options) | Open a panel in the side drawer, in a tab of its own. | |
| createPanelTab(panel) | the tab of a panel: its title, which shows it, and a button closing it | |
| selectPanel(id) | Show an open panel. | |
| updatePanel(id, changes) | Change an open panel: the title of its tab, or its key (showPanel). | |
| onPanelTabsKey(event) | the tab strip from the keyboard: arrows go from tab to tab, Delete closes one | |
| closePanel(value, id) | Close a panel, resolving its promise. | |
| closeAllPanels(value) | Close every panel. | |
| showNotification(css, content) | Show a notification. | |
| notify(content, title, button, butIcon) | Show a notification with a title and a dismiss button. | |
| showModal(css, content) | Show a modal dialog. | |
| answer(node, value) | Wire a dialog's buttons to its result: any <button value="..."> closes the dialog with that value, and the promise resolves with it -- false when the dialog is dismissed (escape, a click outsid… | |
| ask(title, content) | Ask for a value: one input, and the answer. | |
| confirm(title, content) | Ask a yes/no question. | |
| alert(title, content) | Say something, with one button to dismiss it. | |
| error(title, content) | The same, in the error tone. | |
| describeError(error) | An error as a user reads it: what happened, in French; the server's message when it is meant for a user (the framework's own name what they are about in [brackets], an id or a path is no such thi… | |
| toggleUserCard() | Toggle the account card. | |
| toggleConsole() | Toggle the developer drawer. | |
| showConsoleTab(name) | Show one pane of the developer drawer, and open the drawer if it was closed. | |
| loadServerInfo(reload) | Fill the server pane with what the server is made of: php, its extensions and every package the framework included, as AdminController::routeServerInfo answers them. | |
| toggleTOC() | Toggle the table of contents. | |
| updateConsoleTags(console) | Update the warning and error counters of the status bar. | |
| gotoTop(event) | Scroll back to the top of whichever container actually scrolls. | |
| blockScreen(active) | Block the screen while something runs. | |
| setThemeMode(scheme) | Apply a colour scheme. | |
| toggleDarkMode() | Switch between the dark and light schemes. | |
| (default) | the page itself | |
| logo | the mark at the top of the rail | |
| menu | rail entries written by hand, next to the ones MMO.config.menus adds | |
| side-foot | the foot of the rail, on the row the scheme switch ends | |
| user-info | the account line next to the account button, at the end of the top bar | |
| user-card-body | what the account card shows when it is opened | |
| brand | the brand in the top bar, for the landing and blog templates | |
| nav | links in the top bar | |
| actions | buttons on the right of the top bar | |
| header | anything else on the top bar, after the actions | |
| hero | the band above the page, for a landing | |
| page-title | the page header's title | |
| page-actions | the page header's buttons | |
| navigation | a strip between the header and the content (filters, a sub-navigation) | |
| aside | the rail on the right of the content, for an article | |
| footer | the footer, for the landing and blog templates | |
| panel-title | extra content at the end of the side panel's tab strip (its tabs are built by showPanel) | |
| panel | the body of the side panel | |
| status | the status bar, left of the log button | |
| logs | the lines the server log tab of the developer drawer shows | |
| notifications | the notifications stacked in the corner | |
| screen-blocker | what covers the page while it is blocked (blockScreen) | |
| .admin | the application shell: rail, breadcrumb, page tabs, side panel, status bar | |
| .landing | the marketing shell: sticky translucent header, hero, sections, large footer | |
| .blog | the editorial shell: header, content column, sticky rail, footer | |
| .menu-collapsed | the rail is reduced to icons | |
| .menu-open | the rail is open, on a small screen | |
| .has-tabs | the page has tabs: a small screen gives them a row of their own under the top bar | |
| .panel-open | the side panel is open | |
| .console-open | the developer drawer (server log, server information) is open | |
| .toc-open | the table of contents is open | |
| .palette-open | the command palette is open, over the page | |
| .has-hero | the page filled the hero region, so the shell makes room for it | |
| .has-user-card | the page filled the account card, so it gets a body above the logout link |
Attributes1
template
mmo-app.jhsthe template to use (admin, landing, blog). Defaults to the host's class.
template
Properties1
template
accessormmo-app.jhs:1413The active template.
- Type
string
Methods64
constructor()
mmo-app.jhs:1234init()
mmo-app.jhs:1251initPanelResize()
mmo-app.jhs:1314Let the side panel be dragged wider or narrower by its left edge.
| returns | void |
resizePanelByKey(event)
mmo-app.jhs:1348Resize the panel from the keyboard: left and right by 16px, 4px with shift, Home back to its default width.
| event | KeyboardEvent | |
| returns | void |
setPanelWidth(width)
mmo-app.jhs:1368| width | number | - in pixels |
| returns | void |
fitPanel()
mmo-app.jhs:1379Give the panel the width its shown panel asks for (showPanel's width), unless the user chose one by dragging its edge. The panel's own max-width still caps it.
| returns | void |
resetPanelWidth()
mmo-app.jhs:1387Put the panel back to the width the stylesheet gives it. @return {void}
updateRegions()
mmo-app.jhs:1397Reflect which optional regions the page filled, as host classes: a hero, a page header or a rail that no slot fills is removed from the layout instead of holding empty space.
load(config)
mmo-app.jhs:1435Load the application configuration, the object the theme writes into MMO.config.
| config | object | - breadcrumbs, navigations, menus and logs |
addBreadcrumb(label, url, index)
mmo-app.jhs:1482Add a breadcrumb, closest to the root first.
| label | string | - html, from the application's config (load) |
| url | string | |
| index = 0 | number | - the depth of this crumb |
| returns | HTMLAnchorElement |
clearTabs()
mmo-app.jhs:1489Remove every page tab.
getTabs()
mmo-app.jhs:1498Every page tab currently in the strip.
| returns | NodeList | the page tabs |
addTab(label, url, icon, order)
mmo-app.jhs:1510Add a page tab.
| label | string | - html, from the application's config (load) |
| url | string | |
| icon = null | ?string | |
| order = 0 | number | |
| returns | HTMLAnchorElement |
scrollTabs(direction)
mmo-app.jhs:1526Scroll the tab strip.
| direction | number | - -1 left, 1 right |
updateTabsOverflow()
mmo-app.jhs:1532Show the tab scrollers only when the strip actually overflows.
getMenu(url)
mmo-app.jhs:1549Find a rail entry by the url it points at.
| url | string | |
| returns | ?HTMLElement | the menu entry for this url |
setActiveMenu(url)
mmo-app.jhs:1562Mark a menu entry, and every accordion above it, as active.
| url | string |
revealMenu(node)
mmo-app.jhs:1591Scroll a rail entry into view, in the rail's own scroller.
| node | HTMLElement |
addMenu(group, label, url, icon, order)
mmo-app.jhs:1612Add a menu entry, creating the accordion hierarchy its url implies.
| group | string | - the section of the rail this entry belongs to, html (load) |
| label | string | - html, from the application's config (load) |
| url | string | |
| icon | string | |
| order = 0 | number |
bindAccordionToggle(accordion)
mmo-app.jhs:1695Keep an accordion's open state across pages, and keep its title a link.
| accordion | HTMLElement |
toggleMenu()
mmo-app.jhs:1720Collapse or expand the rail. On a small screen it opens as a drawer instead.
shortcut(event)
mmo-app.jhs:1741Global shortcuts: alt+/ opens the palette, escape closes what is open.
| event | KeyboardEvent |
initCommands()
mmo-app.jhs:1758The commands the shell always has: what its own buttons do, when the template has those buttons.
addCommand(label, run, icon, keywords)
mmo-app.jhs:1775Add a command to the palette, listed under « Commandes ».
| label | string | - text |
| run | Function | - called when the command is picked, once the palette is closed |
| icon = null | ?string | - an <mmo-icon> name |
| keywords = '' | string | - other words the command is found by |
| returns | label: string, run: Function, icon: ?string, keywords: string | } the command |
addSearchSource(source)
mmo-app.jhs:1791Add a remote source to the palette: its results are listed under their own heading, after the pages and the commands. The server is asked url?q=…&limit=… (plus params) and answers {results: [{url, label | shortName | name, kind, hint | namespace, icon}]}, or the same wrapped in data. The server usually declares its sources in MMO.config.searches (load).
| source | ||
| returns | Object | the source |
openPalette(query)
mmo-app.jhs:1802Open the command palette, on the whole menu or already searching.
| query = '' | string | - what the palette starts with |
paletteBackdrop(event)
mmo-app.jhs:1814Close the command palette when the click is on the veil around it, not in its box.
| event | MouseEvent |
closePalette()
mmo-app.jhs:1819Close the command palette.
filterPalette(query)
mmo-app.jhs:1834Filter the palette on what has been typed, one group per category: the text of the page itself first (searchPage), then the pages of the menu, the commands, and each remote source (addSearchSource), which only answers once typing pauses.
| query | string |
searchPage(query, limit)
mmo-app.jhs:1903Find a text in the page: accents and case do not count. Each match is listed with its context and the heading it sits under; picking it scrolls to it and selects it (revealPageMatch).
| query | string | |
| limit = 20 | number | |
| returns | Array<Object> | palette items |
indexPage()
mmo-app.jhs:1925Read the text of the page once, when the palette opens, so a search is a lookup rather than a walk through the whole document at every key. The page is what the default slot and the page's own regions hold -- never the menu, the panels or the notifications -- open shadow roots included, and only what is visible.
| returns | Array<{node: Text, text: string, heading: string | >} each text node, folded (fold), with the heading it sits under |
pageMatch(entry, at, length)
mmo-app.jhs:1967One match in the page, as a palette item: the words around it, the match marked.
| entry | ||
| at | number | - where the match starts in the text node |
| length | number | |
| returns | Object |
revealPageMatch(node, at, length)
mmo-app.jhs:1991Scroll to a match in the page, and select it: the selection is the browser's own highlight, and nothing is written into the page.
| node | Text | |
| at | number | |
| length | number |
fold(text)
staticmmo-app.jhs:2012Fold a text for searching: lower case, accents dropped -- one character for one character, so an offset in the folded text is the same offset in the original.
| text | string | |
| returns | string |
searchRemote(source, query)
mmo-app.jhs:2024Ask a remote source, and read its answer as palette items.
| source | ||
| query | string | |
| returns | Promise<Array<Object>> |
appendPaletteGroup(parent, title, items)
mmo-app.jhs:2044Add a group of results to the palette.
| parent | HTMLElement | |
| title | string | - the category |
| items |
updatePaletteEmpty(query)
mmo-app.jhs:2079Keep one result selected, and say so when there is none left -- once no source is still searching.
| query | string |
paletteKey(event)
mmo-app.jhs:2096Move through the results, across the groups, and follow the selected one.
| event | KeyboardEvent |
showPanel(title, body, options)
mmo-app.jhs:2146Open a panel in the side drawer, in a tab of its own.
- See
selectPanel,updatePanel).
| title | string | - text |
| body | ?(Node | string | MMO.core.dom.Html) | - a node, or text; markup you wrote goes through MMO.core.dom.html() |
| options = {} | object | - key: what identifies the panel, to show it again rather than open it twice; width: the width it wants, in pixels, while it is shown (an edit form needing room), unless the user dragged the panel to a width of their own |
| returns | Promise | resolved with the value the panel is closed with. promise.node is the panel's body element, for a caller that has to reach into it, and promise.id its id (closePanel, |
createPanelTab(panel)
mmo-app.jhs:2174the tab of a panel: its title, which shows it, and a button closing it
| panel |
selectPanel(id)
mmo-app.jhs:2198Show an open panel.
| id | string | - the panel's id (promise.id of showPanel) |
| returns | void |
updatePanel(id, changes)
mmo-app.jhs:2218Change an open panel: the title of its tab, or its key (showPanel).
| id | string | - the panel's id |
| changes = {} | object | - title (text) and/or key |
| returns | void |
onPanelTabsKey(event)
mmo-app.jhs:2232the tab strip from the keyboard: arrows go from tab to tab, Delete closes one
| event |
closePanel(value, id)
mmo-app.jhs:2259Close a panel, resolving its promise. The panel shown is the one closed unless another is named: a button inside a panel closes its own (the one shown, since it was clicked).
| value = null | * | - what showPanel's promise resolves with |
| id = null | ?string | - the panel to close, the one shown by default |
closeAllPanels(value)
mmo-app.jhs:2280Close every panel.
| value = null | * | - what each panel's promise resolves with |
showNotification(css, content)
mmo-app.jhs:2296Show a notification.
| css | string | - a tone class: success, warning, error, info |
| ...content | ...* | - its children (MMO.core.dom.appendChildren); one with a slot goes to that part of the card, title or footer (mmo-notification) |
| returns | HTMLElement |
notify(content, title, button, butIcon)
mmo-app.jhs:2316Show a notification with a title and a dismiss button.
| content | * | - the body: text, a node, or MMO.core.dom.html() (showNotification) |
| title | string | - text |
| button = 'ok' | string | - the dismiss label, text |
| butIcon = 'eye' | string | - the dismiss icon |
| returns | HTMLElement |
showModal(css, content)
mmo-app.jhs:2340Show a modal dialog.
- See
error,showNotification,notifyandshowPanel. Markup the caller wrote itself goes throughMMO.core.dom.html().
| css | string | |
| ...content | ...* | - its children, MMO.core.dom.appendChildren |
| returns | HTMLDialogElement |
answer(node, value)
mmo-app.jhs:2356Wire a dialog's buttons to its result: any <button value="..."> closes the dialog with that value, and the promise resolves with it -- false when the dialog is dismissed (escape, a click outside), so a caller can always tell "no" from "not answered".
| node | HTMLDialogElement | |
| value | function(HTMLDialogElement, string):* | - what to resolve with, from the button's value |
| returns | Promise |
ask(title, content)
mmo-app.jhs:2385Ask for a value: one input, and the answer.
| title | string | - text |
| ...content | ...* | - shown above the input: text unless it is a node (showModal) |
| returns | Promise<string | false> | what was typed, false when cancelled |
confirm(title, content)
mmo-app.jhs:2408Ask a yes/no question.
| title | string | - text |
| ...content | ...* | - text unless it is a node (showModal) |
| returns | Promise<boolean> |
alert(title, content)
mmo-app.jhs:2423Say something, with one button to dismiss it.
| title | string | - text |
| ...content | ...* | - text unless it is a node (showModal) |
| returns | Promise<boolean> | true when it was acknowledged |
error(title, content)
mmo-app.jhs:2444The same, in the error tone.
| title | string | Error | - text, or an Error (then titled Une erreur est survenue) |
| ...content | ...* | - text unless it is a node (showModal); an Error is described |
| returns | Promise<boolean> |
describeError(error)
mmo-app.jhs:2473An error as a user reads it: what happened, in French; the server's message when it is meant for a user (the framework's own name what they are about in [brackets], an id or a path is no such thing); the rest -- url, status, message, stack -- folded under « Détail technique ».
| error | Error | |
| returns | HTMLElement[] | its paragraph and its folded detail |
toggleUserCard()
mmo-app.jhs:2513Toggle the account card.
toggleConsole()
mmo-app.jhs:2518Toggle the developer drawer.
showConsoleTab(name)
mmo-app.jhs:2527Show one pane of the developer drawer, and open the drawer if it was closed. The server pane is fetched the first time it is asked for, not on every page load: it is a tool, not a page region.
| name | string | - logs or server |
loadServerInfo(reload)
mmo-app.jhs:2542Fill the server pane with what the server is made of: php, its extensions and every package the framework included, as AdminController::routeServerInfo answers them.
| reload = false | boolean | - fetch again even if the pane was already filled |
| returns | Promise |
toggleTOC()
mmo-app.jhs:2574Toggle the table of contents.
updateConsoleTags(console)
mmo-app.jhs:2584Update the warning and error counters of the status bar.
| console | HTMLElement |
gotoTop(event)
mmo-app.jhs:2593Scroll back to the top of whichever container actually scrolls.
| event = null | ?Event |
blockScreen(active)
mmo-app.jhs:2603Block the screen while something runs.
| active = true | boolean |
setThemeMode(scheme)
mmo-app.jhs:2611Apply a colour scheme.
| scheme = 'default' | string | - dark, light or default to follow the system |
toggleDarkMode()
mmo-app.jhs:2628Switch between the dark and light schemes.
Slots22
(default)
mmo-app.jhsthe page itself
<slot>
logo
mmo-app.jhsthe mark at the top of the rail
<slot name="logo">
menu
mmo-app.jhsrail entries written by hand, next to the ones MMO.config.menus adds
<slot name="menu">
side-foot
mmo-app.jhsthe foot of the rail, on the row the scheme switch ends
<slot name="side-foot">
user-info
mmo-app.jhsthe account line next to the account button, at the end of the top bar
<slot name="user-info">
user-card-body
mmo-app.jhswhat the account card shows when it is opened
<slot name="user-card-body">
brand
mmo-app.jhsthe brand in the top bar, for the landing and blog templates
<slot name="brand">
nav
mmo-app.jhslinks in the top bar
<slot name="nav">
actions
mmo-app.jhsbuttons on the right of the top bar
<slot name="actions">
header
mmo-app.jhsanything else on the top bar, after the actions
<slot name="header">
hero
mmo-app.jhsthe band above the page, for a landing
<slot name="hero">
page-title
mmo-app.jhsthe page header's title
<slot name="page-title">
page-actions
mmo-app.jhsthe page header's buttons
<slot name="page-actions">
navigation
mmo-app.jhsa strip between the header and the content (filters, a sub-navigation)
<slot name="navigation">
aside
mmo-app.jhsthe rail on the right of the content, for an article
<slot name="aside">
footer
mmo-app.jhsthe footer, for the landing and blog templates
<slot name="footer">
panel-title
mmo-app.jhsextra content at the end of the side panel's tab strip (its tabs are built by showPanel)
<slot name="panel-title">
panel
mmo-app.jhsthe body of the side panel
<slot name="panel">
status
mmo-app.jhsthe status bar, left of the log button
<slot name="status">
logs
mmo-app.jhsthe lines the server log tab of the developer drawer shows
<slot name="logs">
notifications
mmo-app.jhsthe notifications stacked in the corner
<slot name="notifications">
screen-blocker
mmo-app.jhswhat covers the page while it is blocked (blockScreen)
<slot name="screen-blocker">
CSS hooks12
.admin
mmo-app.jhsthe application shell: rail, breadcrumb, page tabs, side panel, status bar
.admin
.landing
mmo-app.jhsthe marketing shell: sticky translucent header, hero, sections, large footer
.landing
.blog
mmo-app.jhsthe editorial shell: header, content column, sticky rail, footer
.blog
.menu-collapsed
mmo-app.jhsthe rail is reduced to icons
.menu-collapsed
.menu-open
mmo-app.jhsthe rail is open, on a small screen
.menu-open
.has-tabs
mmo-app.jhsthe page has tabs: a small screen gives them a row of their own under the top bar
.has-tabs
.panel-open
mmo-app.jhsthe side panel is open
.panel-open
.console-open
mmo-app.jhsthe developer drawer (server log, server information) is open
.console-open
.toc-open
mmo-app.jhsthe table of contents is open
.toc-open
.palette-open
mmo-app.jhsthe command palette is open, over the page
.palette-open
.has-hero
mmo-app.jhsthe page filled the hero region, so the shell makes room for it
.has-hero
.has-user-card
mmo-app.jhsthe page filled the account card, so it gets a body above the logout link
.has-user-card