2018-05-22 10:28:17 +02:00

3080 lines
96 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class SystemSettings {
static setBasePath(basePath)
{
SystemSettings._basePath = basePath;
}
static getBasePath()
{
return SystemSettings._basePath;
}
}
SystemSettings.setBasePath("/");
class MenuAction {
constructor(title, callback, showFor, order) {
this.title = Helper.nonNull(title, null);
this.callback = callback;
this.showFor = Helper.nonNull(showFor, MenuAction.SHOW_FOR_MEDIUM);
this.order = Helper.nonNull(order, 1000);
this._menu = null;
this._activated = true;
this._visible = true;
this.id = MenuAction.maxId++;
this._icon = null;
this._shouldTranslate = true;
this._copies = [];
}
setTitle(title)
{
this.title = title;
}
setShouldTranslate(shouldTranslate)
{
this._shouldTranslate = shouldTranslate;
}
getTitle()
{
return this.title;
}
getShouldTranslate()
{
return this._shouldTranslate;
}
remove(removeCopies) {
removeCopies = Helper.nonNull(removeCopies, false);
if (Helper.isNotNull(this._menu)) {
console.log(this._menu);
this._menu.removeAction(this);
this._menu = null;
}
if (removeCopies)
{
for (let i = 0, n = this._copies.length; i < n; i++) {
this._copies[i].remove();
}
}
}
getMenu() {
return this._menu;
}
setMenu(value) {
this._menu = value;
}
getVisible() {
return this._visible;
}
setVisible(value) {
if (value !== this._visible) {
this._visible = value;
this.redraw();
}
}
getActivated() {
return this._activated;
}
getIcon() {
return this._icon;
}
setIcon(value) {
this._icon = value;
}
getId()
{
return this.id;
}
redraw() {
if (Helper.isNotNull(this._menu)) {
this._menu.updateAction(this);
}
}
copy(instance){
let copy = Helper.nonNull(instance, new MenuAction());
copy.title = this.title;
copy.callback = this.callback;
copy.showFor = this.showFor;
copy.order = this.order;
copy._activated = this._activated;
copy._visible = this._visible;
copy._icon = this._icon;
copy._shouldTranslate = this._shouldTranslate;
copy._menu = null;
copy.id = MenuAction.maxId++;
this._copies.push(copy);
return copy;
}
redrawMenu()
{
if (Helper.isNotNull(this._menu)) {
this._menu.redraw();
}
}
}
MenuAction.maxId = 0;
MenuAction.SHOW_ALWAYS = "always";
MenuAction.SHOW_FOR_MEDIUM = "medium";
MenuAction.SHOW_FOR_LARGE = "large";
MenuAction.SHOW_NEVER = "never";
class OpenSubmenuAction extends MenuAction {
constructor(title, menu, showFor, order) {
super(title, function (action) {
action.getSubmenu().toggle();
action.redraw();
}, showFor, order);
this.submenu = menu;
menu.setParentAction(this);
}
getSubmenu() {
return this.submenu;
}
copy(instance) {
instance = super.copy(Helper.nonNull(instance, new OpenSubmenuAction(null, this.submenu.copy())));
return instance;
}
}
class Menu {
constructor(parentElementSelector) {
this.actions = [];
this.submenus = [];
if (typeof parentElementSelector === 'string') {
this.parentElements = document.querySelectorAll(parentElementSelector);
}
else if (Array.isArray(parentElementSelector)) {
this.parentElements = parentElementSelector;
}
else {
this.parentElements = [parentElementSelector];
}
}
copy(instance)
{
instance = Helper.nonNull(instance, new Menu([]));
instance.actions = [];
for (let i = 0, n = this.actions.length; i < n; i++) {
instance.actions.push(this.actions[i].copy());
}
instance.submenus = [];
for (let i = 0, n = this.submenus.length; i < n; i++) {
instance.submenus.push(this.submenus[i].copy());
}
return instance;
}
addAction(action) {
if (Helper.includesNot(this.actions, action)) {
this.actions.push(action);
this.redraw();
action.setMenu(this);
if (action instanceof OpenSubmenuAction) {
this.submenus.push(action.getSubmenu());
}
}
}
draw() {
if (Helper.isNotNull(this.parentElements)) {
this.sortActions();
let actionElements = [];
for (let i = 0, n = this.actions.length; i < n; i++) {
let element = this.renderAction(this.actions[i]);
this.actions[i]._htmlElement = element;
actionElements.push(element);
}
for (let i = 0, n = this.parentElements.length; i < n; i++) {
this.parentElements[i].removeAllChildren();
for (let i2 = 0, n2 = actionElements.length; i2 < n2; i2++) {
this.parentElements[i].appendChild(Helper.cloneNode(actionElements[i2]));
}
this.parentElements[i].onclick = this._getOnClickListener();
}
}
}
_getOnClickListener() {
let menu = this;
return function (event) {
let _element = event.target;
if (_element.matches('.action') || _element.matches('.action *')) {
// while (!_element.matches('.action > a')) {
// _element = _element.parentNode;
// }
_element = _element.closest(".action");
let actionId = parseInt(_element.dataset["id"]);
for (let i = 0, n = menu.actions.length; i < n; i++) {
if (menu.actions[i].id === actionId) {
if (typeof menu.actions[i].callback === 'function' && menu.actions[i].getActivated()) {
menu.actions[i].callback(menu.actions[i], event);
}
return menu.actions[i];
}
}
for (let i = 0, n = menu.submenus.length; i < n; i++) {
if (menu.submenus[i].click(actionId, event)) {
return menu.submenus[i];
}
}
}
return null;
};
}
/** @protected */
renderAction(action) {
let aElement = document.createElement("a");
if (typeof action.callback === 'string') {
aElement.href = action.callback;
}
if (Helper.isNotNull(action.getIcon())) {
let iconElement = document.createElement("img");
iconElement.src = action.getIcon();
iconElement.classList.add('action-image');
if (action.getShouldTranslate())
{
iconElement.dataset["translationTitle"] = action.title;
}
aElement.appendChild(iconElement);
}
let title = action.getTitle();
if (action.getShouldTranslate())
{
title = Translator.makePersistentTranslation(title);
}
else
{
title = document.createTextNode(title);
}
aElement.appendChild(title);
return this.renderLiElement(aElement, action)
}
/** @protected */
renderLiElement(aElement, action) {
let liElement = document.createElement("li");
liElement.classList.add('action');
liElement.appendChild(aElement);
liElement.dataset["id"] = action.id;
if (Helper.isNotNull(action.getIcon())) {
liElement.classList.add("img");
}
if (!action.getVisible())
{
liElement.classList.add("hidden");
}
if (action instanceof OpenSubmenuAction) {
action.getSubmenu().draw();
liElement.appendChild(action.getSubmenu().getParentElement());
liElement.classList.add("is-dropdown-submenu-parent");
liElement.classList.add("opens-right");
}
return liElement;
}
/** @private */
sortActions() {
this.actions = this.actions.sort(function (first, second) {
return first.order - second.order;
});
}
_getElementsForAction(action){
let elements = [];
for (let i = 0, n = this.parentElements.length; i < n; i++) {
let elem = this.parentElements[i].querySelector("[data-id=\""+action.getId()+"\"]");
Helper.isNull(elem) || elements.push(elem);
}
return elements
}
updateAction(action)
{
let oldElements = this._getElementsForAction(action);
if (oldElements.length === 0)
{
return;
}
let element = this.renderAction(action);
action._htmlElement = element;
for (let i = 0, n = oldElements.length; i < n; i++) {
oldElements[i].replaceWith(Helper.cloneNode(element));
}
}
removeAction(action)
{
let index = this.actions.indexOf(action);
if (index > 0)
{
this.actions.splice(index, 1);
let oldElements = this._getElementsForAction(action);
for (let i = 0, n = oldElements.length; i < n; i++) {
oldElements[i].remove();
}
if (action instanceof OpenSubmenuAction) {
let index = this.submenus.indexOf(action.getSubmenu());
this.submenus.splice(index, 1);
}
}
}
redraw() {
this.draw();
}
}
Menu.SHOW_ALWAYS = "always";
Menu.SHOW_FOR_MEDIUM = "medium";
Menu.SHOW_FOR_SMEDIUM = "smedium";
Menu.SHOW_FOR_LARGE = "large";
Menu.SHOW_NEVER = "never";
class Submenu extends Menu
{
constructor()
{
let menuElement = document.createElement("ul");
menuElement.classList.add("menu");
menuElement.classList.add("vertical");
menuElement.classList.add("submenu");
menuElement.classList.add("is-dropdown-submenu");
menuElement.classList.add("first-sub");
super(menuElement);
this.parentAction = null;
this.isOpen = false;
}
copy(instance)
{
instance = super.copy(Helper.nonNull(instance, new Submenu()));
instance.parentElements = [];
for (let i = 0, n = this.parentElements.length; i < n; i++) {
instance.parentElements.push(Helper.cloneNode(this.parentElements[i]));
}
instance.parentAction = this.parentAction;
instance.isOpen = this.isOpen;
return instance;
}
setParentAction(action)
{
this.parentAction = action;
}
draw()
{
super.draw();
if (Helper.isNotNull(this.parentElements))
{
let self = this;
for (let i = 0, n = this.parentElements.length; i < n; i++) {
let closeListener = document.createElement("div");
closeListener.classList.add("close-listener");
closeListener.onclick = function(e){
console.log(e);
self.close();
};
this.parentElements[i].insertBefore(closeListener, this.parentElements[i].firstElementChild);
}
}
}
getParentElement()
{
return this.parentElements[0];
}
_getOnClickListener()
{
return function () {};
}
click(actionId, event)
{
for (let i = 0, n = this.actions.length; i < n; i++) {
if (this.actions[i].id === actionId)
{
if (typeof this.actions[i].callback === 'function' && this.actions[i].getActivated()) {
this.actions[i].callback(this.actions[i], event);
}
this.close();
return true;
}
}
return false;
}
toggle()
{
if (this.isOpen)
{
this.close();
}
else
{
this.open();
}
}
open()
{
this.isOpen = true;
for (let i = 0, n = this.parentElements.length; i < n; i++) {
this.parentElements[i].classList.add("js-dropdown-active");
}
if (Helper.isNotNull(this.parentAction))
{
this.parentAction.redraw();
}
}
close()
{
this.isOpen = false;
for (let i = 0, n = this.parentElements.length; i < n; i++) {
this.parentElements[i].classList.remove("js-dropdown-active");
}
if (Helper.isNotNull(this.parentAction))
{
this.parentAction.redraw();
}
}
}
class TranslatorDB {
constructor() {
this._indexedDB = indexedDB || mozIndexedDB || webkitIndexedDB || msIndexedDB;
this._version = 3;
let self = this;
this._dbPromise = new Promise(function (resolve, reject) {
let request = self._indexedDB.open("Translator", self._version);
request.onupgradeneeded = function (event) {
let db = event.target.result;
self._upgradeDb(db);
};
request.onsuccess = function (event) {
let db = event.target.result;
resolve(db);
};
request.onerror = function (event) {
reject(event);
};
}).catch(function(e){
console.error(e);
});
}
_upgradeDb(db) {
try {
db.deleteObjectStore("currentLang");
db.deleteObjectStore("translations");
}
catch (e) {
console.warn(e);
}
let currentLangObjectStore = db.createObjectStore("currentLang", {"keyPath": "id"});
let translationsObjectStore = db.createObjectStore("translations", {"keyPath": ["lang","key"]});
translationsObjectStore.createIndex("lang", "lang", {"unique": false});
}
setLanguage(lang) {
this._dbPromise.then(function (db) {
let transaction = TranslatorDB._openTransaction(["currentLang"], "readwrite", db);
let currentLangObjectStore = transaction.objectStore("currentLang");
currentLangObjectStore.put({"id": 1, "lang": lang});
}).catch(function(e){
console.error(e);
});
}
saveTranslationsForLang(lang, translations) {
return this._dbPromise.then(function (db) {
return new Promise(function (resolve) {
let transaction = TranslatorDB._openTransaction(["translations"], "readwrite", db);
let translationsObjectStore = transaction.objectStore("translations");
for (let k in translations) {
translationsObjectStore.put({"lang": lang, "key": k, "translation": translations[k]});
}
transaction.oncomplete = function () {
resolve();
};
});
}).catch(function(e){
// console.error(e);
});
}
loadTranslationsForLang(lang) {
return this._dbPromise.then(function (db) {
return new Promise(function (resolve) {
let transaction = TranslatorDB._openTransaction(["translations"], "readonly", db);
let translationsObjectStore = transaction.objectStore("translations");
let index = translationsObjectStore.index("lang");
let request = index.openCursor(IDBKeyRange.only(lang));
let translations = {};
request.onsuccess = function (e) {
let cursor = e.target.result;
if (cursor) {
let translation = cursor.value;
translations[translation["key"]] = translation["translation"];
cursor.continue();
}
};
transaction.oncomplete = function(){
resolve(translations);
};
});
}).catch(function(e){
console.error(e);
return {};
});
}
getLanguage() {
return this._dbPromise.then(function (db) {
return new Promise(function (resolve) {
let transaction = TranslatorDB._openTransaction(["currentLang"], "readonly", db);
let currentLangObjectStore = transaction.objectStore("currentLang");
let req = currentLangObjectStore.get(1);
req.onsuccess = function (e) {
let data = e.currentTarget.result;
if (data)
{
resolve(data["lang"]);
}
else
{
resolve(null);
}
};
req.onerror = function (e) {
resolve(null);
};
});
}).catch(function(e){
// console.error(e);
});
}
static _openTransaction(name, transactionMode, db) {
let transaction = null;
try {
transaction = db.transaction(name, transactionMode);
}
catch (e) {
console.warn(e);
transaction = db.transaction(name);
}
return transaction;
}
}
class Translator {
constructor() {
this._translations = [];
this._db = new TranslatorDB();
this._currentLanguage = null;
this._supportedLanguages = Translator.supportedLanguages;
this._baseLanguage = Translator.baseLanguage;
this._languageBasePath = Translator.languageBasePath;
this._markUntranslatedTranslations = Translator.markUntranslatedTranslations;
this._markTranslations = Translator.markTranslations;
let self = this;
this._initPromise = this.loadBaseLanguage().then(function () {
return self.loadUserLanguage();
});
}
_loadLanguage(language) {
let self = this;
return fetch(Helper.basePath(this._languageBasePath + language + ".json")).then(function (result) {
return result.json();
}).then(function (res) {
self._translations[language] = Object.assign(res, self._translations[language]);
self._db.saveTranslationsForLang(language, self._translations[language]);
}).catch(function (err) {
console.error("could not load lang " + language + " because of error: ", err);
});
}
loadBaseLanguage() {
let self = this;
return this._loadLanguage(this._baseLanguage).then(function () {
self._currentLanguage = self._baseLanguage;
if (typeof document !== 'undefined') {
document.getElementsByTagName("html")[0].setAttribute("lang", self._baseLanguage);
}
});
};
static setLanguage(language) {
let instance = Translator.getInstance();
if (instance) {
return instance.setLanguage(language);
}
}
setLanguage(language) {
if (this._currentLanguage === language) {
this.updateTranslations();
return Promise.resolve();
}
if (this._supportedLanguages.indexOf(language) === -1) {
return Promise.resolve();
}
this._currentLanguage = language;
if (typeof localStorage !== 'undefined') {
localStorage.setItem("language", language);
}
this._db.setLanguage(language);
let self = this;
return this._loadLanguage(language).then(function () {
if (typeof document !== 'undefined') {
document.getElementsByTagName("html")[0].setAttribute("lang", language);
}
self.updateTranslations();
});
}
static translate(key, args) {
let instance = Translator.getInstance();
if (instance) {
return instance.translate(key, args);
}
return "";
}
translate(key, args) {
if (typeof key === 'object' && Helper.isNotNull(key)) {
key = this.addDynamicTranslation(key);
}
let translation = null;
if (Helper.isNotNull(this._translations[this._currentLanguage]) && Helper.isNotNull(this._translations[this._currentLanguage][key])) {
translation = this._translations[this._currentLanguage][key];
}
if (Helper.isNull(translation)) {
if (Translator.logMissingTranslations) {
console.warn("missing translation for language " + this._currentLanguage + " and key " + key);
}
if (Helper.isNotNull(this._translations[this._baseLanguage])) {
translation = this._translations[this._baseLanguage][key];
}
if (Helper.isNull(translation)) {
if (Translator.logMissingTranslations) {
console.error("missing base translation for key " + key + ". FIX IT");
}
translation = key;
}
if (this._markUntranslatedTranslations) {
translation = "&gt;&gt;" + translation + "&lt;&lt;";
}
}
if (this._markTranslations) {
translation = "$" + translation + "$";
}
if (args !== undefined) {
translation = translation.format(args);
}
return translation;
}
static addDynamicTranslation(trans) {
let instance = Translator.getInstance();
if (instance) {
return instance.addDynamicTranslation(trans);
}
}
addDynamicTranslation(trans) {
let key = trans["key"];
delete trans["key"];
for (let lang in trans) {
if (trans.hasOwnProperty(lang)) {
if (Helper.isNull(this._translations[lang])) {
this._translations[lang] = {};
}
this._translations[lang][key] = trans[lang];
}
}
return key;
}
updateTranslations() {
if (typeof document !== 'undefined') {
let elements = document.querySelectorAll("[data-translation]");
for (let i = 0, max = elements.length; i < max; i++) {
if (elements[i].dataset["translation"] != "") {
try {
elements[i].innerHTML = this.translate(elements[i].dataset["translation"], (elements[i].dataset["translationArgs"] !== undefined) ? JSON.parse(elements[i].dataset["translationArgs"]) : undefined);
}
catch (err) {
console.error("wrong configured translation: " + err);
}
}
for (let k in elements[i].dataset) {
if (k.startsWith("translation") && !k.endsWith("Args")) {
try {
elements[i][k.substr(11).toLowerCase()] = this.translate(elements[i].dataset[k], (elements[i].dataset[k + "Args"] !== undefined) ? JSON.parse(elements[i].dataset[k + "Args"]) : undefined);
}
catch (err) {
console.error("wrong configured translation: " + err);
}
}
}
}
}
}
loadUserLanguage() {
let userLanguage = localStorage.getItem("language");
if (Helper.isNull(userLanguage) || this._supportedLanguages.indexOf(userLanguage) === -1) {
let userLanguages = [];
if (Helper.isNotNull(navigator.languages)) {
userLanguages = navigator.languages.slice(0); //.slice(0) klont das Array. Behebt einen Bug in Firefox
}
if (navigator.language !== undefined) {
userLanguages.push(navigator.language);
}
//sicherstellen, dass überhaupt eine Sprache gefunden wird
userLanguages.push(this._baseLanguage);
if (userLanguages !== undefined) {
for (let i = 0, numLanguages = userLanguages.length; i < numLanguages; i++) {
if (this._supportedLanguages.indexOf(userLanguages[i]) !== -1) {
userLanguage = userLanguages[i];
break;
}
}
}
}
return this.setLanguage(userLanguage.toLowerCase())
}
static makePersistentTranslation(key, args, tag) {
tag = Helper.nonNull(tag, "span");
if (typeof key === 'object') {
key = Translator.addDynamicTranslation(key);
}
if (typeof document !== 'undefined') {
let htmlElem = document.createElement(tag);
htmlElem.dataset["translation"] = key;
if (args !== undefined) {
htmlElem.dataset["translationArgs"] = JSON.stringify(args);
}
htmlElem.innerHTML = Translator.translate(key, args);
return htmlElem;
}
}
static generateChangeLanguageMenuAction() {
let submenu = new Submenu();
submenu.addAction(new MenuAction("en", function () {
Translator.getInstance().setLanguage("en");
}));
submenu.addAction(new MenuAction("de", function () {
Translator.getInstance().setLanguage("de");
}));
return new OpenSubmenuAction("current-lang", submenu, Menu.SHOW_ALWAYS)
}
static init() {
Translator.instance = new Translator();
// Translator.loadBaseLanguage().then(function () {
// Translator.loadUserLanguage();
// });
}
static getInstance() {
return Translator.instance;
}
}
Translator.logMissingTranslations = false;
Translator.instance = null;
Translator.baseLanguage = "en";
Translator.supportedLanguages = [
"de",
"en"
];
Translator.markUntranslatedTranslations = true;
Translator.markTranslations = false;
Translator.languageBasePath = "js/lang/";
Translator.currentLanguage = null;
Translator.translations = {};
class Helper {
static init() {
Helper.heightMmToPxFactor = null;
Helper.widthMmToPxFactor = null;
}
static includesNot(array, value, fromIndex) {
return -1 === array.indexOf(value, fromIndex);
}
static includes(array, value, fromIndex) {
return !Helper.includesNot(array, value, fromIndex);
}
static isSet() {
if (arguments.length > 0) {
const object = arguments[0];
let keys = Array.prototype.slice.call(arguments, 1);
return (Helper.isNotNull(object) && (keys.length === 0 || Helper.isSet.apply(null, [object[keys[0]]].concat(keys.slice(1)))));
}
return false;
}
static isNull(variable) {
return (variable === null || variable === undefined);
}
static isNotNull(variable) {
return !Helper.isNull(variable);
}
static nonNull(val1, val2) {
if (Helper.isNotNull(val1)) {
return val1;
}
return val2;
}
static notEmpty(value) {
return !Helper.empty(value);
}
static buildQuery(values) {
let queryStrings = [];
for (let k in values) {
queryStrings.push(encodeURIComponent(k) + "=" + encodeURIComponent(values[k]));
}
return "?" + queryStrings.join("&");
}
static empty(value) {
return (Helper.isNull(value) || (typeof value === 'string' && value.trim() === ""))
}
static inflateElementsFromString(string) {
let template = document.createElement('template');
template.innerHTML = string;
return template.content.childNodes;
}
static createLoadingSymbol() {
let svgNS = "http://www.w3.org/2000/svg";
let loader = document.createElement("div");
loader.className = 'loader';
let svg = document.createElementNS(svgNS, "svg");
svg.setAttribute('viewBox', "0 0 32 32");
svg.setAttribute("widh", "32");
svg.setAttribute("height", "32");
let circle = document.createElementNS(svgNS, "circle");
circle.setAttribute("id", "spinner");
circle.setAttribute("cx", "16");
circle.setAttribute("cy", "16");
circle.setAttribute("r", "14");
circle.setAttribute("fill", "none");
svg.appendChild(circle);
loader.appendChild(svg);
return loader;
}
static basePath(url) {
return SystemSettings.getBasePath() + url;
}
static isMobileApple() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
}
static isMobile() {
return (navigator.userAgent.match(/Android|BlackBerry|Opera Mini|IEMobile/i) !== null || Helper.isMobileApple() || (typeof window.orientation !== "undefined" || window.orientation === false || window.orientation === null));
}
static select(e) {
let range = document.createRange();
range.selectNodeContents(e);
let sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
static format(number, leadingZeros) {
number = "" + number;
while (number.length < leadingZeros) {
number = "0" + number;
}
return number;
}
static cloneNode(srcNode) {
let destNode = srcNode.cloneNode(true);
destNode.onclick = srcNode.onclick;
return destNode;
}
static encodeToBase(stringToEncode, base) {
let encodedString = "";
let charlength = Math.floor(Math.log(265) / Math.log(base));
for (let i = 0, n = stringToEncode.length; i < n; i++) {
let value = stringToEncode.charCodeAt(i).toString(base);
let joinLength = value.length % charlength;
if (joinLength > 0) {
let joinArray = new Array(charlength + 1 - (joinLength)); //+1, da join nur zwischen elemente einfügt
value = joinArray.join("0") + value;
}
encodedString += value;
}
return encodedString;
}
static decodeToBase(stringToDecode, base) {
let charlength = Math.floor(Math.log(265) / Math.log(base));
let values = stringToDecode.match(new RegExp(".{1," + charlength + "}", "g")) || [];
let encodedString = "";
for (let i = 0, n = values.length; i < n; i++) {
encodedString += String.fromCharCode(parseInt(values[i], base));
}
return encodedString;
}
static toggleVisibility(elem) {
if (elem.style.display === "none") {
elem.style.display = "";
return true;
}
else {
elem.style.display = "none";
return false;
}
}
static print(content) {
let printContent = document.getElementById("print-content");
if (content instanceof Element) {
printContent.removeAllChildren();
printContent.appendChild(content);
}
else {
printContent.innerHTML = content;
}
window.print();
}
static strftime(sFormat, date, useUTC) {
if (!(date instanceof Date)) date = new Date(date);
useUTC = Helper.nonNull(useUTC, false);
let nDay = (useUTC) ? date.getUTCDay() : date.getDay(),
nDate = (useUTC) ? date.getUTCDate() : date.getDate(),
nMonth = (useUTC) ? date.getUTCMonth() : date.getMonth(),
nYear = (useUTC) ? date.getUTCFullYear() : date.getFullYear(),
nHour = (useUTC) ? date.getUTCHours() : date.getHours(),
aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
isLeapYear = function () {
if ((nYear & 3) !== 0) return false;
return nYear % 100 !== 0 || nYear % 400 === 0;
},
getThursday = function () {
let target = new Date(date);
target.setDate(nDate - ((nDay + 6) % 7) + 3);
return target;
},
zeroPad = function (nNum, nPad) {
return ('' + (Math.pow(10, nPad) + nNum)).slice(1);
};
return sFormat.replace(/%[a-z]/gi, function (sMatch) {
return {
'%a': Translator.makePersistentTranslation(aDays[nDay].slice(0, 3)).outerHTML,
'%A': Translator.makePersistentTranslation(aDays[nDay]).outerHTML,
'%b': Translator.makePersistentTranslation(aMonths[nMonth].slice(0, 3)).outerHTML,
'%B': Translator.makePersistentTranslation(aMonths[nMonth]).outerHTML,
'%c': date.toUTCString(),
'%C': Math.floor(nYear / 100),
'%d': zeroPad(nDate, 2),
'%e': nDate,
'%f': zeroPad(date.getTime() % 1000, 4),
'%F': date.toISOString().slice(0, 10),
'%G': getThursday().getFullYear(),
'%g': ('' + getThursday().getFullYear()).slice(2),
'%H': zeroPad(nHour, 2),
'%I': zeroPad((nHour + 11) % 12 + 1, 2),
'%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth > 1 && isLeapYear()) ? 1 : 0), 3),
'%k': '' + nHour,
'%l': (nHour + 11) % 12 + 1,
'%m': zeroPad(nMonth + 1, 2),
'%M': zeroPad(date.getMinutes(), 2),
'%p': (nHour < 12) ? 'AM' : 'PM',
'%P': (nHour < 12) ? 'am' : 'pm',
'%s': Math.round(date.getTime() / 1000),
'%S': zeroPad(date.getSeconds(), 2),
'%u': nDay || 7,
'%V': (function () {
let target = getThursday(),
n1stThu = target.valueOf();
target.setMonth(0, 1);
let nJan1 = target.getDay();
if (nJan1 !== 4) target.setMonth(0, 1 + ((4 - nJan1) + 7) % 7);
return zeroPad(1 + Math.ceil((n1stThu - target) / 604800000), 2);
})(),
'%w': '' + nDay,
'%x': date.toLocaleDateString(),
'%X': date.toLocaleTimeString(),
'%y': ('' + nYear).slice(2),
'%Y': nYear,
'%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
'%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
}[sMatch] || sMatch;
});
}
static cloneJson(obj) {
// https://stackoverflow.com/questions/4120475/how-to-create-and-clone-a-json-object/17502990#17502990
let i;
// basic type deep copy
if (Helper.isNull(obj) || typeof obj !== 'object') {
return obj
}
// array deep copy
if (obj instanceof Array) {
let cloneA = [];
for (i = 0; i < obj.length; ++i) {
cloneA[i] = Helper.cloneJson(obj[i]);
}
return cloneA;
}
if (obj instanceof Date)
{
return new Date(obj.getTime());
}
// object deep copy
let cloneO = {};
for (i in obj) {
cloneO[i] = Helper.cloneJson(obj[i]);
}
return cloneO;
}
static htmlspecialcharsDecode(text) {
const map = {
'&amp;': '&',
'&#038;': "&",
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#039;': "'",
'&#8217;': "",
'&#8216;': "",
'&#8211;': "",
'&#8212;': "—",
'&#8230;': "…",
'&#8221;': '”'
};
if (Helper.isNotNull(text) && typeof text.replace === "function") {
return text.replace(/\&[\w\d\#]{2,5}\;/g, function (m) {
return map[m];
});
}
return text;
}
static formDataFromObject(obj) {
let formData = new FormData();
for (let k in obj) {
formData.set(k, obj[k]);
}
return formData;
}
static scaleContentRecursive(element, content) {
let elementStyle = window.getComputedStyle(element);
let contentStyle = window.getComputedStyle(content);
if (contentStyle.height > elementStyle.height || contentStyle.width > elementStyle.width) {
return Helper.scaleDownContentRecursive(element, content);
}
}
static scaleDownContentRecursive(element, content) {
Helper.convertChildrenToRelativeRecursive(element);
let elementStyle = window.getComputedStyle(element);
let contentStyle = window.getComputedStyle(content);
let runs = 0;
let fontSize = parseFloat(contentStyle.getPropertyValue("font-size"));
let width = contentStyle.width;
let height = contentStyle.height;
while (contentStyle.height > elementStyle.height || contentStyle.width > elementStyle.width) {
fontSize *= 0.95;
if (height > elementStyle.height) {
height *= 0.95;
}
if (width > contentStyle.width) {
width *= 0.95;
}
content.style["font-size"] = fontSize + "px";
content.style["max-height"] = height + "px";
content.style["max-width"] = width + "px";
runs++;
if (runs > 2000) {
console.log("breaked");
break;
}
}
Helper.convertToRelative(content);
contentStyle = window.getComputedStyle(content);
content.style["font-size"] = (parseFloat(contentStyle.getPropertyValue("font-size")) / parseFloat(document.documentElement.clientHeight) * 100) + "vh";
}
static convertChildrenToRelativeRecursive(element) {
let children = element.childNodes;
for (let i = 0, n = children.length; i < n; i++) {
if (children[i] instanceof Element) {
Helper.convertToRelative(children[i]);
Helper.convertChildrenToRelativeRecursive(children[i]);
}
}
}
static convertToRelative(element) {
let hasTransitionClass = (element.classList.contains("no-transtition"));
element.classList.add("no-transition");
let parent = element.parentNode;
console.log(element);
let elementStyle = window.getComputedStyle(element);
let parentStyle = window.getComputedStyle(parent);
let fontSize = parseFloat(elementStyle.getPropertyValue("font-size")) / parseFloat(parentStyle.getPropertyValue("font-size"));
let maxHeight = elementStyle.height;
let maxWidth = elementStyle.width;
let pHeight = parentStyle.height;
let pWidth = parentStyle.width;
let relativeAttributes = element.style;
relativeAttributes['max-height'] = Math.floor(maxHeight / pHeight * 100) + "%";
relativeAttributes['margin-left'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-left')) / pWidth * 100) + "%";
relativeAttributes['margin-right'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-right')) / pWidth * 100) + "%";
relativeAttributes['margin-top'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-top')) / pHeight * 100) + "%";
relativeAttributes['margin-bottom'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-bottom')) / pHeight * 100) + "%";
relativeAttributes['max-width'] = Math.floor(maxWidth / pWidth * 100) + "%";
relativeAttributes["font-size"] = fontSize + "em";
// console.log(relativeAttributes);
// element.css(relativeAttributes);
if (!hasTransitionClass) {
element.classList.remove("no-transition");
}
}
static isChrome() {
let isChromium = window.chrome,
winNav = window.navigator,
vendorName = winNav.vendor,
isOpera = winNav.userAgent.indexOf("OPR") > -1,
isIEedge = winNav.userAgent.indexOf("Edge") > -1,
isIOSChrome = winNav.userAgent.match("CriOS");
if (isIOSChrome) {
return true;
} else {
return isChromium !== null &&
typeof isChromium !== "undefined" &&
vendorName === "Google Inc." &&
isOpera === false &&
isIEedge === false;
}
}
static getIndexedObject(array, keyValue) {
let obj = {};
for (let i = 0, n = array.length; i < n; i++) {
obj[array[i][keyValue]] = array[i];
}
return obj;
}
static invertKeyValues(obj) {
let new_obj = {};
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
new_obj[obj[prop]] = prop;
}
}
return new_obj;
}
static toArray(object) {
let res = [];
for (let k in object) {
res.push(object[k]);
}
return res;
}
}
Helper.init();
class ThemeManager {
static init() {
ThemeManager.loadCurrentTheme();
}
static changeCurrentTheme(newTheme) {
let theme = null;
if (typeof newTheme === 'string') {
let themes = ThemeManager.themes.filter(function (theme) {
return theme._name === newTheme;
});
if (themes.length > 0) {
theme = themes[0];
}
}
else if (ThemeManager.themes.indexOf(newTheme) !== -1) {
theme = newTheme;
}
if (Helper.isNotNull(theme)) {
localStorage.setItem("currentTheme", theme._name);
let themePromise = new Promise(function (resolve) {
document.querySelector("nav.top-bar").addEventListener("transitionend", function(){
resolve();
});
});
document.body.className = theme._className;
ThemeManager.currentTheme = theme;
for (let i = 0, n = ThemeManager.changeListeners.length; i < n; i++) {
ThemeManager.changeListeners[i](ThemeManager.currentTheme, themePromise);
}
}
}
static addTheme(theme) {
ThemeManager.themes.push(theme);
}
static loadCurrentTheme() {
ThemeManager.changeCurrentTheme(localStorage.getItem("currentTheme"));
if (Helper.isNull(ThemeManager.currentTheme)) {
let className = document.body.className;
let themes = ThemeManager.themes.filter(function (theme) {
return theme._className === className;
});
if (themes.length > 0) {
ThemeManager.changeCurrentTheme(themes[0]);
}
else if (ThemeManager.themes.length > 0) {
ThemeManager.changeCurrentTheme(ThemeManager.themes[0]);
}
}
}
static generateChangeThemeMenuAction() {
return new MenuAction(ThemeManager.currentTheme._name, function (action) {
let currentThemeIndex = ThemeManager.themes.indexOf(ThemeManager.currentTheme);
let nextIndex = (currentThemeIndex + 1) % ThemeManager.themes.length;
ThemeManager.changeCurrentTheme(ThemeManager.themes[nextIndex]);
action.title = ThemeManager.currentTheme._name;
action._menu.redraw();
}, Menu.SHOW_ALWAYS)
}
static addChangeListener(listener) {
ThemeManager.changeListeners.push(listener);
}
}
ThemeManager.themes = [];
ThemeManager.changeListeners = [];
class CookieCompliance {
constructor(cookieContainerId) {
this.cookieContainerId = cookieContainerId;
this.dropCookie = true;
this.cookieDuration = 365 * 10;
this.cookieName = 'complianceCookie';
this.cookieValue = 'true';
}
showIfNeeded()
{
if (CookieCompliance.checkCookie(this.cookieName) !== this.cookieValue) {
this.show();
}
}
removeMe() {
this.createCookie(this.cookieName, this.cookieValue, this.cookieDuration);
}
createCookie(name, value, days) {
let expires;
if (Helper.isNotNull(days)) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
else {
expires = "";
}
if (this.dropCookie) {
document.cookie = name + "=" + value + expires + "; path=/";
}
}
eraseCookie(name) {
this.createCookie(name, "", -1);
}
static checkCookie(name) {
const nameEQ = name + "=";
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let c = cookies[i];
while (c.charAt(0) === ' ') {
c = c.substring(1, c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length, c.length);
}
}
return null;
}
show() {
let cookieCompliance = this;
const cookieMessage = document.getElementById(this.cookieContainerId);
cookieMessage.style.display='block';
cookieMessage.querySelector("#close-cookie-msg").onclick = function(){
cookieCompliance.removeMe();
cookieMessage.remove();
};
}
}
class ActionBarMenu extends Menu {
static init() {
function parseStyleToObject(str) {
let styleObject = {};
if (typeof str !== 'string') {
return styleObject;
}
str = str.trim().slice(1, -1); // browsers re-quote string style values
if (!str) {
return styleObject;
}
styleObject = str.split('&').reduce(function (ret, param) {
const parts = param.replace(/\+/g, ' ').split('=');
let key = parts[0];
let val = parts[1];
key = decodeURIComponent(key);
// missing `=` should be `null`:
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
val = val === undefined ? null : decodeURIComponent(val);
if (!ret.hasOwnProperty(key)) {
ret[key] = val;
} else if (Array.isArray(ret[key])) {
ret[key].push(val);
} else {
ret[key] = [ret[key], val];
}
return ret;
}, {});
return styleObject;
}
let cssStyle = document.getElementsByClassName('foundation-mq');
if (cssStyle.length === 0) {
return;
}
let queries = [];
cssStyle = parseStyleToObject(window.getComputedStyle(cssStyle[0]).getPropertyValue('font-family'));
for (let key in cssStyle) {
if (cssStyle.hasOwnProperty(key)) {
queries.push({
_name: key,
value: 'only screen and (min-width: ' + cssStyle[key] + ')'
});
}
}
window.addEventListener('resize', function () {
if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
ActionBarMenu.currentMenu.updateToggleButton();
}
});
let responsiveMenu = document.getElementById("responsive-menu");
document.getElementById("responsive-menu-toggle").onclick = function () {
if (window.getComputedStyle(responsiveMenu).getPropertyValue('display') === 'none') {
responsiveMenu.style.display = 'block';
}
else if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
ActionBarMenu.currentMenu.close();
}
};
responsiveMenu.firstElementChild.addEventListener("click", function (e) {
if (e.target === responsiveMenu.firstElementChild && Helper.isNotNull(ActionBarMenu.currentMenu)) {
ActionBarMenu.currentMenu.close();
}
}
);
ActionBarMenu.queries = queries;
}
static _getCurrentSize() {
let matched;
for (let i = 0, n = ActionBarMenu.queries.length; i < n; i++) {
let query = ActionBarMenu.queries[i];
if (matchMedia(query.value).matches) {
matched = query;
}
}
if (typeof matched === 'object') {
return matched._name;
} else {
return matched;
}
}
renderLiElement(aElement, action) {
let liElement = super.renderLiElement(aElement, action);
liElement.classList.add(action.showFor);
return liElement;
}
static filterVisibleElements(elements) {
let visibleElements = [];
for (let i = 0, n = elements.length; i < n; i++) {
if (!elements[i].classList.contains("hidden")) {
visibleElements.push(elements[i]);
}
}
return visibleElements;
}
updateToggleButton() {
let size = ActionBarMenu._getCurrentSize();
let firstParentElement = this.parentElements[0];
if (ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_LARGE)).length > 0 && (size === "medium" || size === "smedium" || size === "small") ||
ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_MEDIUM)).length > 0 && (size === "smedium" || size === "small") ||
ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_SMEDIUM)).length > 0 && (size === "small") ||
ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_NEVER)).length > 0) {
document.getElementById("responsive-menu-toggle").style.display = 'block';
} else {
document.getElementById("responsive-menu-toggle").style.display = 'none';
if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
ActionBarMenu.currentMenu.close();
}
}
}
_getOnClickListener() {
let superListener = super._getOnClickListener();
return function (event) {
let action = superListener(event);
if (!(action instanceof OpenSubmenuAction) && Helper.isNotNull(ActionBarMenu.currentMenu)) {
ActionBarMenu.currentMenu.close();
}
}
}
draw(parentElement) {
let returnValue = super.draw(parentElement);
this.updateToggleButton();
ActionBarMenu.currentMenu = this;
return returnValue;
}
close() {
document.getElementById("responsive-menu").style.display = 'none';
for (let i = 0, n = this.submenus.length; i < n; i++) {
this.submenus[i].close();
}
}
removeAction(action) {
let res = super.removeAction(action);
this.updateToggleButton();
return res;
}
}
ActionBarMenu.queries = [];
ActionBarMenu.currentMenu = null;
ActionBarMenu.init();
class ViewInflater {
static inflate(viewUrl, parentUrls) {
parentUrls = Helper.nonNull(parentUrls, []).slice(0);
let resultPromise = Promise.resolve();
if (viewUrl instanceof Element) {
resultPromise = Promise.resolve(viewUrl);
}
else {
if (parentUrls.indexOf(viewUrl) !== -1) {
return Promise.reject("views are in a circuit! cannot resolve view for url " + parentUrls[0] + "! url " + viewUrl + " is in stack before!");
}
parentUrls.push(viewUrl);
resultPromise = fetch(Helper.basePath(viewUrl), {credentials: "same-origin"}).then(function (result) {
return result.text();
}).then(function (htmlText) {
let doc = (new DOMParser()).parseFromString(htmlText, "text/html");
if (Helper.isNull(doc)) {
doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = htmlText;
}
return doc.body.firstChild
});
}
return resultPromise.then(function (parentElement) {
let promises = [];
let childViews = parentElement.querySelectorAll("[data-view]");
for (let i = 0, n = childViews.length; i < n; i++) {
promises.push(ViewInflater.inflate(childViews[i].dataset["view"], parentUrls).then(function (element) {
childViews[i].replaceWith(element);
}));
}
return Promise.all(promises).then(function () {
return parentElement;
});
});
}
}
class Context {
constructor(view) {
let self = this;
this._siteContent = null;
this.firstStart = true;
this.inflatePromise = new Promise(function (resolver) {
self.inflatePromiseResolver = resolver;
});
this.fragments = {};
if (Helper.isNotNull(view)) {
this.inflateView(view);
}
}
onConstruct() {
let results = [];
for (let k in this.fragments) {
results.push(this.fragments[k].onConstruct.apply(this.fragments[k], arguments));
results.push(this.fragments[k].inflatePromise);
}
return Promise.all(results);
}
onStart() {
if (this.firstStart) {
this.onFirstStart();
this.firstStart = false;
}
for (let k in this.fragments) {
let fragment = this.fragments[k];
fragment.onStart.apply(this.fragments[k], arguments);
this.fragments[k].inflatePromise.then(function (fragmentView) {
if (fragment.isActive()) {
fragmentView.classList.remove("hidden");
}
else {
fragmentView.classList.add("hidden");
}
});
}
}
onFirstStart() {
// for (let k in this.fragments) {
// this.fragments[k].onFirstStart.apply(this.fragments[k], arguments);
// }
}
onPause() {
for (let k in this.fragments) {
this.fragments[k].onPause.apply(this.fragments[k], arguments);
}
}
onDestroy() {
for (let k in this.fragments) {
this.fragments[k].onDestroy.apply(this.fragments[k], arguments);
}
}
addFragment(viewQuery, fragment) {
this.fragments[viewQuery] = fragment;
this.inflatePromise = this.inflatePromise.then(function (siteContent) {
return fragment.inflatePromise.then(function (fragmentView) {
siteContent.querySelector(viewQuery).appendChild(fragmentView);
return siteContent;
});
});
}
/** @protected */
inflateView(link) {
let self = this;
this.inflatePromiseResolver(ViewInflater.inflate(link).then(function (siteContent) {
self._siteContent = siteContent;
return siteContent;
}));
return this.inflatePromise;
}
findBy(query, all, asPromise) {
all = Helper.nonNull(all, false);
asPromise = Helper.nonNull(asPromise, false);
let getVal = function (root) {
let res = null;
if (all) {
res = root.querySelectorAll(query);
if (root.matches(query)) {
res.push(root);
}
}
else {
if (root.matches(query)) {
res = root;
}
else {
res = root.querySelector(query);
}
}
return res;
};
if (asPromise) {
return this.inflatePromise.then(function (rootView) {
return getVal(rootView);
});
}
return getVal(this._siteContent);
}
}
class AbstractSite$1 extends Context {
constructor(siteManager, view, deepLink) {
super(view);
this.isVisible = false;
this.siteManager = siteManager;
this.isFinishing = false;
this.actionMenu = null;
this.url = "";
this.deepLink = deepLink;
this.startArgs = {};
this.title = siteManager.getDefaultTitle();
}
setTitle(titleElement, title) {
if (typeof titleElement === "string") {
title = titleElement;
titleElement = document.createTextNode(titleElement);
}
this.title = {
element: titleElement
};
this.title["title"] = Helper.nonNull(title, this.title["title"]);
if (this.isVisible) {
this.siteManager.updateTitle();
}
}
startStartsite() {
return this.startSite(this.siteManager.getStartSiteName());
}
inflateView(link) {
let self = this;
return super.inflateView(link).then(function (res) {
let promises = [];
for (let i = 0, n = self.fragments.length; i < n; i++) {
promises.push(self.fragments[i].inflatePromise);
}
return Promise.all(promises).then(function () {
return res;
});
});
}
onConstruct(args) {
this.startArgs = args;
if (Helper.isNotNull(this.deepLink)) {
this.setUrlFromParams(args);
}
return super.onConstruct(args);
}
onStart(args) {
this.isVisible = true;
let res = super.onStart(args);
this.actionMenu.redraw();
return res;
}
onPause(args) {
super.onPause(args);
this.isVisible = false;
}
finish(result) {
if (!this.isFinishing) {
this.isFinishing = true;
this.siteManager.endSite(this, result);
}
}
startSite(siteName, args) {
return this.siteManager.startSite(siteName, args);
}
toForeground() {
this.siteManager.toForeground(this);
}
finishAndStartNext(siteName, startParams, finishResult) {
this.startSite(siteName, startParams);
this.finish(finishResult);
}
createActionBarMenu(menu) {
let defaultActions = this.siteManager.getDefaultActions();
for (let i = 0, n = defaultActions.length; i < n; i++) {
menu.addAction(defaultActions[i].copy());
}
return menu;
}
setUrl(url) {
this.url = url;
this.siteManager.updateUrl(this);
}
setUrlFromParams(params) {
this.setUrl(this.deepLink + Helper.buildQuery(params));
}
updateUrlParams(params) {
this.startArgs = Object.assign(this.startArgs, params);
this.setUrlFromParams(this.startArgs);
}
getUrl() {
return this.url;
}
getFullUrl() {
return Helper.basePath(this.url);
}
onBackPressed() {
}
addListener(event, selector, listenerFunction) {
this.siteManager.addListener(this, event, selector, listenerFunction);
}
addKeyListener(keycode, listenerFunction)
{
this.siteManager.addKeyListener(this, keycode, listenerFunction);
}
addKeyAndEventListener(keycode, event, selector, listenerFunction) {
this.siteManager.addKeyAndEventListener(this, keycode, event, selector, listenerFunction);
}
}
class SiteContainer {
constructor(site, finishResolver) {
this._site = site;
this._siteContent = null;
this._pauseParameters = {};
this._startParameters = {};
this._finishResolver = finishResolver;
}
getSite() {
return this._site;
}
setSite(site) {
if (site instanceof AbstractSite) {
this._site = site;
}
}
getSiteContent() {
return this._siteContent;
}
setSiteContent(value) {
this._siteContent = value;
}
getPauseParameters() {
return this._pauseParameters;
}
setPauseParameters(value) {
this._pauseParameters = value;
}
getStartParameters() {
return this._startParameters;
}
setStartParameters(value) {
this._startParameters = value;
}
getFinishResolver() {
return this._finishResolver;
}
setFinishResolver(value) {
this._finishResolver = value;
}
}
class SiteManager {
constructor(siteDivId, actionBarMenuSelector) {
this.siteDiv = document.getElementById(siteDivId);
this.siteContainerStack = [];
this.currentSiteContainerToShow = null;
this.actionBarMenuSelector = Helper.nonNull(actionBarMenuSelector, '.action-bar');
this.siteStartingPromise = Promise.resolve();
this.defaultActions = [];
this.startSiteName = null;
this.titleElement = document.querySelector(".top-bar-title");
const defaultTitleElem = document.createElement("span");
while(this.titleElement.childNodes.length > 0)
{
const child = this.titleElement.firstChild;
child.remove();
defaultTitleElem.appendChild(child);
}
this.defaultTitle = {
element: defaultTitleElem,
title: document.title
};
console.log(this.defaultTitle);
let siteManager = this;
window.onpopstate = function (e) {
if (siteManager.siteContainerStack.length >= 1) {
let site = siteManager.siteContainerStack[siteManager.siteContainerStack.length - 1].getSite();
if (site.onBackPressed() !== false) {
siteManager.endSite(site);
}
}
};
}
getDefaultTitle() {
return this.defaultTitle;
}
setStartSiteName(startSiteName) {
this.startSiteName = startSiteName;
}
getStartSiteName() {
return this.startSiteName;
}
addDefaultAction(action) {
this.defaultActions.push(action);
}
getDefaultActions() {
return this.defaultActions;
}
startSite(siteConstructor, paramsPromise) {
if (!(siteConstructor.prototype instanceof AbstractSite$1))
{
throw {
"error": "wrong class given! Expected AbstractSite, given "+siteConstructor.name
};
}
let site = new siteConstructor(this);
let resolver = {};
let finishPromise = new Promise(function (resolve, reject) {
resolver.resolve = resolve;
resolver.reject = reject;
});
let siteContainer = new SiteContainer(site, resolver);
this.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
let manager = this;
this.siteStartingPromise = new Promise(function (resolve) {
Promise.resolve(paramsPromise).then(function (params) {
siteContainer.setStartParameters(params);
return Promise.all([site.onConstruct(params), site.inflatePromise]);
}).then(function () {
site.actionMenu = site.createActionBarMenu(manager.buildActionBarMenu());
}).then(function () {
resolve(manager.show(siteContainer));
});
});
return finishPromise;
}
endSite(site, result) {
let manager = this;
this.siteStartingPromise.then(function () {
let index = manager.findContainerIndexBySite(site);
let container = manager.siteContainerStack.splice(index, 1);
container = container[0];
let showSiteContainer = null;
if (container === manager.currentSiteContainerToShow) {
manager.currentSiteContainerToShow.getSite().onPause();
manager.currentSiteContainerToShow = null;
let newSiteContainerIndex = manager.siteContainerStack.length - 1;
if (newSiteContainerIndex < 0) {
manager.showAppEndedMessage();
manager.startSite(manager.startSiteName);
return;
}
manager.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
showSiteContainer = manager.siteContainerStack[newSiteContainerIndex];
}
container.getSite().onDestroy();
Promise.resolve(result).then(function (resValue) {
container.getFinishResolver().resolve(resValue);
if (Helper.isNotNull(showSiteContainer)) {
manager.show(showSiteContainer);
}
});
});
}
addListener(site, event, _selector, listener) {
this.siteDiv.addEventListener(event, function (_event) {
let _element = _event.target;
if (site.isVisible && _element.matches(_selector)) {
listener(_element, _event);
}
});
}
addKeyAndEventListener(site, keycode, event, selector, listener) {
this.addListener(site, event, selector, listener);
this.addKeyListener(site, keycode, listener);
}
addKeyListener(site, keycode, listener) {
window.addEventListener("keydown", function (e) {
if (site.isVisible && e.which === keycode) {
listener(this, e);
}
});
}
toForeground(site) {
let index = this.findContainerIndexBySite(site);
let container = this.siteContainerStack.splice(index, 1);
container = container[0];
this.show(container);
}
refreshCurrentSite() {
return this.show(this.currentSiteContainerToShow);
}
/** @private */
show(siteContainer) {
if (Helper.isNotNull(this.currentSiteContainerToShow)) {
this.currentSiteContainerToShow.setPauseParameters(this.currentSiteContainerToShow.getSite().onPause());
this.currentSiteContainerToShow.setSiteContent(this.siteDiv.innerHTML);
}
this.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
let siteManager = this;
this.currentSiteContainerToShow = siteContainer;
if (-1 === this.siteContainerStack.indexOf(siteContainer)) {
this.siteContainerStack.push(siteContainer);
}
return siteContainer.getSite().inflatePromise.then(function (data) {
siteContainer.getSite().actionMenu.redraw();
siteManager.siteDiv.removeAllChildren().appendChild(data);
siteManager.updateTitle();
Translator.getInstance().updateTranslations();
return data;
}).then(function (data) {
siteContainer.getSite().onStart(siteContainer.getPauseParameters());
history.pushState({
'siteName': siteContainer.getSite().constructor.name,
'siteData': data.outerHTML,
'stackPosition': siteManager.siteContainerStack.length - 1
}, siteContainer.getSite().constructor.name, siteContainer.getSite().getFullUrl());
});
}
updateUrl(site) {
if (Helper.isNotNull(this.currentSiteContainerToShow) && this.currentSiteContainerToShow.getSite() === site) {
let self = this;
history.replaceState({
'siteName': site.constructor.name,
'siteData': site._siteContent.outerHTML,
'stackPosition': self.siteContainerStack.length - 1
}, site.constructor.name, site.getFullUrl());
}
}
getCurrentSite() {
if (this.currentSiteContainerToShow != null)
return this.currentSiteContainerToShow.getSite();
}
redrawCurrentActionBar() {
if (this.currentSiteContainerToShow != null)
this.currentSiteContainerToShow.getSite().actionMenu.redraw();
}
updateTitle() {
let title = this.getCurrentSite().title;
this.titleElement.removeAllChildren().appendChild(title.element);
document.title = Helper.nonNull(title.title, this.defaultTitle.title);
}
/** @private */
findContainerIndexBySite(site) {
for (let i = 0, n = this.siteContainerStack.length; i < n; i++) {
if (this.siteContainerStack[i].getSite() === site) {
return i;
}
}
return -1;
}
/** @private */
findContainerBySite(site) {
let index = this.findContainerIndexBySite(site);
if (index === -1) {
return null;
}
return this.siteContainerStack[index];
}
/** @private */
showAppEndedMessage() {
this.siteDiv.removeAllChildren().appendChild(Translator.makePersistentTranslation("The app has ended! Please close the window."));
}
/** @private */
buildActionBarMenu() {
return new ActionBarMenu(this.actionBarMenuSelector);
}
}
class PauseSite extends AbstractSite$1 {
onConstruct(args) {
let pausedElement = null;
if (Helper.isSet(args, "url")) {
pausedElement = args["url"];
}
else {
pausedElement = document.createElement("div");
pausedElement.innerHTML = "Paused...";
}
this.inflateView(pausedElement);
}
}
class App {
constructor() {
this._siteManager = null;
this._actionBarMenuSelector = '.action-bar';
this._basePath = SystemSettings.getBasePath();
this._siteContentId = 'site-content';
this._deepLinks = new Map();
this._defaultActions = [];
this._addThemeAction = false;
this._showCookieCompliance = true;
this._startSite = null;
}
getSiteManager()
{
return this._siteManager;
}
addDefaultAction(action) {
this._defaultActions.push(action);
}
setAddThemeAction(addThemeAction) {
this._addThemeAction = addThemeAction;
}
getSiteContentId() {
return this._siteContentId;
}
setSiteContentId(value) {
this._siteContentId = value;
}
getActionBarMenuSelector() {
return this._actionBarMenuSelector;
}
setActionBarMenuSelector(value) {
this._actionBarMenuSelector = value;
}
getBasePath() {
return this._basePath;
}
setBasePath(value) {
this._basePath = value;
}
addDeepLink(alias, site) {
this._deepLinks.set(alias.toLowerCase(), site);
}
setShowCookieCompliance(cookieCompliance)
{
this._showCookieCompliance = cookieCompliance;
}
refreshCurrentSite()
{
this._siteManager.refreshCurrentSite();
}
pause(elementToShow){
this.startSite(PauseSite, {"url": elementToShow});
}
resume(){
const currentSite = this._siteManager.getCurrentSite();
if (currentSite instanceof PauseSite)
{
currentSite.finish();
}
}
_resolveDeepLink(deepLink) {
deepLink = deepLink.toLowerCase();
if (this._deepLinks.has(deepLink)) {
return this._deepLinks.get(deepLink);
}
return null;
}
_getDeepLink() {
let deepLink = "";
if (window.location.pathname.search(this._basePath) === 0) {
deepLink = window.location.pathname.substr(this._basePath.length).trim();
}
if (deepLink.charAt(0) === '/') {
deepLink = deepLink.substr(1).trim();
}
if (deepLink.charAt(deepLink.length - 1) === '/') {
deepLink = deepLink.substr(0, deepLink.length - 2).trim();
}
if (deepLink.length === 0 && window.location.hash) {
deepLink = window.location.hash.substr(1).trim();
}
return this._resolveDeepLink(deepLink);
}
_addDeepLinksListener() {
let app = this;
let elements = document.getElementsByClassName("deep-link");
for (let i = 0, n = elements.length; i < n; i++) {
elements[i].addEventListener("click", function (e) {
e.preventDefault();
app._siteManager.startSite(Helper.nonNull(app._resolveDeepLink(this.dataset["siteName"]), app._startSite), App._extractParams(this.dataset["siteArgs"]));
return true;
});
}
}
removeDefaultAction(action)
{
let index = this._defaultActions.indexOf(action);
if (index >= 0)
{
this._defaultActions[index].remove(true);
this._defaultActions.splice(index, 1);
}
}
startSite(site, parameter)
{
return this._siteManager.startSite(site, parameter);
}
start(fallbackStartSite) {
SystemSettings.setBasePath(this._basePath);
let startSite = Helper.nonNull(this._getDeepLink(), fallbackStartSite);
let startParams = App._getStartParams();
this._startSite = fallbackStartSite;
Translator.init();
ThemeManager.init();
if (this._addThemeAction) {
this.addDefaultAction(ThemeManager.generateChangeThemeMenuAction());
}
this._siteManager = new SiteManager(this._siteContentId, this._actionBarMenuSelector);
this._siteManager.defaultActions = this._defaultActions;
this._siteManager.setStartSiteName(fallbackStartSite);
this._siteManager.startSite(startSite, startParams);
this._addDeepLinksListener();
if (this._showCookieCompliance)
{
new CookieCompliance('cookie-compliance').showIfNeeded();
}
}
static _extractParams(paramString) {
if (Helper.isNull(paramString)) {
return null;
}
let result = {}, tmp = [];
let items = paramString.split("&");
for (let index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0].trim().length > 0) {
result[tmp[0]] = decodeURIComponent(tmp[1]);
}
}
return result;
}
static _getStartParams() {
return App._extractParams(window.location.search.substr(1));
}
}
class InitPromise
{
static addPromise(promise)
{
if (typeof promise === 'function')
{
let func = promise;
promise = InitPromise.mainPromise.then(function(app){
return (func(app));
});
}
InitPromise.promises.push(promise);
}
static resolve(app)
{
InitPromise.mainResolver(app);
return InitPromise.mainPromise.then(function(){
return Promise.all(InitPromise.promises);
});
}
}
InitPromise.promises = [];
InitPromise.mainPromise = new Promise(function(resolver){
InitPromise.mainResolver = resolver;
});
class ShareButton {
constructor(deviceType, icon, callback)
{
this._deviceType = deviceType;
this._icon = icon;
this._callback = callback;
}
shouldShowFor(deviceType)
{
return (deviceType === (deviceType & this._deviceType))
}
getIcon()
{
return this._icon;
}
getCallback()
{
return this._callback;
}
}
ShareButton.TYPE_DESKTOP = 1;
ShareButton.TYPE_MOBILE_APPLE = 2;
ShareButton.TYPE_MOBILE_LEFTOVER = 4;
ShareButton.TYPE_MOBILE = ShareButton.TYPE_MOBILE_APPLE+ShareButton.TYPE_MOBILE_LEFTOVER;
ShareButton.TYPE_ALL = ShareButton.TYPE_DESKTOP+ShareButton.TYPE_MOBILE;
class ShareManager {
static init() {
ShareManager.shareButtons = [];
}
static addShareButton(shareButton) {
ShareManager.shareButtons.push(shareButton);
}
static generateDefaultShareElement(shareUrl)
{
return ShareManager.generateShareElement(shareUrl, ShareManager.getDefaultGenerateCallback());
}
static generateDefaultShareElementForButtons(shareUrl, buttons)
{
return ShareManager.generateShareElementForButtons(shareUrl, buttons, ShareManager.getDefaultGenerateCallback());
}
static generateShareElement(shareUrl, generateCallback) {
return ShareManager.generateShareElementForButtons(shareUrl, ShareManager.shareButtons, generateCallback);
}
static generateShareElementForButtons(shareUrl, buttons, generateCallback)
{
let shareButtonElement = document.createElement("div");
let currentDeviceType = ShareManager.getCurrentDeviceType();
for (let i = 0, n = buttons.length; i < n; i++) {
if (buttons[i].shouldShowFor(currentDeviceType)) {
let elem = generateCallback(buttons[i], shareUrl);
elem.onclick = function(event){
buttons[i].getCallback()(shareUrl, this, event);
};
shareButtonElement.appendChild(elem);
}
}
return shareButtonElement;
}
static getCurrentDeviceType() {
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
return ShareButton.TYPE_MOBILE_APPLE;
}
else if ((navigator.userAgent.match(/Android|BlackBerry|Opera Mini|IEMobile/i) !== null || (typeof window.orientation !== "undefined"))) {
return ShareButton.TYPE_MOBILE_LEFTOVER;
}
else {
return ShareButton.TYPE_DESKTOP;
}
}
static getDefaultGenerateCallback()
{
return function(button){
let linkElement = document.createElement("a");
let iconElement = document.createElement("img");
linkElement.appendChild(iconElement);
iconElement.src = Helper.basePath(button.getIcon());
iconElement.classList.add("share-icon");
return linkElement;
}
}
}
ShareManager.init();
class SmsShareButton extends ShareButton
{
constructor(icon) {
super(ShareButton.TYPE_MOBILE, icon, function (link) {
let linkToOpen = "";
if (ShareManager.getCurrentDeviceType() === ShareButton.TYPE_MOBILE_APPLE) {
linkToOpen = "sms:&body="+encodeURIComponent(link);
}
else {
linkToOpen = "sms:?body=" + encodeURIComponent(link);
}
window.open(linkToOpen, '_blank');
});
}
}
class TelegramShareButton extends ShareButton {
constructor(icon) {
super(ShareButton.TYPE_ALL, icon, function (link) {
let linkToOpen = "https://t.me/share/url?url="+encodeURIComponent(link);
window.open(linkToOpen, '_blank');
});
}
}
class WhatsappShareButton extends ShareButton {
constructor(icon) {
super(ShareButton.TYPE_ALL, icon, function (link) {
let linkToOpen = "";
if (ShareManager.getCurrentDeviceType() === ShareButton.TYPE_DESKTOP) {
linkToOpen = "https://web.whatsapp.com/send?text="+encodeURIComponent(link);
}
else {
linkToOpen = "whatsapp://send?text=" + encodeURIComponent(link);
}
window.open(linkToOpen, '_blank');
});
}
}
class Theme
{
constructor(name, className, icon)
{
this._name = name;
this._className = className;
this._icon = icon;
}
}
function applyPolyfills(){
if (!String.prototype.format) {
String.prototype.format = function (args) {
return this.replace(/{(\d+)}/g, function (match, number) {
return args[number] !== undefined
? args[number]
: match
;
});
};
}
Object.assign = Helper.nonNull(Object.assign, function (base, obj) {
base = Helper.nonNull(base, {});
if (obj === null || typeof(obj) !== 'object' || 'isActiveClone' in obj)
return base;
// if (obj instanceof Date) {
// temp = new obj.constructor(); //or new Date(obj);
// }
// else {
// temp = obj.constructor();
// }
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
obj['isActiveClone'] = null;
base[key] = obj[key];
delete obj['isActiveClone'];
}
}
return base;
});
if (typeof window !== 'undefined') {
if (Helper.isNotNull(window["Node"]) && !window["Node"]["prototype"]["removeAllChildren"]) {
Node.prototype["removeAllChildren"] = function () {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
return this;
};
}
if (HTMLElement) {
HTMLElement.prototype["fadeOut"] = Helper.nonNull(HTMLElement.prototype["fadeOut"],
function (time, effect, delay) {
time = Helper.nonNull(time, 0.5);
effect = Helper.nonNull(effect, "ease-in-out");
delay = Helper.nonNull(delay, 0);
this.style.transition = "opacity " + time + "s " + effect + " " + delay + "s";
let elem = this;
let animPromise = new Promise(function (resolve) {
let transEndLis = function (e) {
elem.removeEventListener("transitionend", transEndLis);
elem.removeEventListener("transitioncancel", transCancelledLis);
elem.style.opacity = null;
elem.style.transition = null;
resolve(true, e);
};
let transCancelledLis = function (e) {
elem.removeEventListener("transitionend", transEndLis);
elem.removeEventListener("transitioncancel", transCancelledLis);
elem.style.opacity = null;
elem.style.transition = null;
resolve(false, e);
};
elem.addEventListener("transitionend", transEndLis);
elem.addEventListener("transitioncancel", transCancelledLis);
});
//Nach Seitenneuzeichnen, damit chrome das immer macht (und FF auch)
requestAnimationFrame(function () {
requestAnimationFrame(function () {
elem.style.opacity = 0;
});
});
return animPromise
});
HTMLElement.prototype["fadeIn"] = Helper.nonNull(HTMLElement.prototype["fadeIn"], function (time, effect, delay) {
time = Helper.nonNull(time, 0.5);
effect = Helper.nonNull(effect, "ease-in-out");
delay = Helper.nonNull(delay, 0);
this.style.transition = "opacity " + time + "s " + effect + " " + delay + "s";
let elem = this;
let animPromise = new Promise(function (resolve) {
let transEndLis = function (e) {
elem.removeEventListener("transitionend", transEndLis);
elem.removeEventListener("transitioncancel", transCancelledLis);
elem.style.opacity = null;
elem.style.transition = null;
resolve(true, e);
};
let transCancelledLis = function (e) {
elem.removeEventListener("transitionend", transEndLis);
elem.removeEventListener("transitioncancel", transCancelledLis);
elem.style.opacity = null;
elem.style.transition = null;
resolve(false, e);
};
elem.addEventListener("transitionend", transEndLis);
elem.addEventListener("transitioncancel", transCancelledLis);
});
//Nach Seitenneuzeichnen, damit chrome das immer macht (und FF auch)
requestAnimationFrame(function () {
requestAnimationFrame(function () {
elem.style.opacity = 1;
});
});
return animPromise;
});
}
if (Node) {
Node.prototype["replaceWith"] = Helper.nonNull(Node.prototype["replaceWith"], function (elem) {
this.parentElement.replaceChild(elem, this);
});
Node.prototype["remove"] = Helper.nonNull(Node.prototype["remove"], function () {
this.parentElement.removeChild(this);
});
}
if (Element) {
Element.prototype.matches = Helper.nonNull(Element.prototype.matches, Helper.nonNull(Element.prototype["matchesSelector"], Element.prototype["webkitMatchesSelector"]));
window["Element"]["prototype"]["closest"] = Helper.nonNull(window["Element"]["prototype"]["getAll"], function (s) {
// if (!Element.prototype.matches)
// Element.prototype.matches = Element.prototype.msMatchesSelector ||
// Element.prototype.webkitMatchesSelector;
//
// if (!Element.prototype.closest)
// Element.prototype.closest = function(s) {
let el = this;
if (!document.documentElement.contains(el)) return null;
do {
if (el.matches(s)) return el;
el = el.parentElement;
} while (el !== null);
return null;
// };
});
}
window["IDBObjectStore"]["prototype"]["getAll"] = Helper.nonNull(window["IDBObjectStore"]["prototype"]["getAll"], function () {
let res = {};
let items = [];
this.openCursor().onsuccess = function (e) {
let cursor = e.target.result;
if (Helper.isNotNull(cursor)) {
items.push(cursor.value);
cursor.continue();
}
else if (Helper.isNotNull(res.onsuccess)) {
res.onsuccess({currentTarget: {result: items}});
}
};
return res;
});
}
String.prototype.startsWith = Helper.nonNull(String.prototype.startsWith, function (searchString, position) {
position = position || 0;
return this.indexOf(searchString, position) === position;
});
String.prototype.endsWith = Helper.nonNull(String.prototype.endsWith, function (searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
});
var fetch = Helper.nonNull(fetch, function (url) {
console.log("customFetch", url);
let request = null;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
}
catch (e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
}
catch (e) {
}
}
}
let resultPromise = new Promise(function (resolve) {
request.onload = function () {
let data = this.responseText;
let response = {
json: function () {
return Promise.resolve(JSON.parse(data));
},
text: function () {
return Promise.resolve(data);
}
};
resolve(response);
};
request.onerror = function (err) {
resolve(Promise.reject(err));
};
});
request.open('get', url, true);
request.send();
return resultPromise;
});
}
SystemSettings.setBasePath("/pwa/wordRotator/public/");
Translator.supportedLanguages = ["de", "en"];
Translator.markTranslations = false;
class Segment{
constructor(element){
this.rotation = 0;
this.element = element;
}
isSolved(){
return (this.rotation === 0);
}
rotate(){};
_updateElement(){};
applyRotations(rotations){
return rotations;
}
getElement()
{
return this.element;
}
}
class ParentSegment extends Segment {
constructor(element) {
super(element);
this.children = [];
this.class = "rotate-0";
}
rotate() {
this.rotation += 90;
this.rotation %= 360;
this._updateRotationClass();
}
applyRotations(rotations) {
// debugger;
this.rotation = rotations[0];
rotations.splice(0, 1);
for (let i = 0, n = this.children.length; i < n; i++) {
rotations = this.children[i].applyRotations(rotations);
}
return rotations;
}
isSolved() {
for (let i = 0, n = this.children.length; i < n; i++) {
if (!this.children[i].isSolved()) {
return false;
}
}
return super.isSolved();
}
setChildren(children) {
this.children = [];
for (let i = 0, n = children.length; i < n; i++) {
this.addChild(children[i]);
}
}
addChild(child) {
this.children.push(child);
this._updateElement();
}
_updateRotationClass() {
// this.style.transform = "rotate("+this.rotation+"deg)";
this.element.classList.remove(this.class);
this.class = "rotate-" + this.rotation;
if (this.class === "rotate-0")
{
this.class = "rotate-360";
}
this.element.classList.add(this.class);
// if (this.rotation === 0) {
// const self = this;
// self.element.classList.add("no-transition");
//
// setTimeout(() => {
// if (self.class === "rotate-0") {
// requestAnimationFrame(()=>{
//
// self.element.classList.remove("rotate-0");
// self.element.classList.remove("no-transition");
// });
// }
// }, 250);
// }
}
_updateElement() {
const childContainer = this.element.querySelector(".child-container");
childContainer.removeAllChildren();
this._updateRotationClass();
const self = this;
this.element.onclick = function () {
self.rotate();
};
for (let i = 0, n = this.children.length; i < n; i++) {
this.children[i]._updateElement();
childContainer.appendChild(this.children[i].getElement());
}
}
}
class LeafSegment extends Segment{
constructor(element, leaf) {
super(element);
this.leaf = 'A';
if (Helper.isNotNull(leaf))
{
this.setLeaf(leaf);
}
}
setLeaf(leaf)
{
this.leaf = leaf;
}
_updateElement() {
this.element.querySelector(".leaf-element").removeAllChildren().appendChild(document.createTextNode(this.leaf));
}
}
class TemplateContainer{
constructor(leafTemplate, parentTemplate, rowTemplate){
this.leafTemplate = leafTemplate;
this.parentTemplate = parentTemplate;
this.rowTemplate = rowTemplate;
}
copyLeafTemplate()
{
return Helper.cloneNode(this.leafTemplate);
}
copyParentTemplate()
{
return Helper.cloneNode(this.parentTemplate);
}
copyRowTemplate()
{
return Helper.cloneNode(this.rowTemplate);
}
}
class Level {
constructor(templateContainer) {
this.rootSegment = null;
this.words = [];
this.startRotations = [];
this.templateContainer = templateContainer;
}
setWords(words)
{
this.words = [];
for (let i = 0, n = words.length; i < n; i++) {
this.words.push(words[i].toUpperCase());
}
}
setStartRotations(rotations)
{
this.startRotations = rotations;
}
hasWon() {
return this.rootSegment.isSolved();
}
getRootSegment(){
return this.rootSegment;
}
createSegments() {};
static _createLeafsForWord(word, leafSegmentTemplate)
{
let leafSegments = [];
for (let i = 0, n = word.length; i < n; i++) {
leafSegments.push(new LeafSegment(Helper.cloneNode(leafSegmentTemplate), word.charAt(i)));
}
return leafSegments;
}
}
class RowSegment extends ParentSegment{
rotate() {}
applyRotations(rotations)
{
for (let i = 0, n = this.children.length; i < n; i++) {
rotations = this.children[i].applyRotations(rotations);
}
return rotations;
}
}
class SimpleLevel extends Level{
createSegments() {
if (this.words.length >= 2 && this.words[0].length >= 6 &&this.words[1].length >= 6){
let leafsWordOne = Level._createLeafsForWord(this.words[0], this.templateContainer.copyLeafTemplate());
let leafsWordTwo = Level._createLeafsForWord(this.words[1], this.templateContainer.copyLeafTemplate());
let segmentOne = new ParentSegment(this.templateContainer.copyParentTemplate());
let segmentTwo = new ParentSegment(this.templateContainer.copyParentTemplate());
let segmentThree = new ParentSegment(this.templateContainer.copyParentTemplate());
segmentOne.addChild(leafsWordOne[0]);
segmentOne.addChild(leafsWordOne[1]);
segmentOne.addChild(leafsWordTwo[0]);
segmentOne.addChild(leafsWordTwo[1]);
segmentTwo.addChild(leafsWordOne[2]);
segmentTwo.addChild(leafsWordOne[3]);
segmentTwo.addChild(leafsWordTwo[2]);
segmentTwo.addChild(leafsWordTwo[3]);
segmentThree.addChild(leafsWordOne[4]);
segmentThree.addChild(leafsWordOne[5]);
segmentThree.addChild(leafsWordTwo[4]);
segmentThree.addChild(leafsWordTwo[5]);
this.rootSegment = new RowSegment(this.templateContainer.copyRowTemplate());
this.rootSegment.addChild(segmentOne);
this.rootSegment.addChild(segmentTwo);
this.rootSegment.addChild(segmentThree);
this.rootSegment.applyRotations(this.startRotations);
}
}
}
class LevelSite extends AbstractSite$1{
constructor(siteManager) {
super(siteManager, "html/application/level.html", "level");
}
onConstruct(args) {
this.setTitle("Level");
return super.onConstruct(args);
}
onFirstStart() {
super.onFirstStart();
let leafSegmentTemplate = this.findBy("#segment-leaf-template");
let parentSegmentTemplate = this.findBy("#segment-parent-template");
let rowSegmentTemplate = this.findBy("#segment-row-template");
leafSegmentTemplate.id = null;
parentSegmentTemplate.id = null;
rowSegmentTemplate.id = null;
leafSegmentTemplate.remove();
parentSegmentTemplate.remove();
rowSegmentTemplate.remove();
let templateContainer = new TemplateContainer(leafSegmentTemplate, parentSegmentTemplate, rowSegmentTemplate);
let level = new SimpleLevel(templateContainer);
level.setWords([
"Dynamo",
"Abhang"
]);
level.setStartRotations([0,90,180]);
level.createSegments();
level.getRootSegment()._updateElement();
this.findBy("#level").appendChild(level.getRootSegment().getElement());
}
}
applyPolyfills();
ThemeManager.addTheme(new Theme('red', ''));
ThemeManager.addTheme(new Theme("blue", "blue"));
ThemeManager.addTheme(new Theme("black", "black"));
ThemeManager.addTheme(new Theme("green", "green"));
ThemeManager.addTheme(new Theme("pink", "pink"));
ShareManager.addShareButton(new WhatsappShareButton('img/whatsapp.svg'));
ShareManager.addShareButton(new SmsShareButton('img/sms.svg'));
ShareManager.addShareButton(new TelegramShareButton('img/telegram.svg'));
// ShareManager.addShareButton(new CopyShareButton('img/copy.svg'));
let app = new App();
// app.addDeepLink("policy", PrivatePolicySite.name);
app.setAddThemeAction(true);
app.addDefaultAction(Translator.generateChangeLanguageMenuAction());
//bridge für Android
// window["ThemeManager"] = ThemeManager;
// window["ThemeManager"]["addChangeListener"] = ThemeManager.addChangeListener;
// window["app"] = app;
// window["app"]["refreshCurrentSite"] = app.refreshCurrentSite;
// window["Translator"] = Translator;
// window["Translator"]["setLanguage"] = Translator.setLanguage;
InitPromise.resolve(app).then(function(){
app.start(LevelSite);
Translator.setLanguage("de");
});