native-document 1.0.40 → 1.0.41
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/dist/native-document.dev.js +145 -30
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.devtools.min.js +1 -1
- package/dist/native-document.min.js +1 -1
- package/elements.js +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/data/ObservableItem.js +10 -0
- package/src/data/observable-helpers/array.js +26 -2
- package/src/data/observable-helpers/object.js +4 -0
- package/src/elements/anchor.js +28 -12
- package/src/elements/control/show-if.js +8 -9
- package/src/elements/control/switch.js +1 -2
- package/src/router/Route.js +2 -0
- package/src/router/RouteGroupHelper.js +3 -0
- package/src/router/Router.js +2 -1
- package/src/router/RouterComponent.js +8 -3
- package/src/utils/validator.js +5 -1
- package/src/wrappers/NDElement.js +0 -2
- package/src/wrappers/SingletonView.js +48 -0
- package/src/wrappers/TemplateCloner.js +2 -0
- package/types/elements.d.ts +10 -1
- package/types/observable.d.ts +3 -0
- package/types/router.d.ts +3 -2
- package/types/singleton.d.ts +19 -0
|
@@ -18,7 +18,7 @@ export const Match = function($condition, values, shouldKeepInCache = true) {
|
|
|
18
18
|
throw new NativeDocumentError("Toggle : condition must be an Observable");
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const anchor = new Anchor();
|
|
21
|
+
const anchor = new Anchor('Match');
|
|
22
22
|
const cache = new Map();
|
|
23
23
|
|
|
24
24
|
const getItem = function(key) {
|
|
@@ -63,7 +63,6 @@ export const Match = function($condition, values, shouldKeepInCache = true) {
|
|
|
63
63
|
* @returns {DocumentFragment}
|
|
64
64
|
*/
|
|
65
65
|
export const Switch = function ($condition, onTrue, onFalse) {
|
|
66
|
-
|
|
67
66
|
if(!Validator.isObservable($condition)) {
|
|
68
67
|
throw new NativeDocumentError("Toggle : condition must be an Observable");
|
|
69
68
|
}
|
package/src/router/Route.js
CHANGED
|
@@ -21,6 +21,7 @@ export function Route($path, $component, $options = {}) {
|
|
|
21
21
|
const $middlewares = $options.middlewares || [];
|
|
22
22
|
const $shouldRebuild = $options.shouldRebuild || false;
|
|
23
23
|
const $paramsValidators = $options.with || {};
|
|
24
|
+
const $layout = $options.layout || null;
|
|
24
25
|
|
|
25
26
|
const $params = {};
|
|
26
27
|
const $paramsNames = [];
|
|
@@ -65,6 +66,7 @@ export function Route($path, $component, $options = {}) {
|
|
|
65
66
|
this.middlewares = () => $middlewares;
|
|
66
67
|
this.shouldRebuild = () => $shouldRebuild;
|
|
67
68
|
this.path = () => $path;
|
|
69
|
+
this.layout = () => $layout;
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
72
|
*
|
package/src/router/Router.js
CHANGED
|
@@ -54,7 +54,7 @@ export default function Router($options = {}) {
|
|
|
54
54
|
*
|
|
55
55
|
* @param {string} path
|
|
56
56
|
* @param {Function} component
|
|
57
|
-
* @param {{name:?string, middlewares:Function[], shouldRebuild:Boolean, with: Object }} options
|
|
57
|
+
* @param {{name:?string, middlewares:Function[], shouldRebuild:Boolean, with: Object, layout: Function }} options
|
|
58
58
|
* @returns {this}
|
|
59
59
|
*/
|
|
60
60
|
this.add = function(path, component, options) {
|
|
@@ -62,6 +62,7 @@ export default function Router($options = {}) {
|
|
|
62
62
|
...options,
|
|
63
63
|
middlewares: RouteGroupHelper.fullMiddlewares($groupTree, options?.middlewares || []),
|
|
64
64
|
name: options?.name ? RouteGroupHelper.fullName($groupTree, options.name) : null,
|
|
65
|
+
layout: options?.layout || RouteGroupHelper.layout($groupTree)
|
|
65
66
|
});
|
|
66
67
|
$routes.push(route);
|
|
67
68
|
if(route.name()) {
|
|
@@ -7,8 +7,13 @@ export function RouterComponent(router, container) {
|
|
|
7
7
|
|
|
8
8
|
const $cache = new Map();
|
|
9
9
|
|
|
10
|
-
const updateContainer = function(node) {
|
|
10
|
+
const updateContainer = function(node, route) {
|
|
11
11
|
container.innerHTML = '';
|
|
12
|
+
const layout = route.layout();
|
|
13
|
+
if(layout) {
|
|
14
|
+
container.appendChild(layout(node));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
12
17
|
container.appendChild(node);
|
|
13
18
|
};
|
|
14
19
|
|
|
@@ -19,13 +24,13 @@ export function RouterComponent(router, container) {
|
|
|
19
24
|
const { route, params, query, path } = state;
|
|
20
25
|
if($cache.has(path)) {
|
|
21
26
|
const cacheNode = $cache.get(path);
|
|
22
|
-
updateContainer(cacheNode);
|
|
27
|
+
updateContainer(cacheNode, route);
|
|
23
28
|
return;
|
|
24
29
|
}
|
|
25
30
|
const Component = route.component();
|
|
26
31
|
const node = Component({ params, query });
|
|
27
32
|
$cache.set(path, node);
|
|
28
|
-
updateContainer(node);
|
|
33
|
+
updateContainer(node, route);
|
|
29
34
|
};
|
|
30
35
|
|
|
31
36
|
router.subscribe(handleCurrentRouterState);
|
package/src/utils/validator.js
CHANGED
|
@@ -19,6 +19,9 @@ const Validator = {
|
|
|
19
19
|
isProxy(value) {
|
|
20
20
|
return value?.__isProxy__
|
|
21
21
|
},
|
|
22
|
+
isAnchor(value) {
|
|
23
|
+
return value?.__Anchor__
|
|
24
|
+
},
|
|
22
25
|
isObservableChecker(value) {
|
|
23
26
|
return value?.__$isObservableChecker || value instanceof ObservableChecker;
|
|
24
27
|
},
|
|
@@ -50,7 +53,8 @@ const Validator = {
|
|
|
50
53
|
return value && (
|
|
51
54
|
value.nodeType === COMMON_NODE_TYPES.ELEMENT ||
|
|
52
55
|
value.nodeType === COMMON_NODE_TYPES.TEXT ||
|
|
53
|
-
value.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT
|
|
56
|
+
value.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT ||
|
|
57
|
+
value.nodeType === COMMON_NODE_TYPES.COMMENT
|
|
54
58
|
);
|
|
55
59
|
},
|
|
56
60
|
isFragment(value) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Anchor from "../elements/anchor";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export function SingletonView($viewCreator) {
|
|
5
|
+
let $cacheNode = null;
|
|
6
|
+
let $components = null;
|
|
7
|
+
|
|
8
|
+
this.render = (data) => {
|
|
9
|
+
if(!$cacheNode) {
|
|
10
|
+
$cacheNode = $viewCreator(this);
|
|
11
|
+
}
|
|
12
|
+
if(!$components) {
|
|
13
|
+
return $cacheNode;
|
|
14
|
+
}
|
|
15
|
+
for(const index in $components) {
|
|
16
|
+
const updater = $components[index];
|
|
17
|
+
updater(...data);
|
|
18
|
+
}
|
|
19
|
+
return $cacheNode;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
this.createSection = (name, fn) => {
|
|
23
|
+
$components = $components || {};
|
|
24
|
+
const anchor = new Anchor('Component '+name);
|
|
25
|
+
|
|
26
|
+
$components[name] = function(...args) {
|
|
27
|
+
anchor.removeChildren();
|
|
28
|
+
if(!fn) {
|
|
29
|
+
anchor.append(args);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
anchor.appendChild(fn(...args));
|
|
33
|
+
};
|
|
34
|
+
return anchor;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
export function useSingleton(fn) {
|
|
40
|
+
let $cache = null;
|
|
41
|
+
|
|
42
|
+
return function(...args) {
|
|
43
|
+
if(!$cache) {
|
|
44
|
+
$cache = new SingletonView(fn);
|
|
45
|
+
}
|
|
46
|
+
return $cache.render(args);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {ElementCreator} from "./ElementCreator";
|
|
2
2
|
import {createTextNode} from "./HtmlElementWrapper";
|
|
3
|
+
import Anchor from "../elements/anchor";
|
|
3
4
|
|
|
4
5
|
const cloneBindingsDataCache = new WeakMap();
|
|
5
6
|
|
|
@@ -142,6 +143,7 @@ export function TemplateCloner($fn) {
|
|
|
142
143
|
this.attach = (fn) => {
|
|
143
144
|
return createBinding(fn, 'attach');
|
|
144
145
|
};
|
|
146
|
+
|
|
145
147
|
}
|
|
146
148
|
|
|
147
149
|
export function useCache(fn) {
|
package/types/elements.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type ValidChild =
|
|
|
18
18
|
| ValidChild[]
|
|
19
19
|
| ((...args: any[]) => ValidChild);
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
export type Attributes = Record<string, any> & {
|
|
22
23
|
class?: string | Record<string, boolean | ObservableItem<boolean>>;
|
|
23
24
|
style?: string | Record<string, string | ObservableItem<string>>;
|
|
@@ -122,5 +123,13 @@ export declare const TBodyCell: ElementFunction;
|
|
|
122
123
|
export declare const Fragment: ElementFunction;
|
|
123
124
|
export declare const NativeDocumentFragment: typeof Anchor;
|
|
124
125
|
|
|
126
|
+
|
|
127
|
+
export declare type AnchorDocumentFragment = DocumentFragment & {
|
|
128
|
+
detach: () => void;
|
|
129
|
+
restore: () => void;
|
|
130
|
+
removeChildren: () => void;
|
|
131
|
+
appendElement: (child: ValidChild, before: HTMLElement) => void;
|
|
132
|
+
};
|
|
133
|
+
|
|
125
134
|
// Anchor
|
|
126
|
-
export declare function Anchor(name?: string, isUniqueChild?: boolean):
|
|
135
|
+
export declare function Anchor(name?: string, isUniqueChild?: boolean): AnchorDocumentFragment;
|
package/types/observable.d.ts
CHANGED
|
@@ -50,11 +50,14 @@ export interface ObservableArray<T> extends ObservableItem<T[]> {
|
|
|
50
50
|
sort(compareFn?: (a: T, b: T) => number): T[];
|
|
51
51
|
splice(start: number, deleteCount?: number, ...items: T[]): T[];
|
|
52
52
|
|
|
53
|
+
isEmpty(): boolean;
|
|
53
54
|
clear(): boolean;
|
|
54
55
|
merge(values: T[]): void;
|
|
56
|
+
removeItem(item: T): T[];
|
|
55
57
|
remove(index: number): T[];
|
|
56
58
|
swap(indexA: number, indexB: number): boolean;
|
|
57
59
|
length(): number;
|
|
60
|
+
count(condition: (item:T, index?:number) => boolean): number;
|
|
58
61
|
populateAndRender(iteration: number, callback: (index: number) => T): void;
|
|
59
62
|
|
|
60
63
|
map<U>(callback: (value: T, index: number, array: T[]) => U): U[];
|
package/types/router.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Router system type definitions
|
|
2
|
-
import { ValidChild
|
|
2
|
+
import { ValidChild } from './elements';
|
|
3
|
+
import { NDElement } from './nd-element';
|
|
3
4
|
|
|
4
5
|
export interface RouteParams {
|
|
5
6
|
[key: string]: string;
|
|
@@ -42,7 +43,7 @@ export interface Router {
|
|
|
42
43
|
with?: Record<string, string>;
|
|
43
44
|
}): this;
|
|
44
45
|
|
|
45
|
-
group(suffix: string, options: { middlewares?: Function[]; name?: string }, callback: () => void): this;
|
|
46
|
+
group(suffix: string, options: { middlewares?: Function[]; name?: string, layout?: Function }, callback: () => void): this;
|
|
46
47
|
|
|
47
48
|
generateUrl(name: string, params?: RouteParams, query?: QueryParams): string;
|
|
48
49
|
resolve(target: string | { name: string; params?: RouteParams; query?: QueryParams }): {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AnchorDocumentFragment } from "./elements";
|
|
2
|
+
|
|
3
|
+
export type ViewCreator = (instance: SingletonView) => Node;
|
|
4
|
+
|
|
5
|
+
export type SectionFunction = (...args: any[]) => Node | Node[];
|
|
6
|
+
|
|
7
|
+
export type ComponentUpdater = (...args: any[]) => void;
|
|
8
|
+
|
|
9
|
+
export type ComponentsMap = Record<string, ComponentUpdater>;
|
|
10
|
+
|
|
11
|
+
export declare class SingletonView {
|
|
12
|
+
constructor(viewCreator: ViewCreator);
|
|
13
|
+
|
|
14
|
+
render(data: any[]): Node;
|
|
15
|
+
|
|
16
|
+
createSection(name: string, fn?: SectionFunction): AnchorDocumentFragment;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export declare function useSingleton(fn: ViewCreator): (...args: any[]) => Node;
|