mmo-app
1 symbol · generated 30 Sep 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) | ||
| 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. | |
| 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) | Open a panel in the side drawer. | |
| closePanel(value) | Close the panel on top of the stack, 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. | |
| 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 | the tabs of the side panel, one per open panel | |
| 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 | |
| .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:1240The active template.
- Type
string
Methods57
constructor()
mmo-app.jhs:1086init()
mmo-app.jhs:1098initPanelResize()
mmo-app.jhs:1161Let the side panel be dragged wider or narrower by its left edge.
| returns | void |
resizePanelByKey(event)
mmo-app.jhs:1187Resize 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:1207| width | number | - in pixels |
| returns | void |
resetPanelWidth()
mmo-app.jhs:1214Put the panel back to the width the stylesheet gives it. @return {void}
updateRegions()
mmo-app.jhs:1224Reflect 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:1262Load 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:1309Add 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:1316Remove every page tab.
getTabs()
mmo-app.jhs:1325Every page tab currently in the strip.
| returns | NodeList | the page tabs |
addTab(label, url, icon, order)
mmo-app.jhs:1337Add 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:1353Scroll the tab strip.
| direction | number | - -1 left, 1 right |
updateTabsOverflow()
mmo-app.jhs:1359Show the tab scrollers only when the strip actually overflows.
getMenu(url)
mmo-app.jhs:1374Find a rail entry by the url it points at.
| url | string | |
| returns | ?HTMLElement | the menu entry for this url |
setActiveMenu(url)
mmo-app.jhs:1387Mark a menu entry, and every accordion above it, as active.
| url | string |
revealMenu(node)
mmo-app.jhs:1416Scroll a rail entry into view, in the rail's own scroller.
| node | HTMLElement |
addMenu(group, label, url, icon, order)
mmo-app.jhs:1437Add 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:1520Keep an accordion's open state across pages, and keep its title a link.
| accordion | HTMLElement |
toggleMenu()
mmo-app.jhs:1536Collapse or expand the rail. On a small screen it opens as a drawer instead.
shortcut(event)
mmo-app.jhs:1557Global shortcuts: alt+/ opens the palette, escape closes what is open.
| event | KeyboardEvent |
initCommands()
mmo-app.jhs:1574The commands the shell always has: what its own buttons do, when the template has those buttons.
addCommand(label, run, icon, keywords)
mmo-app.jhs:1591Add 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:1607Add 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:1618Open the command palette, on the whole menu or already searching.
| query = '' | string | - what the palette starts with |
closePalette()
mmo-app.jhs:1627Close the command palette.
filterPalette(query)
mmo-app.jhs:1642Filter 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:1711Find 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:1733Read 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:1775One 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:1799Scroll 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:1820Fold 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:1832Ask a remote source, and read its answer as palette items.
| source | ||
| query | string | |
| returns | Promise<Array<Object>> |
appendPaletteGroup(parent, title, items)
mmo-app.jhs:1852Add a group of results to the palette.
| parent | HTMLElement | |
| title | string | - the category |
| items |
updatePaletteEmpty(query)
mmo-app.jhs:1887Keep one result selected, and say so when there is none left -- once no source is still searching.
| query | string |
paletteKey(event)
mmo-app.jhs:1904Move through the results, across the groups, and follow the selected one.
| event | KeyboardEvent |
showPanel(title, body)
mmo-app.jhs:1944Open a panel in the side drawer.
| title | string | - text |
| body | ?(Node | string | MMO.core.dom.Html) | - a node, or text; markup you wrote goes through MMO.core.dom.html() |
| 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. |
closePanel(value)
mmo-app.jhs:1965Close the panel on top of the stack, resolving its promise.
| value = null | * | - what showPanel's promise resolves with |
closeAllPanels(value)
mmo-app.jhs:1978Close every panel.
| value = null | * | - what each panel's promise resolves with |
showNotification(css, content)
mmo-app.jhs:1994Show 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:2014Show 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:2038Show 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:2054Wire 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:2083Ask 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:2106Ask a yes/no question.
| title | string | - text |
| ...content | ...* | - text unless it is a node (showModal) |
| returns | Promise<boolean> |
alert(title, content)
mmo-app.jhs:2121Say 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:2136The same, in the error tone.
| title | string | Error | - text: an Error reads as Error: its message |
| ...content | ...* | - text unless it is a node (showModal) |
| returns | Promise<boolean> |
toggleUserCard()
mmo-app.jhs:2148Toggle the account card.
toggleConsole()
mmo-app.jhs:2153Toggle the developer drawer.
showConsoleTab(name)
mmo-app.jhs:2162Show 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:2177Fill 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:2209Toggle the table of contents.
updateConsoleTags(console)
mmo-app.jhs:2219Update the warning and error counters of the status bar.
| console | HTMLElement |
gotoTop(event)
mmo-app.jhs:2228Scroll back to the top of whichever container actually scrolls.
| event = null | ?Event |
blockScreen(active)
mmo-app.jhs:2238Block the screen while something runs.
| active = true | boolean |
setThemeMode(scheme)
mmo-app.jhs:2246Apply a colour scheme.
| scheme = 'default' | string | - dark, light or default to follow the system |
toggleDarkMode()
mmo-app.jhs:2263Switch 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.jhsthe tabs of the side panel, one per open panel
<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 hooks11
.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
.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