diff --git a/documentation/tutorial/01-getting-started.md b/documentation/tutorial/01-getting-started.md deleted file mode 100644 index ed208c9505377a3318913e3ff1159f97e03ec8c6..0000000000000000000000000000000000000000 --- a/documentation/tutorial/01-getting-started.md +++ /dev/null @@ -1,73 +0,0 @@ -You'll need basic HTML, CSS, and JavaScript skills for Monster. If you're just -starting out with frontend development, you should have a good beginner's -guide open alongside this one. - -You can also post your questions on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=javascript,monster). - -To get started with Monster, all you need is a text editor and a browser. -The best way is to copy the following example into a file and save it as -index.html. - -``` -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="utf-8"> - <title>awaken the monster in you!</title> -</head> -<body> - -<div>your version is - <spay id="version"></spay> -</div> - -<script type="module"> - import {Version} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/types/version.js'; - document.getElementById('version').innerText = new Version('1.0.0').toString(); -</script> - -</body> -</html> -``` - -Now open this file with your browser. - -What did you do? you used the class 'Version' of monster and created a Version object. They then output this in a span. - -**Voila!** - -As seen above in the version example, each monster class or function can be used independently. -Alternatively, Monster can be used as a collection of many useful classes and functions via -the `Monster` namespace as a single javascript file. - -``` -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="utf-8"> - <title>awaken the monster in you!</title> - <script src="https://cdn.skypack.dev/@schukai/monster@latest/source/monster.js"></script> -</head> -<body> - -<div>your version is - <spay id="version"></spay> -</div> - -<script> - document.getElementById('version').innerText = new Monster.Types.Version('1.0.0').toString(); -</script> - -</body> -</html> -``` - -Besides the CDN [jsdelivr](https://www.jsdelivr.com/package/npm/@schukai/monster), -[skypack](https://cdn.skypack.dev/@schukai/monster@latest), -Monster can also be obtained via [NPM](https://www.npmjs.com/package/@schukai/monster) -or the [git repos](https://gitlab.schukai.com/oss/libraries/javascript/monster). - -Monster itself has no dependencies and does not dictate anything to you, -you can use Monster with Bootstrap, jQuery or other cool frameworks. - - diff --git a/documentation/tutorial/02-what-is-monster.md b/documentation/tutorial/02-what-is-monster.md deleted file mode 100644 index 5d1fb134ac40e28ec5d37d83fbba4ab130f7dcda..0000000000000000000000000000000000000000 --- a/documentation/tutorial/02-what-is-monster.md +++ /dev/null @@ -1,21 +0,0 @@ -Monster is a lightweight, robust and easy-to-use library with modest ambitions. -Monster integrates easily with your existing websites without taking over everything. - -Here's ({@tutorial what-is-monster}) what Monster is all about. In section {@tutorial getting-started} -you can read how to integrate Monster into your own web projects. - -Monster has a free license and therefore you are free to customize Monster to your needs. - -Monster is a collection of functions and classes that can help in the daily work -with Javascript to get faster to the goal. Monster does not require you to be the -only library, nor does it require you to use only Monster. - -Monster itself has no dependencies and works perfectly with other frameworks -like jQuery or Bootstrap. - -**The design goals of Monster's core library are:** - -* Easy integration with existing user interfaces. -* Robust interfaces -* Tested code and good code coverage. -* No dependencies on other libraries \ No newline at end of file diff --git a/documentation/tutorial/03-dom.md b/documentation/tutorial/03-dom.md deleted file mode 100644 index a7c5f55a080e34c1431f283f273a7af806ae77c0..0000000000000000000000000000000000000000 --- a/documentation/tutorial/03-dom.md +++ /dev/null @@ -1,5 +0,0 @@ -The DOM classes, functions and constants help to perform various tasks in the browser. - -Among other things, the [form components](https://monsterjs.org/en/doc/components/form/latest/) were -developed on the basis of this functionality. - | diff --git a/documentation/tutorial/04-i18n.md b/documentation/tutorial/04-i18n.md deleted file mode 100644 index 63b6c3ca5af7ff414a47e90d78a6ee491b887aab..0000000000000000000000000000000000000000 --- a/documentation/tutorial/04-i18n.md +++ /dev/null @@ -1,2 +0,0 @@ -The localization classes and functions support you in dealing with -translations and country-specific settings. \ No newline at end of file diff --git a/documentation/tutorial/09-browser-compatibility.md b/documentation/tutorial/09-browser-compatibility.md deleted file mode 100644 index 72b4f66361d88c3a70da419d88fba637af1717cd..0000000000000000000000000000000000000000 --- a/documentation/tutorial/09-browser-compatibility.md +++ /dev/null @@ -1,14 +0,0 @@ -In the monster library, we use current functions and objects for the implementation. -Some functions may not run on older runtimes. - -There are several ways to increase compatibility. - -One way is [Babel](https://babeljs.io/) and the `@babel/preset-env ` preset. - -More information about the browsers supported by Babel can be found in the [browserslist](https://github.com/browserslist/browserslist) project. - -## Polyfills - -A polyfill can be assembled using the [create-polyfill-service-url](https://www.npmjs.com/package/create-polyfill-service-url) tool. - - diff --git a/documentation/tutorial/assets/customelement-interaction.puml b/documentation/tutorial/assets/customelement-interaction.puml deleted file mode 100644 index 39fb824863070b898e55485cd787b6f5fdf8ce87..0000000000000000000000000000000000000000 --- a/documentation/tutorial/assets/customelement-interaction.puml +++ /dev/null @@ -1,79 +0,0 @@ -@startuml - -autonumber - -Script -> DOM: element = document.createElement('my-element') -create CustomElement - -DOM -> CustomElement: constructor() -activate CustomElement - -CustomElement -> CustomElement: [initMethodSymbol]() -create ProxyObserver -CustomElement -> ProxyObserver: new -activate CustomElement - -CustomElement -> CustomElement: [initMethodSymbol]() - - -CustomElement --> DOM: Element -DOM --> Script : element - - -Script -> DOM: document.querySelector('body').append(element) - -DOM -> CustomElement : connectedCallback() - -note right CustomElement: is only called at\nthe first connection -CustomElement -> CustomElement : [assembleMethodSymbol]() -activate CustomElement - -CustomElement -> CustomElement: initShadowRoot() -activate CustomElement - -CustomElement -> CustomElement: attachShadow() -CustomElement -> CustomElement: appendChild() -CustomElement --> CustomElement -deactivate CustomElement - -CustomElement -> CustomElement: initCSSStylesheet() - -create UpdaterSet -CustomElement -> UpdaterSet : new - -loop every element - create Updater - CustomElement -> Updater : new - CustomElement -> UpdaterSet:add(Updater) - CustomElement -> Updater : run -end - - - -CustomElement -> CustomElement: addObjectWithUpdaterToElement() -activate CustomElement - - -create MutationObserver -CustomElement -> MutationObserver: new -activate MutationObserver - -MutationObserver -> MutationObserver : observe - -MutationObserver --> CustomElement - -deactivate CustomElement -deactivate CustomElement -deactivate CustomElement -deactivate CustomElement -deactivate CustomElement - -... ... - -autonumber - -Script -> DOM: document.querySelector('monster-confirm-button').parentNode.removeChild(element) -DOM -> CustomElement: disconnectedCallback() - - -@enduml \ No newline at end of file diff --git a/documentation/tutorial/dom-based-templating-implementation.md b/documentation/tutorial/dom-based-templating-implementation.md deleted file mode 100644 index e6e6b62390c17b3e0f91867928b12949edea5712..0000000000000000000000000000000000000000 --- a/documentation/tutorial/dom-based-templating-implementation.md +++ /dev/null @@ -1,214 +0,0 @@ -Monster's updater uses a DOM-based approach. The configuration and the template system are valid and parsable HTML. - -The configuration is done via some special attributes with a `data-monster-` prefix. - -Code is always the most informative. So let's take a look at a complete example right away. - -``` -// The first thing to do is to include the Updater class. -import {Updater} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js'; - -// Now we prepare the html document. -// This is done here via script, but can also be inserted into the document as pure html. -// To do this, simply insert the tag <h1 data-monster-replace="path:headline"></h1>. -const body = document.querySelector('body'); -const headline = document.createElement('h1'); -headline.setAttribute('data-monster-replace','path:headline') -body.appendChild(headline); - -// the data structure -let obj = { - headline: "Go!", -}; - -// Now comes the real magic. we pass the updater the parent HTMLElement -// and the desired data structure. -const updater = new Updater(body, obj); - -// now we get the used data structure. why can't we take the original structure? -// the updater puts a proxy over the data structure and thus allows to monitor changes. -// We would not see changes to the original object. -const subject = updater.getSubject(); - -// now start the updater -updater.run(); - -// Now you can change the data structure and the HTML will follow these changes. -// to illustrate, let's put the change into a timer call. -setTimeout(function(){ - console.log(obj); - subject['headline'] = "Hello!" - -},1000); - -``` - -We have seen how we can change the content of an htm element. now let's look at what options are available. - -## Replace - -The simplest manipulation is to replace the content of a HTMLElement. -To do this, simply use the `data-monster-replace` attribute (see example). - -The syntax is quite simple. The result of the attribute pipe is inserted as content of the -HTMLElement. For the processing the [Pipe](Monster_Data.Pipe.html)<!-- @IGNORE PREVIOUS: link --> and [Transformer class](Monster_Data.Transformer.html)<!-- @IGNORE PREVIOUS: link --> -is used. - -If, for example, you have an object `x` with the structure listed below and want to insert the value of the key b, you write: `path:a.b`. - -The pipe can then be used to apply operators. For example, `tolower` can be used to convert everything to lowercase. - -``` -let x = { - a: { - b: "EXAMPLE" - } -} -``` - -this is how it looks as an attribute: - -``` -<div data-monster-replace="static:HELLO | tolower"></div> -``` - -The result is then the following html: - -``` -<div data-monster-replace="static:hello">hello</div> -``` - -A full example looks like this: - -``` -import {Updater} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js'; -const body = document.querySelector('body'); -const headline = document.createElement('h1'); -headline.setAttribute('data-monster-replace','static:hello') -body.appendChild(headline); -// result in ↦ <div data-monster-replace="static:hello"></div> - -new Updater(body).run(); -``` - -## Attributes - -Attributes can be added via the `data-monster-attributes` attribute. The syntax is attribute name followed by -a space and the desired pipe definition. - -``` -<div data-monster-attributes="id static:myid">hello</div> -``` - -The result is then the following html: - -``` -<div id="myid" data-monster-attributes="id static:myid">hello</div> -``` - -Multiple attributes can be separated by commas. - -``` -<div data-monster-attributes="id static:myid, class static:myclass">hello</div> -``` - -## Remove - -The `data-monster-remove` attribute can be used to remove html elements. it is important to -note that this cannot be undone. Once removed, nodes will not be reinserted. - -This tag is removed via the updater - -``` -<div data-monster-remove></div> -``` - -## Insert - -The strongest feature is adding elements to a node. - -For this feature you need a template and the `data-monster-insert` attribute. - -The syntax of the attribute is first an id followed by a space. This is then followed by the pipe command. - -``` -<ol data-monster-insert="myid path:a"></ol> -``` - -Furthermore, you need a template. The template must have the same string as id. - -``` -<template id="myid"> - <li data-monster-replace="path:myid | index:id | tostring | prefix:x"></li> -</template> -``` - -In this template, we define the structure of the new elements. In this case, the id is taken -from the dataset `index:id`, converted to a string `tostring`, and an x is placed in front of it `prefix:x`. - -The values for the corresponding data must be available as an array. - -``` -let obj = { - a: [ - {"id": 1}, - {"id": 2}, - {"id": 3}, - {"id": 4} - ] -}; -``` - -Below we have a complete example. Instead of specifying the template `<template />` in HTML, it is constructed via -javascript `document.createElement('template')`. But it is essentially the same. - -``` -const body = document.querySelector('body'); -const li = document.createElement('li'); -li.innerHTML="-/-"; -li.setAttribute('data-monster-replace','path:myid | index:id | tostring | prefix:x'); - -const template = document.createElement('template'); -template.setAttribute('id','myid'); -template.content.appendChild(li); - -body.appendChild(template); - -const list = document.createElement('ul'); -list.setAttribute('data-monster-insert', 'myid path:a') - -body.appendChild(list); - -let obj = { - a: [ - {"id": 1}, - {"id": 2}, - {"id": 3}, - {"id": 4} - ] -}; - -const updater = new Updater(body, obj) -updater.run(); -``` - -The result will be - -``` -<ul data-monster-insert="myid path:a"> - <li data-monster-replace="path:a.0 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-0">x1</li> - <li data-monster-replace="path:a.1 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-1">x2</li> - <li data-monster-replace="path:a.2 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-2">x3</li> - <li data-monster-replace="path:a.3 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-3">x4</li> -</ul> -``` - -You can easily add and delete values to the array. The DOM will be adjusted accordingly. -The attribute `data-monster-insert-reference` identifies if the entry already exists. - - - - - - - diff --git a/documentation/tutorial/dom-form-handling.md b/documentation/tutorial/dom-form-handling.md deleted file mode 100644 index 8c67ae9818feef8eda8f5b512102dfcd4d45a4df..0000000000000000000000000000000000000000 --- a/documentation/tutorial/dom-form-handling.md +++ /dev/null @@ -1,69 +0,0 @@ -Forms can be bound to a structure just like other structures via the updater class. - -Suppose we have an html form with some controls. - -``` -<div> - <form id="form1"> - <input type="checkbox" name="checkbox"> - <input type="text" name="text"> - <input type="radio" name="radio"> - - <select name="select"> - <option>value1</option> - <option>value2</option> - </select> - - <textarea name="textarea"> - </textarea> - - <input type="button" name="button"> - - </form> -</div> -``` - -A new updater is created in this case via the following call. - -``` -const updater = new Updater(document.getElementById('form1')); -``` - -With the method `Updater.getSubject()` you can get the structure of the updater. If you want to use an already defined structure, you can pass it to the updater as a second parameter. - -``` -let subject = updater.getSubject(); -console.log(subject); -``` - -Now we want a click on the checkbox to be mapped in the data structure. - -To do this we need to extend the html with the `data-monster-bind` attribute. - -The values or states of controls are mapped to the data structure via this binding. - - -``` -<div> - <form id="form1"> - <!-- data-monster-bind added --> - <input type="checkbox" name="checkbox" data-monster-bind="path:state"> - </form> -</div> -``` - -In this case the status of the checkbox is mapped to the key `state`. If the checkbox is selected the field `state` contains the value `on` , otherwise state is undefined. - -If you want to use another value instead of `on`, you can set the attribute `value`. - -``` -<input type="checkbox" name="checkbox" value="checked" data-monster-bind="path:state"> -``` - -To see the magic the handling must still be switched on. - -``` -updater.enableEventProcessing() -``` - -Voila! diff --git a/documentation/tutorial/form-example.html b/documentation/tutorial/form-example.html deleted file mode 100644 index 3feee950edf4601756e49dee7336b14b99f67627..0000000000000000000000000000000000000000 --- a/documentation/tutorial/form-example.html +++ /dev/null @@ -1,233 +0,0 @@ -<p> - On this page you will find a sample implementation for many HTML5 controls. The binding is set up in both - directions, so that a change to the control also causes a change to the values, and changes to the values cause a change to the - control. -</p> - -<p> - You can save the updater as a temporary variable in the console. In our case Chrome assigns the variable <code>temp1</code> to - the object. -</p> - -<p> - Note that instead of <code>temp1</code> you have to take the variable from your browser. -</p> - -<p> - And then access the data array using <code>temp1.getSubject().</code> -</p> - -<p> - For example, to enable the checkbox you can set <code>temp1.getSubject().value.checkbox="YES"</code>. To deactivate the checkbox - you have to remove the value <code>temp1.getSubject().value.checkbox=undefined</code> -</p> - -<p> - Note that you have to take the variable from your browser instead of temp1. -</p> - -<p> - At the bottom you will find the JSON with all values -</p> - -<h3>Examples</h3> - -<template id="example1"> - - <style> - - [readonly] { - background-color: #e9e9e9; - border: 1px solid grey; - } - - div { - box-sizing: border-box; - } - - .table { - display: grid; - grid-template-columns: 1fr 1fr 4fr; - } - - .cell.control { - padding: 5px 20px; - } - - .cell.value { - padding: 5px 20px; - } - - .json { - margin: 5px 20px; - padding: 20px; - border: 4px solid #424242; - margin-top: 20px - } - - </style> - - <div id="container"> - <div class="table"> - - <div class="cell control"><select type="input" data-monster-bind="path:value.multiple" multiple> - <option value="a" data-monster-attributes="selected path:value.multiple | call:checkstate">A - </option> - <option value="b" data-monster-attributes="selected path:value.multiple | call:checkstate">B - </option> - <option value="c" data-monster-attributes="selected path:value.multiple | call:checkstate">C - </option> - </select></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.multiple"></div> - <div class="cell code"></div> - <div class="cell control"><select type="input" data-monster-bind="path:value.select" - data-monster-attributes="value path:value.select"> - <option value="a">A</option> - <option value="b">B</option> - <option value="c">C</option> - </select></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.select"></div> - <div class="cell code"></div> - <div class="cell control"><input type="checkbox" data-monster-bind="path:value.checkbox" value="YES" - data-monster-attributes="checked path:value.checkbox | call:checkstate"> - </div> - <div class="cell value"><input id="my" readonly data-monster-attributes="value path:value.checkbox"></div> - <div class="cell code"></div> - <div class="cell control"><input type="search" name="search" data-monster-bind="path:value.search" - data-monster-attributes="value path:value.search"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.search"></div> - <div class="cell code"></div> - <div class="cell control"><input type="tel" name="tel" data-monster-bind="path:value.tel" - data-monster-attributes="value path:value.tel"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.tel"></div> - <div class="cell code"></div> - <div class="cell control"><input type="time" name="time" data-monster-bind="path:value.time" - data-monster-attributes="value path:value.time"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.time"></div> - <div class="cell code"></div> - <div class="cell control"><input type="url" name="url" data-monster-bind="path:value.url" - data-monster-attributes="value path:value.url"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.url"></div> - <div class="cell code"></div> - <div class="cell control"><input type="week" name="week" data-monster-bind="path:value.week" - data-monster-attributes="value path:value.week"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.week"></div> - <div class="cell code"></div> - <div class="cell control"><input type="color" name="color" data-monster-bind="path:value.color" - data-monster-attributes="value path:value.color"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.color"></div> - <div class="cell code"></div> - <div class="cell control"><input type="radio" name="doit" data-monster-bind="path:value.radio" value="2" - data-monster-attributes="checked path:value.radio | call:checkstate"><br> - <input type="radio" name="doit" data-monster-bind="path:value.radio" value="1" - data-monster-attributes="checked path:value.radio | call:checkstate"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.radio"></div> - <div class="cell code"></div> - <div class="cell control"><input type="range" name="range" data-monster-bind="path:value.range" - data-monster-attributes="value path:value.range"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.range"></div> - <div class="cell code"></div> - <div class="cell control"><input type="password" name="password" data-monster-bind="path:value.password" - data-monster-attributes="value path:value.password"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.password"></div> - <div class="cell code"></div> - <div class="cell control"> - <input type="number" name="number" data-monster-bind="path:value.number" - data-monster-attributes="value path:value.number"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.number"></div> - <div class="cell code"></div> - <div class="cell control"> - <input type="month" name="month" data-monster-bind="path:value.month" - data-monster-attributes="value path:value.month"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.month"></div> - <div class="cell code"></div> - <div class="cell control"><input type="email" name="email" data-monster-bind="path:value.email" - data-monster-attributes="value path:value.email"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.email"></div> - <div class="cell code"></div> - <div class="cell control"><input type="datetime-local" name="datetime-local" - data-monster-bind="path:value.datetime-local" - data-monster-attributes="value path:value.datetime-local"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.datetime-local"></div> - <div class="cell code"></div> - <div class="cell control"> - <input type="date" name="date" data-monster-bind="path:value.date" - data-monster-attributes="value path:value.date"></div> - <div class="cell value"><input readonly data-monster-attributes="value path:value.date"></div> - <div class="cell code"></div> - </div> - <div class="json" - data-monster-replace="path:value | tojson"></div> - - - </div> - -</template> - -<script src="https://monsterjs.org/vendor/prism.js"></script> -<link href="https://monsterjs.org/vendor/prism-coy.css" rel="stylesheet"/> - -<script type="module"> - - 'use strict'; - import {Updater} from "https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js"; - - document.addEventListener('readystatechange', () => { - if (document.readyState == 'complete') { - - let included = false; - - let example1 = document.getElementById('example1'); - let article = document.querySelector('article'); - if (article) { - article.appendChild(example1.content); - included = true; - } else { - // for local debug - document.body.appendChild(example1.content); - } - - document.querySelectorAll('div[class*=control]').forEach((element) => { - let col = element.nextElementSibling.nextElementSibling; - - let source = (element.innerHTML); - - let pre = document.createElement('pre'); - pre.setAttribute('class', 'prettyprint source') - let code = document.createElement('code'); - - col.appendChild(pre); - pre.appendChild(code); - - source = Prism.highlight(source, Prism.languages.html, 'html'); - - - code.innerHTML = source - - }) - - - const container = document.getElementById('container'); - - const updater = new Updater(container, { - value: { - input: "Init Value - input", - textarea: "Init Value - textarea", - file: "Init Value - file", - checkbox: "Init Value - checkbox", - radio: "Init Value - radio", - multiple: ['a', 'c'] - } - }); - - updater.run(); - updater.enableEventProcessing(); - console.log(updater); - - - } - - }); - - -</script> diff --git a/documentation/tutorial/how-to-write-a-customcontrol.md b/documentation/tutorial/how-to-write-a-customcontrol.md deleted file mode 100644 index c799e928d4a515cf74bc77b0245e095284c65753..0000000000000000000000000000000000000000 --- a/documentation/tutorial/how-to-write-a-customcontrol.md +++ /dev/null @@ -1,169 +0,0 @@ -In diesem Artikel geht es um das Erstellen einer eigenen -[Web Komponente](https://developer.mozilla.org/en-US/docs/Web/Web_Components). - -Mit Hilfe von Klassen und Funktionen von [Monster](https://monsterjs.org) - -Zuerst erstellen wir eine von `CustomControl` abgeleitete Klasse. Die Elternklasse -`CustomControl` implementiert bereits einige Funktionen, die das Leben im folgenden -leichter machen. - -``` -class Button extends CustomControl { -} -``` - -Der nächste Schritt legt fest, welchen Tag das Control im HTML bekommen soll. - -``` -class Button extends CustomControl { - static getTag() { - return "monster-button"; - - } -} -``` - -Damit man später das Control konfigurieren kann, müssen wir die Möglichkeit, -Optionen anlegen zu können, schaffen. Wir können hier auf die Strukturen der Klasse -`CustomControl` aufsetzen und brauchen nur ein eigenes Property `default` anzulegen. - -``` -class Button extends CustomControl { - - // ..... other implementations - - get defaults() { - return Object.assign({}, super.defaults, {}) - } - -} -``` - -Über diese Struktur werden auch die Templates des Controls definiert. So kann man -dem Control ein Standard mitgeben und dem Anwender des Controls die Möglichkeit geben -die Templates anzupassen. - -Jetzt machen wir uns also an das Aussehen des Controls und erstellen dazu ein Template. -Wir wollen das der Button einen einfachen HTML5-Button verwendet. - -``` -<button>Hello!</button> -``` - -Das Haupttemplate des Buttons wird über die Option `templates.main` gepflegt. - -Wir müssen das HTML also in die oben eingeführte `default` Struktur einfügen. Wir können -das HTML direkt hier angeben. - -``` -return Object.assign({}, super.defaults, { - templates: { - main: `<button>Hello!</button>` - }, -}) -``` - -Um die Übersicht bei größerne Templates zu behalten, kann man alternativ das -Template auch in eine Funktion auslagern und hier nur die Funktion aufrufen. - -``` -return Object.assign({}, super.defaults, { - templates: { - main: getTemplate() - }, -}) -``` - -Wenn wir jetzt den HTML-Tag `<monster-button></monster-button>` in eine HTML-Datei einfügen -erhalten wir soweit so unspektakulär einen Button. - - - -Jetzt kommt die Magie. Im DOM gibt es zwei wichtige Methoden, die beim Einbinden und -beim Entfernen eines Controls aufgerufen werden. - -Wird ein Control in das DOM eingehängt, so wird die Methode -[`connectedCallback`](https://developer.mozilla.org/de/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks) aufgerufen. - -Beim Entfernen eines Controls aus dem DOM wird dagegen die Methode -[`disconnectedCallback`](https://developer.mozilla.org/de/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks) aufgerufen. -aufgerufen. - -Wir implementieren die beiden Methoden in unserer neuen Klasse. - -``` -class Button extends CustomControl { - - // ..... other implementations - - connectedCallback() { - super.connectedCallback(); - } - - disconnectedCallback() { - super.disconnectedCallback(); - } -} -``` - -Innerhalb dieser beiden Methoden können wir nun zum Beispiel Strukturen initailisieren oder -Eventhandler hinzufügen und wieder entfernen. - -Das `CustomControl` besitzt zwei weitere wichtige Methoden, die -man überschreiben kann, um das Control zu initialisieren. Diese beiden Methoden -haben keinen direkten Methodennamen, sondern verbergen sich hinter einem -Symbol-Schlüssel. - -``` - -import { - assembleMethodSymbol, - initMethodSymbol, -} from "@schukai/monster/dist/modules/dom/customelement.js"; - -class Button extends CustomControl { - - // ..... other implementations - - [initMethodSymbol]() { - super[initMethodSymbol](); - } - - [assembleMethodSymbol]() { - super[assembleMethodSymbol](); - } -} -``` - -Die Methode `[initMethodSymbol]()` wird direkt vom Konstruktor aufgerufen und dient zur einmaliegen initialisierung -interner Strukturen. - -Die Methode `[assembleMethodSymbol]()` wird beim ersten einbinden des Kontrols in das -DOM aufgerufen. Wird das Control wieder entfernt und erneut eingebunden, so wird -`[assembleMethodSymbol]()` nicht nochmal aufgerufen. - -@startuml filename2.png -Alice --> Bob -@enduml - - - - - - - - - - - - - - - - - - - - - - diff --git a/documentation/tutorial/i18n-locale-and-formatter.md b/documentation/tutorial/i18n-locale-and-formatter.md deleted file mode 100644 index acd0c64ae95dc7042c61a7a978e20361e3c028cb..0000000000000000000000000000000000000000 --- a/documentation/tutorial/i18n-locale-and-formatter.md +++ /dev/null @@ -1,109 +0,0 @@ -We need the `Formatter` and `Translations` class and the `parseLocale()` function to handle translations. -In the context of the DOM we can also use the `getLocaleOfDocument()` method. - -``` -import {Translations} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/i18n/translations.js'; -import {Formatter} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/text/formatter.js'; -import {parseLocale} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/i18n/locale.js'; -import {getLocaleOfDocument} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/dom/locale.js'; -``` - -Let's start with the function `parseLocale()`. This function can create a `Locale` object from a string. - -So we can create the corresponding `Locale` object from the string `en_GB`. - - -``` -const locale = parseLocale('en_GB') -// ↦ Locale {} -``` - -If we move in the browser, so we can also use the function `getLocaleOfDocument()`. -This function returns a locale object as a result. - -This function looks if the HTML tag `<html lang="en">` has a lang attribute. -If no locale is defined, the default value is assumed to be `en`. - -We now need an object with the translations. For this we use the `Translations` class. - -We can either define the translations ourselves or load them via an API. - -``` -// define translations -const translation = new Translations(parseLocale('en-GB')); -translation.assignTranslations({ - text1: 'hello world!', - text2: { - 'one': 'click once', - 'other': 'click ${n | tostring} times' // this is where the pipe comes in - } - }); - -// fetch from API -const translation = new Fetch('https://example.com/${language}.json').getTranslation('en-GB'); -// ↦ https://example.com/en.json -``` - -If we now have a translation, we can now read the desired strings. For this -we use the method `Translation.getText()` or the method `Translation.getPluralRuleText()` -for texts with more than one number. - -``` -const message = translation.getText('text1'); -// -> hello world -``` - -To translate texts with number references, enter the desired number. - -``` -let n=1; -const message1 = translation.getPluralRuleText('text2', n); -// -> click once - -n=2 -const message2 = translation.getPluralRuleText('text2', n); -// -> click ${n} times -``` - -To replace the placeholder now, the formatter is used. - -``` -const text = new Formatter({n}).format(message2); -console.log(text) -// ↦ click 2 times -``` - -Finally, let's take a look at the formatter class from the i18n module. - -``` -import {Formatter} from - 'https://cdn.skypack.dev/@schukai/monster@latest/source/i18n/formatter.js'; -``` - -A tranlate object can be passed directly to this class. - -There is also the possibility to pass values in the format string. - - -``` -// define translation -const translations = new Translations('en') - .assignTranslations({ - // text with placeholder - message: "${animal} has eaten the ${food}!" - }); - -// without marker and inline values -new Formatter({}, translations).format("message::animal=dog::food=cake") -// ↦ dog has eaten the cake! -``` - - -Voila! - - - - - - - diff --git a/documentation/tutorial/images/button1.png b/documentation/tutorial/images/button1.png deleted file mode 100644 index 85ea3a394d470d0c70e7d2585cd34a76aea03c0d..0000000000000000000000000000000000000000 Binary files a/documentation/tutorial/images/button1.png and /dev/null differ diff --git a/documentation/tutorial/tutorials.json b/documentation/tutorial/tutorials.json index 00375446f2764b1ed18f97e9fa8a647523cd960e..0e0dcd235c4973becf25f38eb4e5bb26e154c86a 100644 --- a/documentation/tutorial/tutorials.json +++ b/documentation/tutorial/tutorials.json @@ -1,36 +1,3 @@ { - "01-getting-started": { - "title": "Getting Started" - }, - "02-what-is-monster": { - "title": "What is Monster?" - }, - "03-dom": { - "title": "DOM", - "children": { - "dom-form-handling": { - "title": "Form handling" - }, - "form-example": { - "title": "Form examples" - }, - "dom-based-templating-implementation": { - "title": "DOM-based templating implementation" - }, - "how-to-write-a-customcontrol": { - "title": "How to write a CustomControl" - } - } - }, - "04-i18n": { - "title": "Internationalization", - "children": { - "i18n-locale-and-formatter": { - "title": "Locale & Formatter" - } - } - }, - "09-browser-compatibility": { - "title": "Browser compatibility" - } + } \ No newline at end of file