PageEditor
MMO.editor · 1 symbole · générée le 27 Oct 2026
PageEditor
PageEditor.js:29The backoffice of the pages built from sections (mmo.editor's MMO\editor\cms): the pages, and the one being edited -- its fields, its sections as forms made from their types' schemas, a live preview, its publication and its history. Everything goes through the api (admin/pages…, `MMO.editor.config). <mmo-page-editor>` is its element; it can be built on any container.
- Espace de noms
MMO.editor
Index
| HISTORY_PAUSE static | how long a pause ends a group of changes: typing a sentence is one step to undo, as in <mmo-editor> | |
| HISTORY_SIZE static | the steps kept | |
| LANGUAGES static | the languages offered when one is added (any other code can be typed) | |
| LANGUAGE_CODE static | a language's tag (RFC 5646), as the server takes it: mmo.core's I18n::LANGUAGE_REGEX, which MMO\editor\cms\Translations::Code() checks with -- change both together | |
| constructor(node, options) | ||
| Level() static | ||
| EdmsUploadUrl(labels) static | ||
| destroy() | The editor is gone: what it listens to outside of its node goes with it | |
| h(tag, attrs, children) | ||
| $(name) | ||
| t(text, context) | ||
| build() | [internal] The editor's own nodes: a bar (the page, its state, its actions, the level), the work -- the sections' form and the preview; at the expert level the preview alone, over the whole window … | |
| openDrawer(panel, id) | Open the drawer on $panel: page (the page's settings), new (a new page), section (the settings of the section $id), add (a section to add, after $id), languages (the page's, and what they… | |
| closeDrawer() | ||
| renderSectionPanel(id) | [internal] The drawer shows the settings of the section $id: @return {boolean} false when there is none | |
| renderAddPanel(after) | [internal] The types of section, to add one after the section $after (at the end without it) | |
| levelSwitch() | [internal] @return {HTMLElement} the levels: the display modes', which reload the page, or the editor's own | |
| setLevel(level) | Show $level (without the display modes: the editor's own) | |
| Rank(level) static | ||
| confirm(title, text) | ||
| notify(text) | ||
| tourId() | ||
| registerTour() | Give MMO.guide (mmo.client) the guided tour of the level shown: the bar's ? offers it, and it starts by itself the first time the user meets that level. | |
| tour() | ||
| call(method, path, body, {token = this.token, raw = false, retry = true}) async | ||
| emit(name, detail) | ||
| start() async | [internal] The types of section, the pages, then the page to open | |
| loadPages() async | ||
| pill(page) | ||
| open(id, force) async | Open the page $id: its unsaved changes are the user's to leave | |
| setPage(page, history) | ||
| renderStatus() | ||
| changed(preview) | The draft changed: the history records it, the preview follows, unless the change came from it (the expert level edits it in place) | |
| snapshot() | ||
| record() | [internal] A change: the state before it goes on the undo stack -- once for a group of changes made without a pause -- and what was undone can no longer be redone | |
| flushHistory() | [internal] End the group of changes running: the draft as it is now is the history's state | |
| undo() | Undo the last change of the draft (a group of changes made without a pause) | |
| redo() | Redo the last change undone | |
| applyState(state) | [internal] Put the draft back as $state says: the form, the drawer and the preview follow | |
| updateHistory() | [internal] The undo and redo buttons: enabled when there is something to undo, to redo | |
| historyKey(event) | [internal] The history's keys: Mod+Z undoes, Mod+Shift+Z and Ctrl+Y redo -- but in a field (an input, a text being edited: <mmo-editor> takes the keys it answers, defaultPrevented), which undoe… | |
| save() async | ||
| publish() async | ||
| unpublish() async | ||
| remove() async | ||
| create(form) async | Make a page from the form of the side | |
| loadRevisions() async | ||
| CanCompare() static | ||
| compare(revision) | Show what changed between $revision and the draft, as json, side by side, in a dialog: the application's side panel is too narrow for two versions, and under the editor's drawer. | |
| rollback(number) async | ||
| LanguageCode(code) static | ||
| languageName(code) | ||
| translatable(field, key, parent) | ||
| filled(value) | ||
| merge(field, base, translation, kind) | ||
| extract(field, value, base, kind) | ||
| untranslated(field, base, translation, kind, path, labels, found) | [internal] The texts of $base (a field's value in the default language) that $translation does not translate | |
| translationOf(draft, language) | ||
| draft() | ||
| extractShown() | [internal] @return {?Object} the translation of the language shown: what its texts say that the default language's do not | |
| showLanguage(draft) | [internal] Put $draft (draft) in the form, in the language shown: its texts translated, the default language's where they are not | |
| setLanguage(language) | Show the page in $language (one of its languages; null or the default one: the default one) | |
| baseValue(path) | ||
| renderLanguages() | [internal] The bar's language, the notice of the language shown, the drawer's languages when it shows them | |
| renderLanguagesPanel() | [internal] The drawer's languages: the default one, the others -- each with what it does not translate yet, a link to each field -- and adding one | |
| valueAt(draft, path) | ||
| excerpt(value, length) | ||
| addLanguage(code, defaultLanguage) | Add the language $code to the page ($defaultLanguage its default one, when it had none), and show it | |
| removeLanguage(code) async | Take $code out of the page's languages: its translation goes with it (it can be undone) | |
| setDefaultLanguage(code) | The page's texts are in $code: what its default language is called (nothing is translated) | |
| goToField(language, path) | Open the field $path (the form's data-path) in $language, to translate it | |
| visible(field) | ||
| defaults(schema) | ||
| translateExample(value, schema) | ||
| newSection(type) | ||
| indexOf(id) | ||
| addSection(type, after) | Add a section of $type, after the section $after (at the end without it) | |
| moveSection(i, to) | ||
| copySection(i) | ||
| deleteSection(i) | ||
| fieldInput(field, obj, key, path) | ||
| imageInput(field, obj, key, path) | [internal] @return {Array<HTMLElement>} an image: its address, a file sent to mmo.edms, its description | |
| listInput(field, obj, key, path) | [internal] @return {HTMLElement} a list of items: each its fields, moved, removed, added | |
| renderPageFields() | ||
| renderSections() | ||
| sectionCard(section, i, alone) | ||
| showErrors(errors) | Show what the api says is wrong: in a list, and next to each field (the closest one the form has) | |
| preview(version, label) | Render $version (the draft by default) in the preview, a moment after the last change | |
| showPreview(html, expert) | [internal] $html in the preview: its addresses resolved from this page, its sections clickable | |
| hookPreview(scroll, expert, tries) | [internal] Once the preview's document is parsed (its load may never come: a request of the page staying open): a click on a section opens its form; at the expert level, the edits in place go int… | |
| setFromPreview(path, html, region) | Write what the expert level edited in place into the draft | |
| sectionTools(doc) | [internal] The toolbar of the section under the pointer, in the preview: move, copy, remove, add one after it | |
| select(id, scroll) | Select the section $id: framed in the preview, its form opened | |
| resize(button, width) | The preview's width: a desktop's, a tablet's, a phone's |
Constantes4
HISTORY_PAUSE
staticPageEditor.js:575how long a pause ends a group of changes: typing a sentence is one step to undo, as in <mmo-editor>
HISTORY_SIZE
staticPageEditor.js:577the steps kept
LANGUAGES
staticPageEditor.js:793the languages offered when one is added (any other code can be typed)
LANGUAGE_CODE
staticPageEditor.js:798a language's tag (RFC 5646), as the server takes it: mmo.core's I18n::LANGUAGE_REGEX, which MMO\editor\cms\Translations::Code() checks with -- change both together
Méthodes90
constructor(node, options)
PageEditor.js:42| node | HTMLElement | - where it is built |
| options = {} | Object | - pages {string} the url of admin/pages.json (MMO.editor.config.pages) - sections {string} the url of admin/sections.json (MMO.editor.config.sections) - token {string} the session's CSRF token (MMO.editor.config.token) - page {?(string|number)} the page to open; none: the first one - level {?string} simple, standard or expert; none: MMO.modes' - uploadUrl {?string} where the images go; none: mmo.edms' one-request upload, when the page has it - uploadLabels {string} the edms labels of the images ("#pages": the user's own tag) - list {boolean} false to show one page only, without the list of the pages |
Level()
staticPageEditor.js:93| retourne | string | the level the display modes show: simple, standard or expert -- standard when the application offers no such level |
EdmsUploadUrl(labels)
staticPageEditor.js:102| labels = '"#pages"' | ||
| retourne | ?string | mmo.edms' one-request upload (edms/files.json), when the page has edms, for $labels |
destroy()
PageEditor.js:111The editor is gone: what it listens to outside of its node goes with it
h(tag, attrs, children)
PageEditor.js:125| tag | string | |
| attrs = {} | Object | - on… are listeners, value is the property; null, undefined and false are left out |
| ...children | ...* | - strings are text, never html |
| retourne | HTMLElement |
$(name)
PageEditor.js:137| name |
t(text, context)
PageEditor.js:146| text | string | - in english, translated by MMO.i18n |
| context = null | ?Object | - what replaces its {name}s |
| retourne | string |
build()
PageEditor.js:156[internal] The editor's own nodes: a bar (the page, its state, its actions, the level), the work -- the sections' form and the preview; at the expert level the preview alone, over the whole window -- and a drawer, opened on demand: the page's settings, a new page, a section's settings, the history
openDrawer(panel, id)
PageEditor.js:237Open the drawer on $panel: page (the page's settings), new (a new page), section (the settings of the section $id), add (a section to add, after $id), languages (the page's, and what they do not translate), history
| panel | ||
| id = null |
closeDrawer()
PageEditor.js:250renderSectionPanel(id)
PageEditor.js:257[internal] The drawer shows the settings of the section $id: @return {boolean} false when there is none
| id |
renderAddPanel(after)
PageEditor.js:265[internal] The types of section, to add one after the section $after (at the end without it)
| after = null |
levelSwitch()
PageEditor.js:273[internal] @return {HTMLElement} the levels: the display modes', which reload the page, or the editor's own
setLevel(level)
PageEditor.js:293Show $level (without the display modes: the editor's own)
| level |
Rank(level)
staticPageEditor.js:304| level |
confirm(title, text)
PageEditor.js:308| title | ||
| text |
notify(text)
PageEditor.js:312| text |
tourId()
PageEditor.js:319| retourne | string | the id of the guided tour of the level shown (guides/{id} in the user's config) |
registerTour()
PageEditor.js:327Give MMO.guide (mmo.client) the guided tour of the level shown: the bar's ? offers it, and it starts by itself the first time the user meets that level. The other levels' tours go: one tour, the one of what is shown.
tour()
PageEditor.js:335| retourne | Object | the guided tour of the level shown (MMO.guide): its targets are the editor's own nodes |
call(method, path, body, {token = this.token, raw = false, retry = true})
asyncPageEditor.js:426| method | string | |
| path | string | - under admin/, or a whole url |
| body = undefined | * | - sent as json |
| {token = this.token, raw = false, retry = true} = {} | ||
| retourne | Promise<{status: number, data: *, meta: *, text: string | >} |
emit(name, detail)
PageEditor.js:458| name | ||
| detail |
start()
asyncPageEditor.js:463[internal] The types of section, the pages, then the page to open
loadPages()
asyncPageEditor.js:484| retourne | Promise<Array<Object>> | the pages, in the picker of the bar |
pill(page)
PageEditor.js:494| page |
open(id, force)
asyncPageEditor.js:499Open the page $id: its unsaved changes are the user's to leave
| id | ||
| force = false |
setPage(page, history)
PageEditor.js:518| page | Object | - as the api gives it |
| history = 'reset' | string | - reset (another page), keep (saved, published: the same draft), record (a draft replaced -- a rollback --, which can be undone) |
renderStatus()
PageEditor.js:545changed(preview)
PageEditor.js:564The draft changed: the history records it, the preview follows, unless the change came from it (the expert level edits it in place)
| preview = true |
snapshot()
PageEditor.js:580| retourne | string | the draft as the history keeps it |
record()
PageEditor.js:588[internal] A change: the state before it goes on the undo stack -- once for a group of changes made without a pause -- and what was undone can no longer be redone
flushHistory()
PageEditor.js:603[internal] End the group of changes running: the draft as it is now is the history's state
undo()
PageEditor.js:614Undo the last change of the draft (a group of changes made without a pause)
redo()
PageEditor.js:622Redo the last change undone
applyState(state)
PageEditor.js:630[internal] Put the draft back as $state says: the form, the drawer and the preview follow
| state |
updateHistory()
PageEditor.js:648[internal] The undo and redo buttons: enabled when there is something to undo, to redo
historyKey(event)
PageEditor.js:659[internal] The history's keys: Mod+Z undoes, Mod+Shift+Z and Ctrl+Y redo -- but in a field (an input, a text being edited: <mmo-editor> takes the keys it answers, defaultPrevented), which undoes its own typing
| event | KeyboardEvent |
save()
asyncPageEditor.js:673| retourne | Promise<boolean> | whether the draft was saved |
publish()
asyncPageEditor.js:685unpublish()
asyncPageEditor.js:696remove()
asyncPageEditor.js:704create(form)
asyncPageEditor.js:720Make a page from the form of the side
| form |
loadRevisions()
asyncPageEditor.js:738CanCompare()
staticPageEditor.js:755| retourne | boolean | whether the page can show what changed between a revision and the draft: when it has mmo.git's <mmo-diff>, which mmo.editor does not depend on |
compare(revision)
PageEditor.js:764Show what changed between $revision and the draft, as json, side by side, in a dialog: the application's side panel is too narrow for two versions, and under the editor's drawer.
| revision | Object | - {number, version: {title, layout, seo, sections}}, from revisions.json?full=1 |
rollback(number)
asyncPageEditor.js:780| number |
LanguageCode(code)
staticPageEditor.js:803| code | ||
| retourne | ?string | $code as a page keeps it: --separated, lowercase -- null when it is no language tag |
languageName(code)
PageEditor.js:809| code | ||
| retourne | string | the name of the language $code, in the user's language |
translatable(field, key, parent)
PageEditor.js:821| field | Object | - a field's schema |
| key = null | ?string | - its name |
| parent = null | ?Object | - the schema of the object holding it |
| retourne | ?string | what a translation does with it: text (translated), object and list (their fields may be), null (the same in every language) -- the server's rules (Translations::Kind()): change both together |
filled(value)
PageEditor.js:835| value | ||
| retourne | boolean | whether $value is a text that says something: not empty, nor a markup holding nothing |
merge(field, base, translation, kind)
PageEditor.js:840| field | ||
| base | ||
| translation | ||
| kind = 'object' | ||
| retourne | * | $base (a field's value in the default language) with the texts of $translation where it has them |
extract(field, value, base, kind)
PageEditor.js:859| field | ||
| value | ||
| base | ||
| kind = 'object' | ||
| retourne | * | what a translation keeps of $value (a field's, in a language): its texts that differ from $base's; null, none |
untranslated(field, base, translation, kind, path, labels, found)
PageEditor.js:884[internal] The texts of $base (a field's value in the default language) that $translation does not translate
| field | ||
| base | ||
| translation | ||
| kind | ||
| path | ||
| labels | ||
| found |
translationOf(draft, language)
PageEditor.js:908| draft | Object | - draft |
| language | string | - one of its languages but the default one |
| retourne | missing: Array<{path: string, labels: Array<string>, section: ?number | >, total: number}} the texts of the draft $language does not translate, and how many texts it has |
draft()
PageEditor.js:933| retourne | slug: string, title: string, layout: string, seo: Object, sections: Array<Object>, languages: Array<string>, translations: Object | } the draft as the api takes it: in its default language, and its translations -- the language shown's taken from the form (extractShown) |
extractShown()
PageEditor.js:945[internal] @return {?Object} the translation of the language shown: what its texts say that the default language's do not
showLanguage(draft)
PageEditor.js:964[internal] Put $draft (draft) in the form, in the language shown: its texts translated, the default language's where they are not
| draft |
setLanguage(language)
PageEditor.js:985Show the page in $language (one of its languages; null or the default one: the default one)
| language |
baseValue(path)
PageEditor.js:1000| path | ||
| retourne | * | the value at $path (the form's: sections/0/data/title, seo/title) in the default language |
renderLanguages()
PageEditor.js:1010[internal] The bar's language, the notice of the language shown, the drawer's languages when it shows them
renderLanguagesPanel()
PageEditor.js:1031[internal] The drawer's languages: the default one, the others -- each with what it does not translate yet, a link to each field -- and adding one
valueAt(draft, path)
PageEditor.js:1078| draft | ||
| path | ||
| retourne | * | the value at $path in $draft (draft) |
excerpt(value, length)
PageEditor.js:1083| value | ||
| length = 60 | ||
| retourne | string | the beginning of a text (html or not), to recognise it |
addLanguage(code, defaultLanguage)
PageEditor.js:1092Add the language $code to the page ($defaultLanguage its default one, when it had none), and show it
| code | ||
| defaultLanguage |
removeLanguage(code)
asyncPageEditor.js:1107Take $code out of the page's languages: its translation goes with it (it can be undone)
| code |
setDefaultLanguage(code)
PageEditor.js:1121The page's texts are in $code: what its default language is called (nothing is translated)
| code |
goToField(language, path)
PageEditor.js:1132Open the field $path (the form's data-path) in $language, to translate it
| language | ||
| path |
visible(field)
PageEditor.js:1166| field | ||
| retourne | boolean | whether $field (or a type) is shown at the level |
defaults(schema)
PageEditor.js:1171| schema | ||
| retourne | * | the default value of $schema (its default, or its fields' for an object) |
translateExample(value, schema)
PageEditor.js:1190| value | * | - an example of a schema (its default), in English |
| schema | Object | - its field's |
| retourne | * | the example in the user's language: its texts translated (MMO.i18n), but a choice (enum) and an address, which the page needs as they are |
newSection(type)
PageEditor.js:1202| type | ||
| retourne | type: string, data: Object | } a section of $type, with its defaults (its id is the server's to make) |
indexOf(id)
PageEditor.js:1207| id | ||
| retourne | number | the index of the section $id in the draft, -1 if it has none |
addSection(type, after)
PageEditor.js:1212Add a section of $type, after the section $after (at the end without it)
| type | ||
| after = null |
moveSection(i, to)
PageEditor.js:1225| i | ||
| to |
copySection(i)
PageEditor.js:1233| i |
deleteSection(i)
PageEditor.js:1247| i |
fieldInput(field, obj, key, path)
PageEditor.js:1263| field | Object | - its schema |
| obj | Object | - what holds its value |
| key | string | - its key in obj |
| path | string | - its path, as the api's errors name it (sections/0/data/title) |
| retourne | HTMLElement | the input of a field, writing into obj[key] |
imageInput(field, obj, key, path)
PageEditor.js:1320[internal] @return {Array<HTMLElement>} an image: its address, a file sent to mmo.edms, its description
| field | ||
| obj | ||
| key | ||
| path |
listInput(field, obj, key, path)
PageEditor.js:1346[internal] @return {HTMLElement} a list of items: each its fields, moved, removed, added
| field | ||
| obj | ||
| key | ||
| path |
renderPageFields()
PageEditor.js:1362renderSections()
PageEditor.js:1374sectionCard(section, i, alone)
PageEditor.js:1388| section | Object | |
| i | number | - its index in the draft |
| alone = false | boolean | - in the drawer: open, its tools alone |
| retourne | HTMLElement | the form of a section: its fields, and tools to move, copy, remove it |
showErrors(errors)
PageEditor.js:1407Show what the api says is wrong: in a list, and next to each field (the closest one the form has)
| errors |
preview(version, label)
PageEditor.js:1444Render $version (the draft by default) in the preview, a moment after the last change
| version = null | ?Object | - {title, layout, seo, sections} |
| label = null | ?string | - what it is |
showPreview(html, expert)
PageEditor.js:1472[internal] $html in the preview: its addresses resolved from this page, its sections clickable
| html | ||
| expert |
hookPreview(scroll, expert, tries)
PageEditor.js:1488[internal] Once the preview's document is parsed (its load may never come: a request of the page staying open): a click on a section opens its form; at the expert level, the edits in place go into the draft
| scroll = 0 | ||
| expert = false | ||
| tries = 60 |
setFromPreview(path, html, region)
PageEditor.js:1526Write what the expert level edited in place into the draft
| path | string | - the field's data-path: sections.{id}.data.{key}[.{index}.{key}…] |
| html | string | - the region's html (MMO.editor.sanitize) |
| region | Element | - the region, whose text a plain text field takes |
sectionTools(doc)
PageEditor.js:1548[internal] The toolbar of the section under the pointer, in the preview: move, copy, remove, add one after it
| doc |
select(id, scroll)
PageEditor.js:1600Select the section $id: framed in the preview, its form opened
| id | ||
| scroll = true |
resize(button, width)
PageEditor.js:1616The preview's width: a desktop's, a tablet's, a phone's
| button | ||
| width |