- /**
- * Содержит методы обработки событий __при запуске__ программы, __перед закрытием__,<br />
- * при обновлении файлов __ApplicationCache__, а так же, при переходе в __offline__ и __online__
- *
- * События развиваются в такой последовательности:
- *
- * 1) выясняем, совместим ли браузер. В зависимости от параметров url и параметров по умолчанию,
- * может произойти переход в ChromeStore или другие действия
- *
- * 2) анализируем AppCache, при необходимости обновляем скрипты и перезагружаем страницу
- *
- * 3) инициализируем $p.wsql и комбинируем параметры работы программы с параметрами url
- *
- * 4) если режим работы предполагает использование построителя, подключаем слушатель его событий.
- * по событию построителя "ready", выполняем метод initMainLayout() объекта $p.iface.
- * Метод initMainLayout() переопределяется во внешним, по отношению к ядру, модуле
- *
- * © Evgeniy Malyarov http://www.oknosoft.ru 2014-2016
- *
- * @module common
- * @submodule events
- */
-
- /**
- * ### Обработчики событий приложения
- *
- * Cм. так же, модули {{#crossLinkModule "events"}}{{/crossLinkModule}} и {{#crossLinkModule "events_browser"}}{{/crossLinkModule}}
- *
- * @class AppEvents
- * @static
- * @menuorder 30
- * @tooltip Движок событий
- */
- function AppEvents() {
-
- this.__define({
-
- /**
- * ### Запускает процесс инициализаци параметров и метаданных
- *
- * @method run
- * @for AppEvents
- *
- */
- init: {
- value: function () {
- $p.__define("job_prm", {
- value: new JobPrm(),
- writable: false
- });
- $p.wsql.init_params();
- }
- },
-
- /**
- * ### Добавляет объекту методы генерации и обработки событий
- *
- * @method do_eventable
- * @for AppEvents
- * @param obj {Object} - объект, которому будут добавлены eventable свойства
- */
- do_eventable: {
- value: function (obj) {
-
- function attach(name, func) {
- name = String(name).toLowerCase();
- if (!this._evnts.data[name])
- this._evnts.data[name] = {};
- var eventId = $p.utils.generate_guid();
- this._evnts.data[name][eventId] = func;
- return eventId;
- }
-
- function detach(eventId) {
-
- if(!eventId){
- return detach_all.call(this);
- }
-
- for (var a in this._evnts.data) {
- var k = 0;
- for (var b in this._evnts.data[a]) {
- if (b == eventId) {
- this._evnts.data[a][b] = null;
- delete this._evnts.data[a][b];
- } else {
- k++;
- }
- }
- if (k == 0) {
- this._evnts.data[a] = null;
- delete this._evnts.data[a];
- }
- }
- }
-
- function detach_all() {
- for (var a in this._evnts.data) {
- for (var b in this._evnts.data[a]) {
- this._evnts.data[a][b] = null;
- delete this._evnts.data[a][b];
- }
- this._evnts.data[a] = null;
- delete this._evnts.data[a];
- }
- }
-
- function call(name, params) {
- name = String(name).toLowerCase();
- if (this._evnts.data[name] == null)
- return true;
- var r = true;
- for (var a in this._evnts.data[name]) {
- r = this._evnts.data[name][a].apply(this, params) && r;
- }
- return r;
- }
-
- function ontimer() {
-
- for(var name in this._evnts.evnts){
- var l = this._evnts.evnts[name].length;
- if(l){
- for(var i=0; i<l; i++){
- this.emit(name, this._evnts.evnts[name][i]);
- }
- this._evnts.evnts[name].length = 0;
- }
- }
-
- this._evnts.timer = 0;
- }
-
- obj.__define({
-
- _evnts: {
- value: {
- data: {},
- timer: 0,
- evnts: {}
- }
- },
-
- on: {
- value: attach
- },
-
- attachEvent: {
- value: attach
- },
-
- off: {
- value: detach
- },
-
- detachEvent: {
- value: detach
- },
-
- detachAllEvents: {
- value: detach_all
- },
-
- checkEvent: {
- value: function(name) {
- name = String(name).toLowerCase();
- return (this._evnts.data[name] != null);
- }
- },
-
- callEvent: {
- value: call
- },
-
- emit: {
- value: call
- },
-
- emit_async: {
- value: function callEvent(name, params){
-
- if(!this._evnts.evnts[name])
- this._evnts.evnts[name] = [];
-
- this._evnts.evnts[name].push(params);
-
- if(this._evnts.timer)
- clearTimeout(this._evnts.timer);
-
- this._evnts.timer = setTimeout(ontimer.bind(this), 4);
- }
- }
-
- });
- }
- }
- });
-
- // если мы внутри браузера и загружен dhtmlx, переносим в AppEvents свойства dhx4
- if(typeof window !== "undefined" && window.dhx4){
- for(var p in dhx4){
- this[p] = dhx4[p];
- delete dhx4[p];
- }
- window.dhx4 = this;
-
- }else if(typeof WorkerGlobalScope === "undefined"){
-
- // мы внутри Nodejs
-
- this.do_eventable(this);
-
- }
-
- }
-
- /**
- * ### Параметры работы программы
- * - Хранит глобальные настройки варианта компиляции (_Заказ дилера_, _Безбумажка_, _Демо_ и т.д.)
- * - Настройки извлекаются из файла "settings" при запуске приложения и дополняются параметрами url,
- * которые могут быть переданы как через search (?), так и через hash (#)
- * - см. так же, {{#crossLink "WSQL/get_user_param:method"}}{{/crossLink}} и {{#crossLink "WSQL/set_user_param:method"}}{{/crossLink}} - параметры, изменяемые пользователем
- *
- * @class JobPrm
- * @static
- * @menuorder 04
- * @tooltip Параметры приложения
- */
- function JobPrm(){
-
- function base_url(){
- return $p.wsql.get_user_param("rest_path") || $p.job_prm.rest_path || "/a/zd/%1/odata/standard.odata/";
- }
-
- function parse_url(){
-
- function parse(url_prm){
- var prm = {}, tmp = [], pairs;
-
- if(url_prm.substr(0, 1) === "#" || url_prm.substr(0, 1) === "?")
- url_prm = url_prm.substr(1);
-
- if(url_prm.length > 2){
-
- pairs = decodeURI(url_prm).split('&');
-
- // берём параметры из url
- for (var i in pairs){ //разбиваем пару на ключ и значение, добавляем в их объект
- tmp = pairs[i].split('=');
- if(tmp[0] == "m"){
- try{
- prm[tmp[0]] = JSON.parse(tmp[1]);
- }catch(e){
- prm[tmp[0]] = {};
- }
- }else
- prm[tmp[0]] = tmp[1] || "";
- }
- }
-
- return prm;
- }
-
- return parse(location.search)._mixin(parse(location.hash));
- }
-
- this.__define({
-
- /**
- * Осуществляет синтаксический разбор параметров url
- * @method parse_url
- * @return {Object}
- */
- parse_url: {
- value: parse_url
- },
-
- offline: {
- value: false,
- writable: true
- },
-
- local_storage_prefix: {
- value: "",
- writable: true
- },
-
- create_tables: {
- value: true,
- writable: true
- },
-
- /**
- * Содержит объект с расшифровкой параметров url, указанных при запуске программы
- * @property url_prm
- * @type {Object}
- * @static
- */
- url_prm: {
- value: typeof window != "undefined" ? parse_url() : {}
- },
-
- /**
- * Адрес стандартного интерфейса 1С OData
- * @method rest_url
- * @return {string}
- */
- rest_url: {
- value: function () {
- var url = base_url(),
- zone = $p.wsql.get_user_param("zone", $p.job_prm.zone_is_string ? "string" : "number");
- if(zone)
- return url.replace("%1", zone);
- else
- return url.replace("%1/", "");
- }
- },
-
- /**
- * Адрес http интерфейса библиотеки интеграции
- * @method irest_url
- * @return {string}
- */
- irest_url: {
- value: function () {
- var url = base_url(),
- zone = $p.wsql.get_user_param("zone", $p.job_prm.zone_is_string ? "string" : "number");
- url = url.replace("odata/standard.odata", "hs/rest");
- if(zone)
- return url.replace("%1", zone);
- else
- return url.replace("%1/", "");
- }
- }
- });
-
- // подмешиваем параметры, заданные в файле настроек сборки
- $p.eve.callEvent("settings", [this]);
-
- // подмешиваем параметры url
- // Они обладают приоритетом над настройками по умолчанию и настройками из settings.js
- for(var prm_name in this){
- if(prm_name !== "url_prm" && typeof this[prm_name] !== "function" && this.url_prm.hasOwnProperty[prm_name])
- this[prm_name] = this.url_prm[prm_name];
- }
-
- }
-
- /**
- * ### Модификатор отложенного запуска
- * Служебный объект, реализующий отложенную загрузку модулей,<br />
- * в которых доопределяется (переопределяется) поведение объектов и менеджеров конкретных типов
- *
- * @class Modifiers
- * @constructor
- * @menuorder 62
- * @tooltip Внешние модули
- */
- function Modifiers(){
-
- var methods = [];
-
- /**
- * Добавляет метод в коллекцию методов для отложенного вызова
- * @method push
- * @param method {Function} - функция, которая будет вызвана после инициализации менеджеров объектов данных
- */
- this.push = function (method) {
- methods.push(method);
- };
-
- /**
- * Отменяет подписку на событие
- * @method detache
- * @param method {Function}
- */
- this.detache = function (method) {
- var index = methods.indexOf(method);
- if(index != -1)
- methods.splice(index, 1);
- };
-
- /**
- * Отменяет все подписки
- * @method clear
- */
- this.clear = function () {
- methods.length = 0;
- };
-
- /**
- * Загружает и выполняет методы модификаторов
- * @method execute
- */
- this.execute = function (context) {
-
- // выполняем вшитые в сборку модификаторы
- var res, tres;
- methods.forEach(function (method) {
- if(typeof method === "function")
- tres = method(context);
- else
- tres = $p.injected_data[method](context);
- if(res !== false)
- res = tres;
- });
- return res;
- };
-
- /**
- * выполняет подключаемые модификаторы
- * @method execute_external
- * @param data
- */
- this.execute_external = function (data) {
-
- var paths = $p.wsql.get_user_param("modifiers");
-
- if(paths){
- paths = paths.split('\n').map(function (path) {
- if(path)
- return new Promise(function(resolve, reject){
- $p.load_script(path, "script", resolve);
- });
- else
- return Promise.resolve();
- });
- }else
- paths = [];
-
- return Promise.all(paths)
- .then(function () {
- this.execute(data);
- }.bind(this));
- };
-
- }
-
-
-