minimessage-js
TypeScript icon, indicating that this package has built-in type declarations

1.1.3 • Public • Published

minimessage-js

GitHub Actions Workflow Status GitHub Issues or Pull Requests Website npm bundle size

Online DemoNPMGitHubSpec

Demo GIF

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:

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 #000000
dark_blue #0000aa #0000aa
dark_green #00aa00 #00aa00
dark_aqua #00aaaa #00aaaa
dark_red #aa0000 #aa0000
dark_purple #aa00aa #aa00aa
gold #ffaa00 #ffaa00
gray #aaaaaa #aaaaaa
dark_gray #555555 #555555
blue #5555ff #5555ff
green #55ff55 #55ff55
aqua #55ffff #55ffff
red #ff5555 #ff5555
light_purple #ff55ff #ff55ff
yellow #ffff55 #ffff55
white #ffffff #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 Components 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.

Package Sidebar

Install

npm i minimessage-js

Weekly Downloads

69

Version

1.1.3

License

Apache-2.0

Unpacked Size

402 kB

Total Files

71

Last publish

Collaborators

  • wasabithumbs