minimessage-js
v1.1.3
Published
Lenient MiniMessage parser and HTML serializer made in TypeScript
Downloads
80
Maintainers
Readme
minimessage-js
Online Demo • NPM • GitHub • Spec
A deserializer mirroring the MiniMessage API, combined with an HTML renderer, in pure JS. Compare to minimessage-2-html, which works by sending web requests to the official webui.
Usage
NodeJS
// es6
import MiniMessage from "minimessage-js";
// cjs
const MiniMessage = require("minimessage-js");
const component = MiniMessage
.miniMessage()
.deserialize(`<rainbow>hello world!</rainbow>`);
component.getProperty("extra");
// [ { text: "h", color: "#ff0000" }, ... ]
const htmlCode = MiniMessage
.toHTML(component);
// string containing HTML code
The API is also designed to be able to theoretically support DOM polyfills like JSDOM:
const { JSDOM } = require("jsdom");
const dom = new JSDOM();
const output = dom.document.createElement("p");
MiniMessage.toHTML(component, output, (tag) => dom.document.createElement(tag));
Browser
This package includes a browser build. Add minimessage.min.js
to your document, and
MiniMessage
will be exposed as a global variable. Then the library can be used like
NodeJS.
<script src="https://unpkg.com/minimessage-js@^1.1"></script>
<p id="out"></p>
<script>
const component = MiniMessage
.miniMessage()
.deserialize('<rainbow>hello world!</rainbow>');
MiniMessage.toHTML(
component,
document.querySelector("#out")
); // also returns the HTML code as a string
</script>
Translations
Translations can be registered, which will take effect when rendering to HTML. You can add your own translations or optionally require the vanilla translations:
- @minimessage-js/translations : Contains JSON of all Vanilla translations (huge)
- @minimessage-js/fetch-translations : Contains methods to fetch translations from the Mojang API at runtime
const MiniMessageTranslations =
require("@minimessage-js/translations");
const mm = MiniMessage.builder()
// Add American English translations
.translations(
MiniMessageTranslations.get("en-us")
)
// Add custom translations
.translations({ "greeting": "Hello %s!" })
.build();
const component = mm.deserialize("<lang:greeting:Paul> You are " +
"holding a <lang:block.minecraft.diamond_block>!");
const html = MiniMessage.toHTML(component);
/*
<span>
<span data-mm-translate="greeting" data-mm-with="[\"Paul\"]">
Hello Paul!
</span>
<span> You are holding a </span>
<span data-mm-translate="block.minecraft.diamond_block">
Block of Diamond
</span>
<span>!</span>
</span>
*/
HTML Rendering
As mentioned above, this package has an extra method not found in the original API:
MiniMessage.toHTML
. This converts the parsed Component object into nested <span>
tags,
wtih attributes set to apply the Component data. You can also pass an HTMLElement
, which will
receive the tags in a way that may be more efficient than setting it through innerHTML
. This also will
cause obfuscated text to render properly. Here is an overview of how the implemented
properties parse to HTML:
Color
style="color: #XXXXXX"
is set on the target <span>
. This also supports color literals
through the following conversion:
| Key | Color | Hex Code |
| :--------------: | :------------------------------------------------------: | :---------: |
| black
| | #000000
|
| dark_blue
| | #0000aa
|
| dark_green
| | #00aa00
|
| dark_aqua
| | #00aaaa
|
| dark_red
| | #aa0000
|
| dark_purple
| | #aa00aa
|
| gold
| | #ffaa00
|
| gray
| | #aaaaaa
|
| dark_gray
| | #555555
|
| blue
| | #5555ff
|
| green
| | #55ff55
|
| aqua
| | #55ffff
|
| red
| | #ff5555
|
| light_purple
| | #ff55ff
|
| yellow
| | #ffff55
|
| white
| | #ffffff
|
Decorations (except obfuscated)
A CSS style declaration property: value;
is added to the target <span>
's style attribute.
| Name | Declaration |
| :---------------: | :-------------------------------: |
| bold
| font-weight: bold
|
| italic
| font-style: italic
|
| underlined
| text-decoration: underline
|
| strikethrough
| text-decoration: line-through
|
MiniMessage also allows for decoration inversions, e.g. <!bold>
or <u:false>
. In this case,
the appropriate property is set to normal
or none
only if it was previously set in a higher
enclosure.
Obfuscation
The property data-mm-obfuscted
is set to true
on the <span>
. If outputting to an HTMLElement
,
using in browser, the element is connected to the DOM, and 1 animation frame has ocurred, the
content of the <span>
is converted into <canvas>
elements which will render the obfuscation effect.
Everything Else
Remaining properties propertyName
will have data-mm-property-name
set to a JSON string containing the value of the property
if one is set. Examples:
| Property | HTML Attribute | Example Value |
| :----------------------------------------------------------------------------: | :-----------------: | :------------------------------------------------------: |
| clickEvent
* | data-mm-click-event | { "action": "suggest_command", "value": "/kill @s" }
|
| hoverEvent
* | data-mm-hover-event | { "action": "show_text", "contents": "hello!" }
|
| keybind
* | data-mm-keybind | "key.jump"
|
| translate
* | data-mm-translate | "block.minecraft.diamond_block"
|
| with
(for translate
) | data-mm-with | ["<red>1", "<blue>Stone!"]
|
| selector
* | data-mm-selector | "@s"
|
| score
* | data-mm-score | { "name": "@s", "objective": "kills" }
|
| insertion
* | data-mm-insertion | "some text"
|
| font
* | data-mm-font | "uniform"
|
| nbt
* | data-mm-nbt | "entity"
|
| block
(for nbt
= "block"
) | data-mm-block | unknown (help wanted) |
| entity
(for nbt
= "entity"
) | data-mm-entity | "@s"
|
| storage
(for nbt
= "storage"
) | data-mm-storage | unknown (help wanted) |
| interpret
(for nbt
) | data-mm-interpret | false
|
| separator
(for nbt
) | data-mm-separator | ","
|
Does it work?
minimessage-js
uses output from the official WebUI to validate test cases. Over all implemented
tags, no instance has been found where the 2 outputs do not fuzzy match. The main differences
are:
- This library always hex-ifies color literals, e.g.
red
->#ff5555
, whereas MiniMessage tends to keep color literals unconverted. - This library sometimes may not include the
text
property on empty Components, whereas MiniMessage tends to add an empty string.
What's missing?
Currently, there is no MiniMessageInstance.serialize
. Since there is no way to create Component
s
directly, it doesn't make much sense to include.
License
Copyright 2024 Wasabi Codes
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.