Files
murom/модули/муром.пу_1.0.0.js

766 lines
26 KiB
JavaScript
Raw Permalink 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.

/*
*
* Внешний вид
*
*/
function задатьВнешнийВид()
{
var вид = document.createElement("style");
document.head.appendChild(вид);
вид.innerHTML =
`
.муром-кнопка
{
padding: 0.5em 2em 0.5em 2em;
margin-right: 0.5em;
float: right;
color: #222;
font-family: sans-serif;
border: 1px solid #ddd;
background-color: transparent;
cursor: pointer;
text-transform: uppercase;
-webkit-transition-duration: 0.2s; /* Safari */
transition-duration: 0.2s;
}
.муром-кнопка:hover
{
border: 1px solid #222;
}
.муром-отступ-по-сторонам
{
margin-left: 0.5em;
margin-right: 0.5em;
}
`;
}
/*
*
* Список модулей
*
*/
function СписокМодулей()
{
var я = this;
this.создатьИнтерфейс();
this.задатьВид();
this.выбрали = new Уведомитель();
this.выбрали.подписать(function(){
я.отобразитьВыбор();
});
}
СписокМодулей.prototype.создатьИнтерфейс = function()
{
// Помещаем таблицу в div для реализации промотки.
this.иф = document.createElement("div");
this.таблица = document.createElement("table");
this.иф.appendChild(this.таблица);
};
СписокМодулей.prototype.задатьВид = function()
{
this.иф.style.cssText =
`
overflow: auto;
height: 18.5em;
border: 1px solid #ddd;
/*
padding: 0.5em;
margin: 0.5em;
*/
`;
this.таблица.style.cssText =
`
color: #666666;
font-family: sans-serif;
cursor: default;
border-collapse: collapse;
`;
};
СписокМодулей.prototype.очистить = function()
{
while (this.таблица.rows.length)
{
this.таблица.deleteRow(0);
};
};
СписокМодулей.prototype.добавитьЭлемент = function(статус, имя)
{
var статусHTML = "";
if (статус)
{
статусHTML = "checked";
}
var ряд = this.таблица.insertRow();
var ячейка = 0;
var номер = ряд.insertCell(ячейка++);
номер.innerHTML = this.таблица.rows.length - 1;
номер.style.cssText = "padding: 0.5em;";
var вкл = ряд.insertCell(ячейка++);
вкл.innerHTML = `<input type="checkbox" disabled ` + статусHTML + `></input>`;
var название = ряд.insertCell(ячейка++);
название.innerHTML = имя;
название.style.cssText = "padding: 0.5em; width: 100%;";
};
СписокМодулей.prototype.отобразитьСписок = function(список)
{
this.очистить();
for (var номер in список)
{
var элемент = список[номер];
var статус = элемент[0];
var имя = элемент[1];
this.добавитьЭлемент(статус, имя);
}
};
СписокМодулей.prototype.улавливатьВыборЭлемента = function(номер)
{
var я = this;
var ряд = this.таблица.rows[номер]
ряд.onclick = function()
{
я.выборРанее = я.выбор;
я.выбор = номер;
я.выбрали.уведомить();
};
};
СписокМодулей.prototype.улавливатьВыбор = function()
{
this.выборРанее = null;
this.выбор = null;
for (var номер = 0; номер < this.таблица.rows.length; ++номер)
{
this.улавливатьВыборЭлемента(номер);
}
};
СписокМодулей.prototype.отобразитьВыбор = function()
{
if (this.выборРанее != null)
{
var ряд = this.таблица.rows[this.выборРанее];
ряд.style.backgroundColor = null;
}
var ряд = this.таблица.rows[this.выбор];
ряд.style.backgroundColor = "#eee";
};
СписокМодулей.prototype.задатьСписок = function(список)
{
this.отобразитьСписок(список);
this.улавливатьВыбор();
};
СписокМодулей.prototype.выбрать = function(номер)
{
var ряд = this.таблица.rows[номер];
ряд.scrollIntoView();
ряд.onclick();
};
СписокМодулей.prototype.обновитьЭлемент = function(номер, статус, имя)
{
var ряд = this.таблица.rows[номер];
ряд.cells[1].childNodes[0].checked = статус;
ряд.cells[2].innerHTML = имя;
};
СписокМодулей.prototype.удалитьЭлемент = function(номер)
{
var ряд = this.таблица.rows[номер];
ряд.parentNode.removeChild(ряд);
}
/*
*
* Тест списка модулей
*
*/
function ТестСпискаМодулей()
{
this.создатьИнтерфейс();
}
ТестСпискаМодулей.prototype.создатьИнтерфейс = function()
{
var я = this;
this.иф = document.createElement("div");
this.список = new СписокМодулей();
this.иф.appendChild(this.список.иф);
var модули = [
[true, "муром.загрузка_1.0.0"],
[true, "муром.uuid_1.0.0"],
[true, "Уведомитель_1.0.0"],
[false, "uikit_3.2.0.css"],
[false, "uikit_3.2.0.js"],
[false, "ПанельУправления.UIKit"],
[false, анельУправления_1.0.0"],
];
this.список.задатьСписок(модули);
this.список.выбрать(0);
this.создатьКнопку("Выбрать последний", function(){
console.log("выбрать");
я.список.выбрать(модули.length - 1);
});
this.создатьКнопку("Обновить последний", function(){
я.список.обновитьЭлемент(модули.length - 1, true, "Новое имя");
});
this.создатьКнопку("Удалить последний", function(){
я.список.удалитьЭлемент(модули.length - 1);
});
this.создатьКнопку("Добавить", function(){
я.список.добавитьЭлемент(true, "Новый-599");
var номер = я.список.таблица.rows.length - 1;
я.список.улавливатьВыборЭлемента(номер);
я.список.выбрать(номер);
});
};
ТестСпискаМодулей.prototype.создатьКнопку = function(имя, реакция)
{
var кнопка = document.createElement("button");
кнопка.innerHTML = имя;
this.иф.appendChild(кнопка);
кнопка.onclick = реакция;
};
/*
*
* Свойства модуля
*
*/
function СвойстваМодуля()
{
this.создатьИнтерфейс();
this.изменилиНомер = new Уведомитель();
this.настроитьНомер();
this.изменилиИмя = new Уведомитель();
this.настроитьИмя();
this.изменилиСтатус = new Уведомитель();
this.настроитьСтатус();
this.удалить = new Уведомитель();
this.настроитьУдаление();
}
СвойстваМодуля.prototype.создатьИнтерфейс = function()
{
this.иф = document.createElement("div");
this.иф.style.cssText =
`
border: 1px solid #ddd;
/*
padding: 0.5em;
margin: 0.5em;
*/
color: #666666;
font-family: sans-serif;
`;
this.таблица = document.createElement("table");
this.иф.appendChild(this.таблица);
};
Object.defineProperty(СвойстваМодуля.prototype, "номер", {
get: function()
{
return Number(this.полеНомер.value);
},
set: function(значение)
{
this.полеНомер.value = значение;
}
});
СвойстваМодуля.prototype.настроитьНомер = function()
{
var я = this;
var ряд = this.таблица.insertRow();
var ячейка = 0;
var ключ = ряд.insertCell(ячейка++);
ключ.innerHTML = "Номер:";
ключ.style.cssText = "padding: 0.5em;";
var значение = ряд.insertCell(ячейка++);
this.полеНомер = document.createElement("input");
this.полеНомер.type = "number";
this.полеНомер.min = 0;
значение.style.cssText = "width: 100%; padding: 0.5em;";
this.полеНомер.style.cssText = "width: 100%;";
значение.appendChild(this.полеНомер);
this.полеНомер.oninput = function()
{
я.изменилиНомер.уведомить();
};
};
Object.defineProperty(СвойстваМодуля.prototype, "имя", {
get: function()
{
return this.полеИмя.value;
},
set: function(значение)
{
this.полеИмя.value = значение;
}
});
СвойстваМодуля.prototype.настроитьИмя = function()
{
var я = this;
var ряд = this.таблица.insertRow();
var ячейка = 0;
var ключ = ряд.insertCell(ячейка++);
ключ.innerHTML = "Имя:";
ключ.style.cssText = "padding: 0.5em;";
var значение = ряд.insertCell(ячейка++);
this.полеИмя = document.createElement("input");
значение.style.cssText = "width: 100%; padding: 0.5em;";
this.полеИмя.style.cssText = "width: 100%;";
значение.appendChild(this.полеИмя);
this.полеИмя.oninput = function()
{
я.изменилиИмя.уведомить();
};
};
Object.defineProperty(СвойстваМодуля.prototype, "статус", {
get: function()
{
return this.переключатель.checked;
},
set: function(значение)
{
this.переключатель.checked = значение;
}
});
СвойстваМодуля.prototype.настроитьСтатус = function()
{
var я = this;
var ряд = this.таблица.insertRow();
var ячейка = 0;
var ключ = ряд.insertCell(ячейка++);
ключ.innerHTML = "Исполнять:";
ключ.style.cssText = "padding: 0.5em;";
var значение = ряд.insertCell(ячейка++);
this.переключатель = document.createElement("input");
this.переключатель.type = "checkbox";
this.переключатель.style.cssText = "padding: 0.5em;";
значение.appendChild(this.переключатель);
this.переключатель.onchange = function()
{
я.изменилиСтатус.уведомить();
};
ключ.onclick = function()
{
я.переключатель.checked = !я.переключатель.checked;
я.изменилиСтатус.уведомить();
};
};
СвойстваМодуля.prototype.настроитьУдаление = function()
{
var я = this;
var ряд = this.таблица.insertRow();
var ячейка = 0;
ряд.insertCell(ячейка++);
var значение = ряд.insertCell(ячейка++);
this.кнопкаУдалить = document.createElement("button");
this.кнопкаУдалить.innerHTML = "Удалить";
this.кнопкаУдалить.classList.add("муром-кнопка");
значение.appendChild(this.кнопкаУдалить);
this.кнопкаУдалить.onclick = function()
{
я.удалить.уведомить();
};
};
/*
*
* Тест свойства модуля
*
*/
function ТестСвойстваМодуля()
{
this.создатьИнтерфейс();
}
ТестСвойстваМодуля.prototype.создатьИнтерфейс = function()
{
var я = this;
this.иф = document.createElement("div");
this.свойства = new СвойстваМодуля();
this.иф.appendChild(this.свойства.иф);
this.свойства.изменилиНомер.подписать(function(){
console.log("номер: '" + я.свойства.номер + "'");
});
this.свойства.изменилиИмя.подписать(function(){
console.log("имя: '" + я.свойства.имя + "'");
});
this.свойства.изменилиСтатус.подписать(function(){
console.log("статус: '" + я.свойства.статус + "'");
});
this.свойства.удалить.подписать(function(){
console.log("удалить модуль '" + я.свойства.имя + "'");
});
};
/*
*
* Модули
*
*/
function Модули()
{
}
Модули.prototype.свойства = function(номер)
{
return murom.moduleProperties(номер);
};
Модули.prototype.задатьСвойства = function(номер, свойства)
{
var м = муром.модули[номер];
м[2] = свойства;
};
Модули.prototype.статус = function(номер)
{
return murom.moduleStatus(номер);
};
Модули.prototype.задатьСтатус = function(номер, статус)
{
var св = this.свойства(номер);
св["status"] = статус;
this.задатьСвойства(номер, св);
};
Модули.prototype.задатьИмя = function(номер, имя)
{
var м = муром.модули[номер];
м[0] = имя;
};
Модули.prototype.задатьНомер = function(старый, новый)
{
//console.log("задать номер. '" + старый + "' -> '" + новый + "'");
var модуль = муром.модули[старый];
// Удаляем старую запись.
муром.модули.splice(старый, 1);
// Добавляем модуль в новую позицию.
муром.модули.splice(новый, 0, модуль);
};
/*
*
* Панель управления
*
*/
function ПанельУправления()
{
this.модули = new Модули();
this.создатьОснову();
this.создатьСохранениеСкачиваниеДобавление();
this.создатьСписокМодулей();
this.создатьСвойстваМодуля();
}
ПанельУправления.prototype.создатьОбёрткуЯчейку = function()
{
var обёртка = document.createElement("table");
обёртка.style.cssText = "width: 100%;";
var ряд = обёртка.insertRow();
var ячейка = ряд.insertCell();
return [обёртка, ячейка];
};
ПанельУправления.prototype.создатьОснову = function()
{
this.иф = document.createElement("table");
this.иф.style.cssText = "width: 100%;";
var ряд = this.иф.insertRow();
this.лево = ряд.insertCell();
this.лево.style.cssText = "width: 100%;";
var право = ряд.insertCell();
право.style.cssText = "height: 100%;";
this.кнопки = document.createElement("table");
this.кнопки.style.cssText = "height: 100%;";
право.appendChild(this.кнопки);
ряд = this.иф.insertRow();
this.низ = ряд.insertCell();
this.низ.colSpan = 2;
};
ПанельУправления.prototype.создатьСписокМодулей = function()
{
this.список = new СписокМодулей();
this.список.задатьСписок(this.списокМодулей());
var оя = this.создатьОбёрткуЯчейку();
this.лево.appendChild(оя[0]);
оя[1].appendChild(this.список.иф);
};
ПанельУправления.prototype.создатьСвойстваМодуля = function()
{
this.свойства = new СвойстваМодуля();
оя = this.создатьОбёрткуЯчейку();
this.низ.appendChild(оя[0]);
оя[1].appendChild(this.свойства.иф);
};
ПанельУправления.prototype.списокМодулей = function()
{
var список = [];
for (var номер in муром.модули)
{
var м = муром.модули[номер];
var статус = this.модули.статус(номер);
var имя = м[0];
var элемент = [статус, имя];
список.push(элемент);
}
return список;
};
ПанельУправления.prototype.создатьКнопку = function(имя, уведомитель)
{
var кнопка = document.createElement("button");
кнопка.innerHTML = имя;
кнопка.style.cssText = "width: 100%;";
кнопка.classList.add("муром-кнопка");
кнопка.onclick = function()
{
уведомитель.уведомить();
};
return кнопка;
};
ПанельУправления.prototype.создатьСохранениеСкачиваниеДобавление = function()
{
var я = this;
var ряд = this.кнопки.insertRow();
var ячейка = ряд.insertCell();
this.сохранить = new Уведомитель();
this.кнопкаСохранить = this.создатьКнопку("Сохранить", this.сохранить);
ячейка.appendChild(this.кнопкаСохранить);
ряд = this.кнопки.insertRow();
ячейка = ряд.insertCell();
this.скачать = new Уведомитель();
this.кнопкаСкачать = this.создатьКнопку("Скачать", this.скачать);
ячейка.appendChild(this.кнопкаСкачать);
// Пробел.
ряд = this.кнопки.insertRow();
ячейка = ряд.insertCell();
ячейка.style.cssText = "height: 100%;";
ряд = this.кнопки.insertRow();
ячейка = ряд.insertCell();
this.добавить = new Уведомитель();
this.кнопкаДобавить = this.создатьКнопку("Добавить", this.добавить);
ячейка.appendChild(this.кнопкаДобавить);
};
ПанельУправления.prototype.имяФайла = function()
{
var путь = window.location.pathname;
var имя = путь.split("/").pop();
return decodeURI(имя);
};
function запуститьПУ()
{
var пу = new ПанельУправления();
муром.пу = пу;
var области = муром.создатьЛевуюПравуюОбласти();
var по = области[1];
по.appendChild(пу.иф);
муром.создатьРедакторВЛевойОбласти();
var список = пу.список;
var свойства = пу.свойства;
var модули = пу.модули;
function отобразитьКодВыбранногоМодуля()
{
var модуль = муром.модули[список.выбор];
var код = муром.atob(модуль[1]);
муром.редактор.session.setValue(код);
}
function отобразитьСвойстваВыбранногоМодуля()
{
var модуль = муром.модули[список.выбор];
свойства.номер = список.выбор;
свойства.имя = модуль[0];
свойства.статус = пу.модули.статус(список.выбор);
}
список.выбрали.подписатьМного([
отобразитьКодВыбранногоМодуля,
отобразитьСвойстваВыбранногоМодуля,
]);
function обновитьСтатусМодуля()
{
var номер = список.выбор;
var имя = свойства.имя;
var статус = свойства.статус;
модули.задатьСтатус(номер, статус);
список.обновитьЭлемент(номер, статус, имя);
}
свойства.изменилиСтатус.подписать(обновитьСтатусМодуля);
function обновитьИмяМодуля()
{
var номер = список.выбор;
var имя = свойства.имя;
var статус = свойства.статус;
модули.задатьИмя(номер, имя);
список.обновитьЭлемент(номер, статус, имя);
}
свойства.изменилиИмя.подписать(обновитьИмяМодуля);
function обновитьНомерМодуля()
{
var старый = список.выбор;
var новый = свойства.номер;
if (старый == новый)
{
return;
}
if (новый > муром.модули.length - 1)
{
новый = муром.модули.length - 1;
}
модули.задатьНомер(старый, новый);
список.задатьСписок(пу.списокМодулей());
список.выбрать(новый);
}
свойства.изменилиНомер.подписать(обновитьНомерМодуля);
function добавитьМодуль()
{
var число = Math.floor(Math.random() * Math.floor(1000));
var имя = "новый-" + число;
var код = `console.log("НАДО Добавить код в модуль '` + имя + `'");`;
var модуль = [имя, муром.btoa(код)];
муром.модули.push(модуль);
var модули = пу.списокМодулей();
список.задатьСписок(модули);
список.выбрать(модули.length - 1);
}
пу.добавить.подписать(добавитьМодуль);
function удалитьМодуль()
{
var номер = список.выбор;
var статус = пу.модули.статус(номер);
if (статус)
{
alert("ОШИБКА Удалить можно лишь неисполняемый модуль");
return;
}
// Удалить выбранный модуль.
муром.модули.splice(номер, 1);
--номер;
if (номер < 0)
{
номер = 0;
}
var модули = пу.списокМодулей();
список.задатьСписок(модули);
список.выбрать(номер);
}
свойства.удалить.подписать(удалитьМодуль);
function сохранитьВыбранныйМодуль()
{
var модуль = муром.модули[список.выбор];
var код = муром.редактор.session.getValue();
модуль[1] = муром.btoa(код);
}
function сохранить()
{
пу.кнопкаСохранить.disabled = true;
localforage.setItem("modules", муром.модули, function(ошибка, значение){
пу.кнопкаСохранить.disabled = false;
if (ошибка)
{
console.error("Не удалось сохранить модули: '" + ошибка + "'");
}
});
}
пу.сохранить.подписатьМного([
сохранитьВыбранныйМодуль,
сохранить,
]);
// How to create a file in memory for user to download, but not through server?
// https://stackoverflow.com/a/18197341
function скачать()
{
var содержимое = муром.файл.начало;
for (var номер in муром.модули)
{
var модуль = муром.модули[номер];
var имя = модуль[0];
var код64 = модуль[1];
var свойства = модули.свойства(номер);
содержимое +=
`
[
"` + имя + `",
"` + код64 + `",
`
+
JSON.stringify(свойства)
+
`
],
`
;
}
содержимое += муром.файл.конец;
содержимое = муром.btoa(содержимое);
var ссыль = document.createElement("a");
ссыль.setAttribute("href", "data:text/html;charset=utf-8;base64," + содержимое);
var имя = пу.имяФайла();
ссыль.setAttribute("download", имя);
ссыль.style.display = "none";
document.body.appendChild(ссыль);
ссыль.click();
document.body.removeChild(ссыль);
}
пу.скачать.подписать(скачать);
// При запуске.
список.выбрать(0);
}
/*
*
* Пуск
*
*/
if (window.location.search == "?0")
{
console.debug("Запуск панели управления");
задатьВнешнийВид();
запуститьПУ();
console.debug("Панель управления запущена")
}