-
Notifications
You must be signed in to change notification settings - Fork 439
Expand file tree
/
Copy pathcontext.ts
More file actions
72 lines (66 loc) · 2.47 KB
/
context.ts
File metadata and controls
72 lines (66 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import { createContextProviderWithRegister, getAssociatedVMIfPresent } from '@lwc/engine-core';
import { isUndefined, isNull } from '@lwc/shared';
import {
HostNodeType,
HostTypeKey,
HostParentKey,
HostHostKey,
HostContextProvidersKey,
} from './types';
import type { HostElement, HostParentNode } from './types';
import type {
LightningElement,
WireAdapterConstructor,
WireContextSubscriptionPayload,
WireContextSubscriptionCallback,
} from '@lwc/engine-core';
export function createContextProvider(adapter: WireAdapterConstructor) {
return createContextProviderWithRegister(adapter, registerContextProvider);
}
export function registerContextProvider(
elm: HostElement | LightningElement,
adapterContextToken: string,
onContextSubscription: WireContextSubscriptionCallback
) {
const vm = getAssociatedVMIfPresent(elm);
if (!isUndefined(vm)) {
elm = vm.elm;
}
const contextProviders = (elm as HostElement)[HostContextProvidersKey];
if (isUndefined(contextProviders)) {
throw new Error('Unable to register context provider on provided `elm`.');
}
contextProviders.set(adapterContextToken, onContextSubscription);
}
export function registerContextConsumer(
elm: HostElement,
adapterContextToken: string,
subscriptionPayload: WireContextSubscriptionPayload
) {
// Traverse element ancestors, looking for an element that can provide context
// for the adapter identified by `adapterContextToken`. If found, register
// to receive context updates from that provider.
let currentNode: HostParentNode | null = elm;
do {
if (currentNode[HostTypeKey] === HostNodeType.Element) {
const subscribeToProvider =
currentNode[HostContextProvidersKey].get(adapterContextToken);
if (!isUndefined(subscribeToProvider)) {
// If context subscription is successful, stop traversing to locate a provider
if (subscribeToProvider(subscriptionPayload)) {
break;
}
}
}
currentNode =
currentNode[HostTypeKey] === HostNodeType.Element
? currentNode[HostParentKey]
: currentNode[HostHostKey];
} while (!isNull(currentNode));
}