DOM and i18n helpers¶
The browser is an operating system, and its DOM is where a GUI gclass draws. These helpers build the elements and keep the untrusted values safe.
Source code: src/helpers.js
Build an element¶
createElement2()¶
Builds an HTML element from a description that is a plain array. It is the function that a GUI gclass uses to draw.
createElement2(description, translate_fn)Parameters
| Key | Type | Description |
|---|---|---|
description | array | The element, as [tag, attrs, content, events]. |
translate_fn | function | The translation function. The attribute i18n uses it. |
Returns
The element that the function built.
The four slots
| Slot | Type | Description |
|---|---|---|
tag | string | The name of the element. |
attrs | object | The attributes. style accepts a string or an object. i18n gives the content through translate_fn. |
content | string or array | The text, one child, or a list of children. |
events | object | The listeners, as {event: function}. |
// Data in the third slot: a Text node
['span', {class: 'HOST_NAME'}, document.createTextNode(host)]
// Data in a list of children (gobj-js 7.26.2+): a string is text
['p', {}, [['b', {}, 'Host: '], host]]['div', { class: 'window-top', style: 'border-bottom: 1px solid black;' },
[
['span', {}, 'title'],
['button', {}, 'Close', {
click: (e) => {
e.target.closest('.window').remove();
}
}]
]
]The style attribute accepts both forms:
['span', {style: {position: 'absolute'} }, 'title']html_markup(html)¶
Marks a string as markup for createElement2(), said out loud: the string
is the caller’s own (an icon, an svg), never data. It works in the third slot
and in a list of children, in any mode, and keeps every node of the string
(since gobj-js 7.26.3).
['span', {class: 'icon'}, html_markup('<i class="yi-copy"></i>')]
['div', {}, [['b', {}, 'Saved'], html_markup('<i class="yi-check"></i>')]]Turned into a string (String(m), a template, +), the value gives its html
back, so code that still builds innerHTML keeps working. The string that comes
out is a plain string again, and it is not marked: never add data to it. In
createElement2() with set_strings_are_text(true) that string is text, and
it is logged when it starts with <.
$el.innerHTML = `${html_markup('<i class="yi-check"></i>')}`; // works
['span', {}, `${html_markup('<b>')}${name}`] // text, and loggedis_html_markup(v)¶
Tells whether v is a value that html_markup() returned.
is_html_markup(html_markup('<b>x</b>')); // true
is_html_markup('<b>x</b>'); // falseset_strings_are_text(on)¶
Sets how createElement2() reads a plain string that starts with <. With
false (the default) the string is markup, as it always was. With true it is
text, and html_markup() is the only way to insert markup. In that mode a
string that starts with < is logged once with a warning: it is a deliberate
markup that was not migrated, or a datum that used to run as HTML.
An app turns the mode on at startup, after its own code and the libraries it
mounts pass all their markup through html_markup(). Since 7.26.10 gobj-ui
passes its markup that way, and the check
node node_modules/@yuneta/gobj-ui/scripts/check-markup-strings.mjs src (published with gobj-ui 7.26.11+) finds the literal cases in an app.
import {set_strings_are_text} from "@yuneta/gobj-js";
set_strings_are_text(true);
createElement2(['span', {}, '<img src=x onerror=alert(1)>']); // text, logged oncestrings_are_text()¶
Returns the mode that set_strings_are_text() set.
if(!strings_are_text()) {
log_warning("this app still reads '<' strings as markup");
}createOneHtml(htmlString)¶
Builds one element from a string of HTML.
parseSVG(string)¶
Builds an SVG element from a string of SVG code.
getPositionRelativeToBody(element)¶
Gives the position of an element against the body of the document. A popover or a menu that must stay next to its button uses it.
Untrusted values¶
escapeHtml(str)¶
Escapes a value for an HTML context. Use it every time that a string from a
user or from a server goes into a template that becomes innerHTML.
safeSrc(url)¶
Validates a URL for the src attribute of an image or a media element. It
refuses the javascript: and data: schemes, which carry a cross-site script.
It gives an empty string back for every scheme that it refuses.
Language¶
refresh_language()¶
Translates a DOM tree again, after the application changes its language.
refresh_language(element, t)Parameters
| Key | Type | Description |
|---|---|---|
element | Element | The root of the tree. With an empty value the function takes the whole document. |
t | function | The translation function, such as the t of i18next. |
What the function translates
It reads four attributes, and each one carries the key of its own text.
| Attribute | What it translates |
|---|---|
data-i18n | The first text node of the element. |
data-i18n-title | The title attribute, which is the tooltip. |
data-i18n-aria-label | The aria-label attribute, which a screen reader reads. |
data-i18n-placeholder | The placeholder attribute of an input or a text area. |