OpoTests/Public/ecma/Application/OpoTests.ecma.js

323 lines
11 KiB
JavaScript

"use strict";
import {SettingsManager} from "../Managers/SettingsManager.ecma.js";
import {I18NManager} from "../Managers/I18NManager.ecma.js";
import {IdentifiersManager} from "../Managers/IdentifiersManager.ecma.js";
import {Components} from "./Components.ecma.js";
import {Utils} from "../Utils/Utils.ecma.js";
import {Check} from "../Utils/Check.ecma.js";
import {BaseView} from "../Views/BaseView.ecma.js";
import {MainFormView} from "../Views/MainFormView.ecma.js";
import {TestsView} from "../Views/TestsView.ecma.js";
import {UserView} from "../Views/UserView.ecma.js";
import {CookiesManager} from "../Managers/CookiesManager.ecma.js";
/**
* @class OpoTests
* @constructor
* @param {?(Object.<string, any|null>|Array.<any|null>)} inputs
* @returns {void}
* @access public
* @static
*/
export const OpoTests = (function(){
/**
* @callback opo_tests_preload_callback
* @param {?HTMLElement} item
* @param {!boolean} asynchronous
* @param {!boolean} success
* @returns {void}
*/
/**
* @callback opo_tests_load_file_callback
* @param {?string} responseText
* @param {!number} status
* @param {!number} readyState
* @param {!string} message
* @param {!boolean} success
* @returns {void}
*/
/**
* @callback opo_tests_load_file_end_callback
* @param {!string} message
* @returns {void}
*/
/**
* @callback opo_tests_default_callback
* @returns {void}
*/
/**
* @callback opo_tests_json_each_callback
* @param {!(Object.<string, any|null>|Array.<any|null>)} item
* @param {!opo_tests_default_callback} callback
* @returns {void}
*/
/**
* @constructs OpoTests
* @param {?(Object.<string, any|null>|Array.<any|null>)} inputs
* @returns {void}
* @access private
* @static
*/
const OpoTests = function(inputs = null){
/** @type {OpoTests} */
const self = this;
this.database = [];
/** @type {SettingsManager} */
this.settings = new SettingsManager(self, inputs);
/** @type {I18NManager} */
this.i18n = new I18NManager(self);
/** @type {IdentifiersManager} */
this.identifiers = new IdentifiersManager(self);
/** @type {Components} */
this.components = this.comp = new Components(self);
/** @type {BaseView} */
this.base = new BaseView(self);
/** @type {MainFormView} */
this.main_form = new MainFormView(self);
/** @type {TestsView} */
this.tests = new TestsView(self);
/** @type {UserView} */
this.user = new UserView(self);
this.cookies = new CookiesManager(self);
/**
* @returns {void}
* @access private
*/
const end_constructor = () => {
Utils.execute_array(["default_database_files", "database_files"], (key, next_callback) => {
Utils.execute_array(self.settings.get(key, null, []), (file, next_callback) => {
self.load_file(file, (data, ..._) => {
/** @type {Array.<string>|null} */
const json = data ? JSON.parse(data) : null;
if(Check.is_array(json))
load_database(json, () => {
next_callback();
});
else
next_callback();
});
}, next_callback);
}, () => {
console.log(["database", self.database]);
self.main_form.build();
});
};
/**
* @returns {void}
* @access private
*/
const constructor = () => {
self.settings.start(() => {
self.i18n.start(() => {
self.cookies.start(() => {
self.preload(self.settings.get("position", null, "body"), (position, asynchronous, success) => {
if(success && position){
Utils.html(position, self.base.build());
if(self.cookies.get("ot") == "1")
Utils.execute(end_constructor);
else
self.user.build_login(end_constructor);
};
});
});
});
});
};
/**
* @param {!(string|HTMLElement)} selector
* @param {!opo_tests_preload_callback} callback
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
* @returns {void}
* @access public
*/
this.preload = (selector, callback, inputs = null) => {
if(!Check.is_function(callback))
return;
if(Check.is_html_item(selector))
return Utils.execute(callback, selector, false, true);
if(!Check.is_string(selector))
return Utils.execute(callback, null, false, false);
/** @type {HTMLElement|null} */
let item;
try{
item = document.querySelector(selector)
}catch(e){
return Utils.execute(callback, null, false, false);
};
if(item)
return Utils.execute(callback, item, false, true);
/** @type {number} */
const date = Date.now(),
/** @type {number} */
timeout = self.settings.get(["preload_timeout", "timeout"], inputs, 2000);
/** @type {number} */
let interval = setInterval(() => {
if(item = document.querySelector(selector)){
clearInterval(interval);
Utils.execute(callback, item, true, true);
}else if(Date.now() - date >= timeout){
clearInterval(interval);
Utils.execute(callback, null, true, false);
};
}, 1000 / self.settings.get(["frames_per_second", "fps"], inputs, 24));
};
/**
* @param {!string} url
* @param {!opo_tests_load_file_callback} callback
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
* @returns {XMLHttpRequest}
* @access public
*/
this.load_file = (url, callback, inputs = null) => {
/** @type {boolean} */
let ended = false;
/** @type {XMLHttpRequest} */
const ajax = new XMLHttpRequest(),
/** @type {opo_tests_load_file_end_callback} */
end = message => {
!ended && (ended = true) && Utils.execute(callback, ajax.responseText, ajax.status, ajax.readyState, message, message == "OK");
},
/** @type {number} */
date = Date.now(),
/** @type {number} */
timeout = self.settings.get(["ajax_timeout", "timeout"], inputs, 2000);
ajax.open("GET", url, true);
ajax.timeout = timeout;
ajax.onload = () => {
if(ended)
return;
if(ajax.readyState == 4)
end((ajax.status >= 200 && ajax.status < 300) || [301, 302, 304].includes(ajax.status) ? "OK" : "HTTP_ERROR");
else if(Date.now() - date >= timeout)
end("FORCED_TIMEOUT");
};
ajax.send(null);
ajax.ontimeout = () => end("TIMEOUT");
ajax.onerror = () => end("ERROR");
ajax.onabort = () => end("ABORTED");
return ajax;
};
/**
* @param {!Array.<string>} files
* @param {!opo_tests_default_callback} callback
* @returns {void}
* @access private
*/
const load_database = (files, callback) => {
Utils.execute_array(Check.is_array(files) ? files : [files], (file, next_callback) => {
self.load_file(file, (responseText, status, readyState, message, success) => {
if(success && responseText){
try{
self.database.push(...JSON.parse(responseText).map(item => {
item.queries = item.queries.filter(Check.is_dictionary);
return item;
}));
}catch(exception){
console.log(responseText);
console.error([file, exception]);
};
}else
console.error([file, responseText, message.toLowerCase(), status, readyState]);
next_callback();
});
}, () => {
Utils.execute(callback);
});
};
/**
* @param {!string} message
* @param {?opo_tests_default_callback} [callback = null]
* @param {?string} [default_text = null]
* @return {void}
* @access public
*/
this.alert = (message, callback, default_text = null) => {
alert(self.i18n.get(message, null, default_text));
Utils.execute(callback);
};
/**
* @param {?(Object.<string, any|null>|Array.<any|null>|string)} data
* @param {!opo_tests_json_each_callback} each_callback
* @param {?opo_tests_default_callback} [end_callback = null]
* @param {!boolean} [only_dictionaries = false]
* @returns {void}
* @access public
*/
this.load_json = (data, each_callback, end_callback = null, only_dictionaries = false) => {
if(Check.is_array(data)){
if(only_dictionaries)
Utils.execute_array(data, (item, next_callback) => {
self.load_json(item, each_callback, next_callback, only_dictionaries);
}, end_callback);
else{
Utils.execute(each_callback, data);
Utils.execute(end_callback);
};
}else if(Check.is_dictionary(data)){
Utils.execute(each_callback, data);
Utils.execute(end_callback);
}else if(Check.is_string(data)){
/** @type {Array.<any|null>|Object.<string, any|null>|null} */
let json;
try{
if(json = JSON.parse(data)){
self.load_json(json, each_callback, end_callback, only_dictionaries);
return;
};
}catch(exception){};
self.load_file(data, (responseText, status, readyState, message, success) => {
if(success && responseText){
try{
if(json = JSON.parse(responseText)){
self.load_json(json, each_callback, end_callback, only_dictionaries);
return;
};
}catch(exception){};
};
Utils.execute(end_callback);
});
}else
Utils.execute(end_callback);
};
constructor();
};
return OpoTests;
})();