Compare commits

...

6 Commits

Author SHA1 Message Date
5d2fb7b107 Quiz example 2026-04-12 16:02:56 +04:00
b952b6bc86 Stable/unstable 2026-04-10 19:50:05 +04:00
e641c4e38b Stable/unstable 2026-04-10 19:37:57 +04:00
c10d855260 Stable/unstable 2026-04-10 19:31:47 +04:00
fd78a591b7 Stable/unstable 2026-04-10 19:30:15 +04:00
018bf29078 Stable/unstable 2026-04-10 19:26:59 +04:00
9 changed files with 312 additions and 39 deletions

16
DOCS.md
View File

@ -107,6 +107,20 @@ app.render("com.example");
// Эквивалентно
app.draw();
```
## stable / unstable
Стабильный обьек отрисовывается всегда, например:
```js
import Find from "/home/user/Find_js/Find.js";
const root = Find.search("my_app");
const app = new Find(root);
app.select(0);
app.stable();
// Добавление
app.add(['<button>123</button>']);
app.select(1);
app.add(['<button>123</button>']);
app.render();
```
## Map
Map - обьект на странице. Использует следующие функции:
```js
@ -130,6 +144,8 @@ map.value(/* value для замены */); // Без аргументов ве
map.id(/* ID элемента */); // Вернет экземпляр map для выбранного элемента
map.tag(/* TAG элемента */); // Вернет экземпляр map для выбранного элемента
map.attach(/* событие */, /* функция */); // EventHandler
map.attribute(/* Имя */, /* Значение */); // Задание атрибута
map.add(/* HTML */);
/*
* Функция в attach может принимать параметр.
* Этот параметр - обьект Find, map которого был вызван

View File

@ -56,6 +56,10 @@ class FindObjectMap {
this.root.innerHTML = t;
return this;
}
add(h) {
const t = this.html();
return this.html(t + String(h));
}
value(t) {
if (arguments.length == 0) {
return this.root.value;
@ -105,6 +109,10 @@ class FindObjectMap {
main() {
return new FindObjectMap(this._app.root, this._app, 0);
}
attribute(name, val) {
this.root.setAttribute(name, val);
return this;
}
}
export default class Find {
@ -112,6 +120,7 @@ export default class Find {
/* Public section */
constructor(root) {
this._lll = "";
this.root = root;
this.iter = 0;
this.groups = new Array();
@ -175,11 +184,13 @@ export default class Find {
meta = new Array();
}
if (addr != -1) {
const every = this.groups[addr].every;
this.groups[addr] = {
id: id,
html: html,
meta: meta,
title: document.title
title: document.title,
every: every
};
return this;
}
@ -196,7 +207,8 @@ export default class Find {
this.groups[this.groups_count] = {
id: id,
html: html,
meta: meta
meta: meta,
every: false
};
this.groups_count ++;
return this;
@ -231,6 +243,37 @@ export default class Find {
return this;
}
stable(id_, html_) {
let id = undefined;
let html = undefined;
if (arguments.length == 1 || arguments.length == 0) {
id = this.__id;
if (arguments.length != 0) {
html = id_;
} else {
html = true;
}
} else {
id = id_;
html = html_;
}
if (this.groups.length == 0 || this.getNumberOfGroupFromId(id, false) == -1) {
this.group(id, [], []);
}
const stable = html;
this.groups[this.getNumberOfGroupFromId(id)]
.every = stable;
return this;
}
unstable(id_) {
let id = id_;
if (arguments.length == 0) {
id = this.__id;
}
return this.stable(id, false);
}
correct(groupid_, elementid_, telement_) {
let groupid = undefined;
let elementid = undefined;
@ -328,7 +371,14 @@ export default class Find {
return this;
}
draw() {
draw(...args) {
this._lll = "";
this.__draw(...args);
this.root.innerHTML = this._lll;
return this;
}
__draw(__use) {
if (typeof this.__id === "undefined") {
PrivateFind.error("Use select, before draw. Or you can use render.");
}
@ -341,7 +391,15 @@ export default class Find {
PrivateFind.findTypeError(group.html, "object");
return this;
}
this.root.innerHTML = "";
const isRecursive = (typeof __use === "string" && __use === '__undstta');
if (!isRecursive) {
for (let i = 0; i < this.groups.length; i ++) {
if (typeof this.groups[i].every === "boolean" && this.groups[i].every) {
this.render(this.groups[i].id, '__undstta');
this.iter --;
}
}
}
if (typeof group.title !== "undefined" && document.title !== group.title) {
document.title = group.title;
}
@ -350,22 +408,34 @@ export default class Find {
Array.isArray(group.meta) &&
group.meta.length > 0 && this.iter === 0
) {
let n = document.head.innerHTML;
for (let i = 0; i < group.meta.length; i ++) {
if (typeof group.meta[i] === "string") {
this.root.innerHTML += group.meta[i];
n += group.meta[i];
}
}
document.head.innerHTML = n;
}
let drawer = "";
for (let i = 0; i < group.html.length; i ++) {
if (typeof group.html[i] === "string") {
this.root.innerHTML += group.html[i];
drawer += group.html[i];
}
}
if (this.root.innerHTML !== drawer) {
if (isRecursive) {
if (drawer.length !== 0) {
this._lll += drawer;
}
} else {
this._lll += drawer;
}
}
this.iter ++;
return this;
}
render(id_) {
render(id_, __use) {
let id = undefined;
if (arguments.length == 0) {
id = this.__id;
@ -375,7 +445,7 @@ export default class Find {
const sv = this.__id;
this.select(id);
this.draw();
this.draw(__use);
this.__id = sv;
return this;
}

3
demos/Quiz/bulma.min.css vendored Normal file

File diff suppressed because one or more lines are too long

41
demos/Quiz/index.html Normal file
View File

@ -0,0 +1,41 @@
<!--
index.html
Copyright 2026 Lida <lida@lida-laptol>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<head>
<title>Find</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta name="generator" content="Geany 2.0" />
<link rel="stylesheet" href="bulma.min.css" />
</head>
<body>
<div id="root"></div>
<script src="nomodule-find.min.js"></script>
<script src="index.js"></script>
</body>
</html>

114
demos/Quiz/index.js Normal file
View File

@ -0,0 +1,114 @@
const qestions = [
{
qestion: "Мой вопрос",
variants: [
"Вариант 1",
"Вариант 2",
"Вариант 3"
],
correct: 0
}
];
class Quiz extends Find.createApp() {
constructor(qestions) {
const root = Find.search('root');
super(root);
this.qestions = qestions;
}
init() {
this.select('com.find.demos.quiz');
this.setMeta();
this.setCard();
this.stable();
this.createQestions();
}
setCard() {
this.add([
Find.content(
`<div class="card">
<div class="card-header">
<p class="card-header-title">
<span id="title">
Загрузка...
</span>
</p>
</div>
<div class="card-content">
<div class="content" id="content"></div>
<button
class="button"
style="width: 100%;"
id="test"
>Проверить</button>
</div>
</div>`
)
]);
}
setMeta() {
this.meta([
Find.content('<meta name="viewport" content="width=device-width, initial-scale=1">'),
Find.content('<style>body { margin: 20px; } </style>')
]);
}
createQestions() {
this.number = 0;
for (let i = 0; i < this.qestions.length; i ++) {
this.select('qestion' + this.number);
this.setTitle();
this.render();
this.setForms(this.qestions[i]);
this.setEvents(this.qestions[i])
.then((result) => {
this.number ++;
})
.catch((error) => {
});
this.number ++;
}
}
setEvents() {}
setTitle() {
this.title('Quiz qestion ' + this.number + ' - Find.js demo');
}
setForms(qe) {
let input_id = 0;
const root = this.component();
const content = root.id("content");
const title = root.id("title");
title.text(qe.qestion);
for (let val in (qe.variants)) {
content.add(
Find.content(
`<input
type="radio"
id="variant${input_id}"
name="radiobutton">
<label class="radio" for="variant${input_id}">
<span class="has-text-weight-medium" id="text${input_id}"></span>
</label>
</input>
<br>`
)
);
content.id('text' + input_id).text(qe.variants[val]);
input_id ++;
}
}
setEvents(r) {
}
}
const quiz = new Quiz(qestions);
quiz.init();

1
demos/Quiz/nomodule-find.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -23,12 +23,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<head>
<title>Find</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta name="generator" content="Geany 2.0" />
<link rel="stylesheet" href="bulma.min.css" />
</head>
<body>

View File

@ -2,14 +2,17 @@ import Find from './Find/Find.js';
const ROOT_OBJECT = 'root';
class MyApp extends Find.createApp() {
const STANDARD = 0;
const NO_MODULE = 1;
class App extends Find.createApp() {
constructor(name) {
const root = Find.search(name);
super(root);
}
init() {
this.select('com.example');
this.select('com.find.minify');
this.setMeta();
this.setTitle();
this.setForms();
@ -19,20 +22,14 @@ class MyApp extends Find.createApp() {
setMeta() {
this.meta([
Find.css('bulma.min.css'),
Find.content('<meta name="viewport" content="width=device-width, initial-scale=1">'),
Find.content(
`<style>
body {
margin: 20px;
}
</style>`
)
Find.content('<style>body { margin: 20px; } </style>'),
Find.content('<link rel="icon" href="favicon.ico" type="image/x-icon" />')
]);
}
setTitle() {
this.title('Минификатор FInd.js на Find.js');
this.title('Минификатор Find.js на Find.js');
}
setForms() {
@ -40,15 +37,29 @@ class MyApp extends Find.createApp() {
Find.content(
`<div class="card">
<div class="card-header">
<p id="title" class="card-header-title">Минификация Find.js</p>
<p class="card-header-title">
<span id="title">Минификация Find.js</span> &nbsp;
<span id="hand_error" class="has-text-danger"></span>
</p>
</div>
<div class="card-content">
<div class="content">
<span class="has-text-weight-bold">
Минифицируйте Find.js прямо сейчас!
</span>
<button
class="button"
id="minify"
style="width: 100%"
style="width: 100%; margin-top: 10px; margin-bottom: 10px;"
>Минифицировать</button>
<span class="has-text-weight-bold">
Или же скачайте no-module версию:
</span>
<button
class="button"
id="no-module"
style="width: 100%; margin-top: 10px;"
>Скачать</button>
</div>
</div>
</div>`
@ -56,14 +67,18 @@ class MyApp extends Find.createApp() {
]);
}
mwait(t) {
const root = app.component();
mwait(t, x) {
const root = this.component();
const title = root.id('title');
root.id("hand_error").text('');
if (t === true) {
title.text('Минификация Find.js в процессе...');
} else {
if (typeof t === "string") {
title.text(t);
if (arguments.length > 1) {
root.id("hand_error").text(x);
}
} else {
title.text('Минификация Find.js');
}
@ -72,27 +87,39 @@ class MyApp extends Find.createApp() {
attachEvents() {
const root = this.component();
const button = root.id('minify');
button.attach('click', (app) => {
root.id('minify').attach('click', () => {
this.mwait(true);
this.minifyFind();
this.minifyFind(STANDARD);
});
root.id('no-module').attach('click', () => {
this.mwait(true);
this.minifyFind(NO_MODULE);
});
}
async minifyFind() {
async minifyFind(mode) {
try {
let response = await fetch('Find/Find.js');
if (response.ok) {
let code = await response.text();
let name = 'find.min.js';
if (mode == NO_MODULE) {
code = code.replace('export default class Find', 'class Find');
name = 'nomodule-' + name;
}
let minif = await Terser.minify(code, { sourceMap: false });
this.uploadJS("find.min.js", minif.code);
this.uploadFile(name, 'application/javascript', minif.code);
this.mwait(false);
} else {
this.mwait("Ошибка HTTP: " + response.status);
this.mwait('Ошибка HTTP', response.status);
}
} catch (err) {
this.mwait('Ошибка: ', err);
}
}
uploadJS(filename, content) {
const blob = new Blob([content], { type: 'application/javascript' });
uploadFile(filename, mime, content) {
const blob = new Blob([content], { type: mime });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
@ -101,5 +128,5 @@ class MyApp extends Find.createApp() {
}
}
const app = new MyApp(ROOT_OBJECT);
const app = new App(ROOT_OBJECT);
app.init();