1 | import {Stream} from 'xstream';
|
2 | import {VNode} from 'snabbdom';
|
3 | import {isClassOrId} from './utils';
|
4 | import {MainDOMSource} from './MainDOMSource';
|
5 |
|
6 | export interface Scope {
|
7 | type: 'sibling' | 'total' | 'selector';
|
8 | scope: string;
|
9 | }
|
10 |
|
11 | export type IsolateSink<T extends VNode> = (
|
12 | s: Stream<T>,
|
13 | scope: string
|
14 | ) => Stream<T>;
|
15 |
|
16 | export function makeIsolateSink<T extends VNode>(
|
17 | namespace: Array<Scope>
|
18 | ): IsolateSink<T> {
|
19 | return (sink, scope) => {
|
20 | if (scope === ':root') {
|
21 | return sink;
|
22 | }
|
23 |
|
24 | return sink.map(node => {
|
25 | if (!node) {
|
26 | return node;
|
27 | }
|
28 | const scopeObj = getScopeObj(scope);
|
29 | const newNode = {
|
30 | ...(node as any),
|
31 | data: {
|
32 | ...node.data,
|
33 | isolate:
|
34 | !node.data || !Array.isArray(node.data.isolate)
|
35 | ? namespace.concat([scopeObj])
|
36 | : node.data.isolate,
|
37 | },
|
38 | };
|
39 | return {
|
40 | ...newNode,
|
41 | key:
|
42 | newNode.key !== undefined
|
43 | ? newNode.key
|
44 | : JSON.stringify(newNode.data.isolate),
|
45 | } as T;
|
46 | });
|
47 | };
|
48 | }
|
49 |
|
50 | export function getScopeObj(scope: string): Scope {
|
51 | return {
|
52 | type: isClassOrId(scope) ? 'sibling' : 'total',
|
53 | scope,
|
54 | };
|
55 | }
|