silentium-components 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/silentium-components.cjs +134 -483
- package/dist/silentium-components.cjs.map +1 -1
- package/dist/silentium-components.d.ts +8 -190
- package/dist/silentium-components.js +130 -467
- package/dist/silentium-components.js.map +1 -1
- package/dist/silentium-components.min.js +1 -1
- package/dist/silentium-components.min.mjs +1 -1
- package/dist/silentium-components.min.mjs.map +1 -1
- package/dist/silentium-components.mjs +130 -467
- package/dist/silentium-components.mjs.map +1 -1
- package/docs/assets/js/index.mjs +3 -3
- package/docs/build.sh +3 -4
- package/docs/index.html +3 -3
- package/docs/pages/behaviors/deadline.html +60 -0
- package/docs/pages/behaviors/dirty.html +4 -4
- package/docs/pages/behaviors/loading.html +6 -6
- package/docs/pages/behaviors.html +5 -0
- package/docs/pages/structures/hash-table.html +4 -4
- package/docs/routes.json +1 -1
- package/eslint.config.mjs +1 -0
- package/package.json +7 -5
- package/src/behaviors/Deadline._value.test.ts +27 -0
- package/src/behaviors/Deadline.test.ts +28 -0
- package/src/behaviors/Deadline.ts +49 -0
- package/src/behaviors/Dirty.test.ts +5 -5
- package/src/behaviors/Dirty.ts +48 -54
- package/src/behaviors/Loading.test.ts +8 -8
- package/src/behaviors/Loading.ts +21 -31
- package/src/behaviors/Path.index.test.ts +5 -5
- package/src/behaviors/Path.nested.test.ts +5 -5
- package/src/behaviors/Path.test.ts +5 -5
- package/src/behaviors/Path.ts +26 -30
- package/src/behaviors/index.ts +1 -1
- package/src/controls/GroupActiveClass.test.ts +16 -13
- package/src/controls/GroupActiveClass.ts +19 -22
- package/src/controls/index.ts +0 -5
- package/src/index.ts +0 -2
- package/src/navigation/Router.test.ts +47 -0
- package/src/navigation/Router.ts +43 -111
- package/src/navigation/index.ts +0 -6
- package/src/structures/HashTable.test.ts +5 -5
- package/src/structures/HashTable.ts +14 -25
- package/src/system/RegexpMatched.test.ts +14 -0
- package/src/system/RegexpMatched.ts +17 -0
- package/src/system/index.ts +1 -0
- package/dist/patron-components.cjs +0 -372
- package/dist/patron-components.cjs.map +0 -1
- package/dist/patron-components.d.ts +0 -158
- package/dist/patron-components.js +0 -358
- package/dist/patron-components.js.map +0 -1
- package/dist/patron-components.min.js +0 -1
- package/dist/patron-components.min.mjs +0 -2
- package/dist/patron-components.min.mjs.map +0 -1
- package/dist/patron-components.mjs +0 -358
- package/dist/patron-components.mjs.map +0 -1
- package/src/behaviors/Touched.ts +0 -1
- package/src/controls/ComputedElement.ts +0 -51
- package/src/controls/Input.ts +0 -40
- package/src/controls/Link.ts +0 -53
- package/src/controls/Text.ts +0 -16
- package/src/controls/Visible.ts +0 -16
- package/src/jsdom/JSDomDocument.ts +0 -15
- package/src/jsdom/JSDomElement.ts +0 -28
- package/src/jsdom/JSDomQuerySelector.ts +0 -28
- package/src/navigation/CurrentPage.ts +0 -27
- package/src/navigation/Navigation.default.test.ts +0 -53
- package/src/navigation/Navigation.main.test.ts +0 -46
- package/src/navigation/Navigation.ts +0 -92
- package/src/navigation/Navigation.wildcard.test.ts +0 -52
- package/src/navigation/PageFetchTransport.ts +0 -26
- package/src/navigation/RouteDisplay.ts +0 -18
- package/src/navigation/RoutePageType.ts +0 -3
- package/src/page/EntryPointPage.ts +0 -20
- package/src/page/Page.ts +0 -12
- package/src/page/PageFake.ts +0 -8
- package/src/page/index.ts +0 -2
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sourceOf, sourceSync } from "silentium";
|
|
2
|
+
import { loading } from "../behaviors/Loading";
|
|
2
3
|
import { expect, test } from "vitest";
|
|
3
|
-
import { Loading } from "../behaviors/Loading";
|
|
4
4
|
|
|
5
5
|
test("Loading.test", () => {
|
|
6
|
-
const loadingStartSource =
|
|
7
|
-
const loadingFinishSource =
|
|
8
|
-
const
|
|
9
|
-
|
|
6
|
+
const loadingStartSource = sourceOf();
|
|
7
|
+
const loadingFinishSource = sourceOf();
|
|
8
|
+
const loadingSrc = sourceSync(
|
|
9
|
+
loading(loadingStartSource, loadingFinishSource),
|
|
10
10
|
);
|
|
11
11
|
loadingStartSource.give({});
|
|
12
|
-
expect(
|
|
12
|
+
expect(loadingSrc.syncValue()).toBe(true);
|
|
13
13
|
loadingFinishSource.give({});
|
|
14
|
-
expect(
|
|
14
|
+
expect(loadingSrc.syncValue()).toBe(false);
|
|
15
15
|
});
|
package/src/behaviors/Loading.ts
CHANGED
|
@@ -1,37 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
GuestCast,
|
|
3
|
-
GuestType,
|
|
4
|
-
SourceObjectType,
|
|
5
|
-
SourceType,
|
|
6
|
-
SourceWithPool,
|
|
7
|
-
value,
|
|
8
|
-
} from "silentium";
|
|
1
|
+
import { patron, sourceOf, SourceType, subSourceMany, value } from "silentium";
|
|
9
2
|
|
|
10
3
|
/**
|
|
11
4
|
* https://silentium-lab.github.io/silentium-components/#/behaviors/loading
|
|
12
5
|
*/
|
|
13
|
-
export
|
|
14
|
-
|
|
6
|
+
export const loading = (
|
|
7
|
+
loadingStartSource: SourceType<unknown>,
|
|
8
|
+
loadingFinishSource: SourceType<unknown>,
|
|
9
|
+
) => {
|
|
10
|
+
const loadingSrc = sourceOf<boolean>();
|
|
11
|
+
subSourceMany(loadingSrc, [loadingStartSource, loadingFinishSource]);
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
value(
|
|
14
|
+
loadingStartSource,
|
|
15
|
+
patron(() => {
|
|
16
|
+
loadingSrc.give(true);
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
value(
|
|
20
|
+
loadingFinishSource,
|
|
21
|
+
patron(() => {
|
|
22
|
+
loadingSrc.give(false);
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.loadingStartSource,
|
|
24
|
-
new GuestCast(guest, () => {
|
|
25
|
-
this.loadingSource.give(true);
|
|
26
|
-
}),
|
|
27
|
-
);
|
|
28
|
-
value(
|
|
29
|
-
this.loadingFinishSource,
|
|
30
|
-
new GuestCast(guest, () => {
|
|
31
|
-
this.loadingSource.give(false);
|
|
32
|
-
}),
|
|
33
|
-
);
|
|
34
|
-
this.loadingSource.value(guest);
|
|
35
|
-
return this;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
26
|
+
return loadingSrc.value;
|
|
27
|
+
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Path } from "./Path";
|
|
1
|
+
import { sourceSync } from "silentium";
|
|
3
2
|
import { expect, test } from "vitest";
|
|
3
|
+
import { path } from "./Path";
|
|
4
4
|
|
|
5
5
|
test("Path.index.test", () => {
|
|
6
|
-
const record =
|
|
6
|
+
const record = {
|
|
7
7
|
name: "Peter",
|
|
8
8
|
surname: "Parker",
|
|
9
9
|
colors: ["blue", "red"],
|
|
10
10
|
type: {
|
|
11
11
|
name: "spider-man",
|
|
12
12
|
},
|
|
13
|
-
}
|
|
14
|
-
const bestColor =
|
|
13
|
+
};
|
|
14
|
+
const bestColor = sourceSync(path(record, "colors.0"));
|
|
15
15
|
expect(bestColor.syncValue()).toBe("blue");
|
|
16
16
|
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Path } from "./Path";
|
|
1
|
+
import { sourceSync } from "silentium";
|
|
3
2
|
import { expect, test } from "vitest";
|
|
3
|
+
import { path } from "./Path";
|
|
4
4
|
|
|
5
5
|
test("Path.nested.test", () => {
|
|
6
|
-
const record =
|
|
6
|
+
const record = {
|
|
7
7
|
name: "Peter",
|
|
8
8
|
surname: "Parker",
|
|
9
9
|
type: {
|
|
10
10
|
name: "spider-man",
|
|
11
11
|
},
|
|
12
|
-
}
|
|
13
|
-
const typeName =
|
|
12
|
+
};
|
|
13
|
+
const typeName = sourceSync(path(record, "type.name"));
|
|
14
14
|
expect(typeName.syncValue()).toBe("spider-man");
|
|
15
15
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Path } from "../behaviors/Path";
|
|
1
|
+
import { sourceSync } from "silentium";
|
|
3
2
|
import { expect, test } from "vitest";
|
|
3
|
+
import { path } from "../behaviors/Path";
|
|
4
4
|
|
|
5
5
|
test("Path.test", () => {
|
|
6
|
-
const record =
|
|
6
|
+
const record = {
|
|
7
7
|
name: "Peter",
|
|
8
8
|
surname: "Parker",
|
|
9
|
-
}
|
|
10
|
-
const name =
|
|
9
|
+
};
|
|
10
|
+
const name = sourceSync(path(record, "name"));
|
|
11
11
|
expect(name.syncValue()).toBe("Peter");
|
|
12
12
|
});
|
package/src/behaviors/Path.ts
CHANGED
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
2
|
give,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
SourceObjectType,
|
|
3
|
+
patron,
|
|
4
|
+
sourceAll,
|
|
5
|
+
sourceOf,
|
|
7
6
|
SourceType,
|
|
7
|
+
subSourceMany,
|
|
8
8
|
value,
|
|
9
9
|
} from "silentium";
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
) {}
|
|
11
|
+
export const path = <T extends Record<string, unknown>, K extends string>(
|
|
12
|
+
baseSrc: SourceType<T>,
|
|
13
|
+
keySrc: SourceType<K>,
|
|
14
|
+
) => {
|
|
15
|
+
const pathSrc = sourceOf<T[K]>();
|
|
16
|
+
subSourceMany(pathSrc, [baseSrc, keySrc]);
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
keyChunks.forEach((keyChunk) => {
|
|
28
|
-
value = (value as T)[keyChunk];
|
|
29
|
-
});
|
|
18
|
+
value(
|
|
19
|
+
sourceAll([baseSrc, keySrc]),
|
|
20
|
+
patron(([base, key]) => {
|
|
21
|
+
const keyChunks = key.split(".");
|
|
22
|
+
let value: unknown = base;
|
|
23
|
+
keyChunks.forEach((keyChunk) => {
|
|
24
|
+
value = (value as T)[keyChunk];
|
|
25
|
+
});
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
27
|
+
if (value !== undefined && value !== base) {
|
|
28
|
+
give(value as T[K], pathSrc);
|
|
29
|
+
}
|
|
30
|
+
}),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return pathSrc.value;
|
|
34
|
+
};
|
package/src/behaviors/index.ts
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { sourceOf, sourceSync, value } from "silentium";
|
|
2
|
+
import { jsdomDocument } from "silentium-jsdom";
|
|
3
|
+
import { element } from "silentium-web-api";
|
|
3
4
|
import { expect, test } from "vitest";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { path } from "../behaviors";
|
|
6
|
+
import { groupActiveClass } from "./GroupActiveClass";
|
|
6
7
|
|
|
7
8
|
test("GroupActiveClass.test", () => {
|
|
8
|
-
const document =
|
|
9
|
+
const document = sourceSync(
|
|
10
|
+
jsdomDocument(`<div class="menu">
|
|
9
11
|
<div id="prev-active" class="menu-link active">One</div>
|
|
10
12
|
<div class="menu-link">Two</div>
|
|
11
13
|
<div id="next-active" class="menu-link">Three</div>
|
|
12
|
-
</div>`)
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
</div>`),
|
|
15
|
+
).syncValue();
|
|
16
|
+
const groupElements = path(<any>element(".menu", document), "childNodes");
|
|
17
|
+
const activeElement = sourceOf<HTMLElement>();
|
|
18
|
+
sourceSync(groupActiveClass("active", activeElement, groupElements));
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
document.value(g);
|
|
20
|
+
value(element("#next-active", document), activeElement);
|
|
19
21
|
|
|
20
|
-
expect(
|
|
22
|
+
expect(document.body.outerHTML).toContain(
|
|
21
23
|
'id="next-active" class="menu-link active"',
|
|
22
24
|
);
|
|
23
|
-
|
|
25
|
+
|
|
26
|
+
expect(document.body.innerHTML).toContain(
|
|
24
27
|
'id="prev-active" class="menu-link"',
|
|
25
28
|
);
|
|
26
29
|
});
|
|
@@ -1,29 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { patron, sourceAll, SourceType, value } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Sets activeClass to one element of group
|
|
5
5
|
* and resets activeClass on other group elements
|
|
6
6
|
* suitable for menu active class
|
|
7
|
-
*
|
|
8
|
-
* @deprecated heavily related to web api needs refactoring
|
|
9
7
|
*/
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
export const groupActiveClass = (
|
|
9
|
+
activeClassSrc: SourceType<string>,
|
|
10
|
+
activeElementSrc: SourceType<HTMLElement>,
|
|
11
|
+
groupElementsSrc: SourceType<HTMLElement[]>,
|
|
12
|
+
) => {
|
|
13
|
+
value(
|
|
14
|
+
sourceAll([activeClassSrc, activeElementSrc, groupElementsSrc]),
|
|
15
|
+
patron(([activeClass, activeElement, groupElements]) => {
|
|
16
|
+
groupElements.forEach((el) => {
|
|
17
|
+
if (el.classList) {
|
|
18
|
+
el.classList.remove(activeClass);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
activeElement.classList.add(activeClass);
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this.document,
|
|
20
|
-
new PatronOnce((document) => {
|
|
21
|
-
document.querySelectorAll(this.groupSelector).forEach((el) => {
|
|
22
|
-
el.classList.remove(this.activeClass);
|
|
23
|
-
});
|
|
24
|
-
element.classList.add(this.activeClass);
|
|
25
|
-
}),
|
|
26
|
-
);
|
|
27
|
-
return this;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
25
|
+
return groupElementsSrc;
|
|
26
|
+
};
|
package/src/controls/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { source, sourceApplied, sourceOf, sourceSync } from "silentium";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { router } from "../navigation/Router";
|
|
4
|
+
|
|
5
|
+
const drop = (dropPart: string) => (value: string) => {
|
|
6
|
+
return value.replace(dropPart, "");
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
test("Router.test", () => {
|
|
10
|
+
const urlSrc = sourceOf<string>("http://domain.com/some/url/");
|
|
11
|
+
const urlClearedSrc = sourceApplied(urlSrc, drop("http://domain.com"));
|
|
12
|
+
|
|
13
|
+
const template = sourceSync(
|
|
14
|
+
router(
|
|
15
|
+
urlClearedSrc,
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
pattern: "^/$",
|
|
19
|
+
template: source("page/home.html"),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
pattern: "/some/url",
|
|
23
|
+
template: "page/home.html",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
pattern: "/some/contacts",
|
|
27
|
+
template: "page/contacts.html",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
source("page/404.html"),
|
|
31
|
+
),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(template.syncValue()).toBe("page/home.html");
|
|
35
|
+
|
|
36
|
+
urlSrc.give("http://domain.com/some/contacts/");
|
|
37
|
+
|
|
38
|
+
expect(template.syncValue()).toBe("page/contacts.html");
|
|
39
|
+
|
|
40
|
+
urlSrc.give("http://domain.com/some/unknown/");
|
|
41
|
+
|
|
42
|
+
expect(template.syncValue()).toBe("page/404.html");
|
|
43
|
+
|
|
44
|
+
urlSrc.give("http://domain.com/");
|
|
45
|
+
|
|
46
|
+
expect(template.syncValue()).toBe("page/home.html");
|
|
47
|
+
});
|
package/src/navigation/Router.ts
CHANGED
|
@@ -1,118 +1,50 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
PrivateClass,
|
|
7
|
-
SourceWithPool,
|
|
8
|
-
give,
|
|
2
|
+
patron,
|
|
3
|
+
sourceAny,
|
|
4
|
+
sourceChain,
|
|
5
|
+
sourceFiltered,
|
|
9
6
|
sourceOf,
|
|
7
|
+
SourceType,
|
|
8
|
+
value,
|
|
10
9
|
} from "silentium";
|
|
11
|
-
import {
|
|
12
|
-
import { ComputedElement, GroupActiveClass, Link, Visible } from "../controls";
|
|
13
|
-
import { CurrentPage } from "../navigation/CurrentPage";
|
|
14
|
-
import { Navigation } from "../navigation/Navigation";
|
|
15
|
-
import { PageFetchTransport } from "../navigation/PageFetchTransport";
|
|
16
|
-
import { RouteDisplay } from "../navigation/RouteDisplay";
|
|
10
|
+
import { regexpMatched } from "../system/RegexpMatched";
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export class Router {
|
|
26
|
-
public constructor(
|
|
27
|
-
private loaderSelector: string,
|
|
28
|
-
private navigationResultSelector: string,
|
|
29
|
-
private menuSelector: string,
|
|
30
|
-
) {}
|
|
31
|
-
|
|
32
|
-
routes(
|
|
33
|
-
routes: Route[],
|
|
34
|
-
currentPage: any,
|
|
35
|
-
basePathSource: any,
|
|
36
|
-
afterPageLoaded?: () => void,
|
|
37
|
-
) {
|
|
38
|
-
if (!currentPage) {
|
|
39
|
-
currentPage = new CurrentPage();
|
|
40
|
-
}
|
|
41
|
-
currentPage.value(new Patron(new HistoryNewPage()));
|
|
42
|
-
|
|
43
|
-
const [basePath] = location.href.replace(location.origin, "").split("#");
|
|
44
|
-
if (!basePathSource) {
|
|
45
|
-
basePathSource = new SourceWithPool(
|
|
46
|
-
`${basePath}#`.replace("index.html", "").replace("//", "/"),
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const pageLoading = new SourceWithPool(false);
|
|
51
|
-
pageLoading.value(new Patron(new Visible(this.loaderSelector)));
|
|
52
|
-
|
|
53
|
-
const historyPoppedPage = new HistoryPoppedPage(currentPage);
|
|
54
|
-
historyPoppedPage.watchPop();
|
|
55
|
-
|
|
56
|
-
const navigation = new Navigation(
|
|
57
|
-
pageLoading,
|
|
58
|
-
basePathSource,
|
|
59
|
-
currentPage,
|
|
60
|
-
new RouteDisplay(this.navigationResultSelector),
|
|
61
|
-
new PrivateClass(PageFetchTransport),
|
|
62
|
-
);
|
|
63
|
-
navigation.routes(routes);
|
|
64
|
-
|
|
65
|
-
const link = new Link(currentPage, basePathSource);
|
|
66
|
-
link.watchClick(this.menuSelector);
|
|
12
|
+
export interface Route<T> {
|
|
13
|
+
pattern: string;
|
|
14
|
+
patternFlags?: string;
|
|
15
|
+
template: T | SourceType<T>;
|
|
16
|
+
}
|
|
67
17
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Router component what will return template if url matches pattern
|
|
20
|
+
*/
|
|
21
|
+
export const router = <T = "string">(
|
|
22
|
+
urlSrc: SourceType<string>,
|
|
23
|
+
routesSrc: SourceType<Route<T>[]>,
|
|
24
|
+
defaultSrc: SourceType<T>,
|
|
25
|
+
) => {
|
|
26
|
+
const resultSrc = sourceOf<T>();
|
|
27
|
+
|
|
28
|
+
value(
|
|
29
|
+
routesSrc,
|
|
30
|
+
patron((routes) => {
|
|
31
|
+
value(
|
|
32
|
+
sourceAny([
|
|
33
|
+
sourceChain(urlSrc, defaultSrc as T),
|
|
34
|
+
...routes.map((r) =>
|
|
35
|
+
sourceChain(
|
|
36
|
+
sourceFiltered(
|
|
37
|
+
regexpMatched(r.pattern, urlSrc, r.patternFlags),
|
|
38
|
+
Boolean,
|
|
39
|
+
),
|
|
40
|
+
r.template,
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
]),
|
|
44
|
+
patron(resultSrc),
|
|
76
45
|
);
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
const activeLink = new ComputedElement(
|
|
80
|
-
[{ source: url, placeholder: "{url}" }],
|
|
81
|
-
`${this.menuSelector} a[href="{url}"]`,
|
|
82
|
-
);
|
|
83
|
-
activeLink.element(
|
|
84
|
-
new Patron(
|
|
85
|
-
new GroupActiveClass(
|
|
86
|
-
"active",
|
|
87
|
-
`${this.menuSelector} a`,
|
|
88
|
-
sourceOf(document),
|
|
89
|
-
),
|
|
90
|
-
),
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
pageLoading.value(
|
|
94
|
-
new Patron((isInLoading) => {
|
|
95
|
-
if (isInLoading) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
98
48
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const divDestination = document.querySelector(
|
|
104
|
-
this.navigationResultSelector,
|
|
105
|
-
);
|
|
106
|
-
if (divDestination) {
|
|
107
|
-
// Оживляем script тэги
|
|
108
|
-
divDestination.querySelectorAll("script").forEach((x) => {
|
|
109
|
-
const sc = document.createElement("script");
|
|
110
|
-
sc.setAttribute("type", "module");
|
|
111
|
-
sc.appendChild(document.createTextNode(x.innerText));
|
|
112
|
-
divDestination.appendChild(sc);
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}),
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
49
|
+
return resultSrc.value;
|
|
50
|
+
};
|
package/src/navigation/index.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { HashTable } from "../structures/HashTable";
|
|
1
|
+
import { sourceOf, sourceSync } from "silentium";
|
|
3
2
|
import { expect, test } from "vitest";
|
|
3
|
+
import { hashTable } from "../structures/HashTable";
|
|
4
4
|
|
|
5
5
|
test("HashTable.test", () => {
|
|
6
|
-
const entrySource =
|
|
7
|
-
const
|
|
6
|
+
const entrySource = sourceOf<[string, string]>();
|
|
7
|
+
const hashTableSrc = sourceSync(hashTable(entrySource));
|
|
8
8
|
entrySource.give(["key-one", "value-one"]);
|
|
9
9
|
entrySource.give(["key-two", "value-two"]);
|
|
10
10
|
|
|
11
|
-
expect(
|
|
11
|
+
expect(hashTableSrc.syncValue()).toStrictEqual({
|
|
12
12
|
"key-one": "value-one",
|
|
13
13
|
"key-two": "value-two",
|
|
14
14
|
});
|
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
GuestType,
|
|
3
|
-
Patron,
|
|
4
|
-
SourceObjectType,
|
|
5
|
-
SourceType,
|
|
6
|
-
SourceWithPool,
|
|
7
|
-
value,
|
|
8
|
-
} from "silentium";
|
|
1
|
+
import { patron, sourceOf, SourceType, subSource, value } from "silentium";
|
|
9
2
|
|
|
10
3
|
/**
|
|
11
4
|
* https://silentium-lab.github.io/silentium-components/#/structures/hash-table
|
|
12
5
|
*/
|
|
13
|
-
export
|
|
14
|
-
|
|
6
|
+
export const hashTable = (baseSource: SourceType<[string, unknown]>) => {
|
|
7
|
+
const result = sourceOf<Record<string, unknown>>({});
|
|
8
|
+
subSource(result, baseSource);
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
);
|
|
25
|
-
}
|
|
10
|
+
value(
|
|
11
|
+
baseSource,
|
|
12
|
+
patron(([key, value]) => {
|
|
13
|
+
result.value((lastRecord) => {
|
|
14
|
+
lastRecord[key] = value;
|
|
15
|
+
});
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
19
|
+
return result.value;
|
|
20
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { sourceOf, sourceSync } from "silentium";
|
|
2
|
+
import { regexpMatched } from "../system/RegexpMatched";
|
|
3
|
+
import { expect, test } from "vitest";
|
|
4
|
+
|
|
5
|
+
test("RegexpMatched.test", () => {
|
|
6
|
+
const urlSrc = sourceOf<string>("http://domain.com/some/url/");
|
|
7
|
+
const matchedSrc = sourceSync(regexpMatched("/some/url", urlSrc));
|
|
8
|
+
|
|
9
|
+
expect(matchedSrc.syncValue()).toBe(true);
|
|
10
|
+
|
|
11
|
+
urlSrc.give("http://domain.com/changed");
|
|
12
|
+
|
|
13
|
+
expect(matchedSrc.syncValue()).toBe(false);
|
|
14
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { give, GuestType, sourceCombined, SourceType } from "silentium";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Boolean source what checks what string matches pattern
|
|
5
|
+
*/
|
|
6
|
+
export const regexpMatched = (
|
|
7
|
+
patternSrc: SourceType<string>,
|
|
8
|
+
valueSrc: SourceType<string>,
|
|
9
|
+
flagsSrc: SourceType<string> = "",
|
|
10
|
+
): SourceType<boolean> =>
|
|
11
|
+
sourceCombined(
|
|
12
|
+
patternSrc,
|
|
13
|
+
valueSrc,
|
|
14
|
+
flagsSrc,
|
|
15
|
+
)((g: GuestType<boolean>, pattern, value, flags) => {
|
|
16
|
+
give(new RegExp(pattern, flags).test(value), g);
|
|
17
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./RegexpMatched";
|