@@ -12,13 +12,14 @@ import {
12
12
type ComponentChildren ,
13
13
} from 'preact' ;
14
14
import { useRef , useCallback , useContext } from 'preact/hooks' ;
15
- import type { VNode , Context , RefObject } from 'preact' ;
15
+ import type { VNode , Context } from 'preact' ;
16
16
17
17
/**
18
18
* Internal dependencies
19
19
*/
20
20
import { store , stores , universalUnlock } from './store' ;
21
21
import { warn } from './utils' ;
22
+ import { getScope , setScope , resetScope , type Scope } from './scopes' ;
22
23
export interface DirectiveEntry {
23
24
value : string | object ;
24
25
namespace : string ;
@@ -69,14 +70,7 @@ interface DirectiveOptions {
69
70
priority ?: number ;
70
71
}
71
72
72
- interface Scope {
73
- evaluate : Evaluate ;
74
- context : object ;
75
- ref : RefObject < HTMLElement > ;
76
- attributes : createElement . JSX . HTMLAttributes ;
77
- }
78
-
79
- interface Evaluate {
73
+ export interface Evaluate {
80
74
( entry : DirectiveEntry , ...args : any [ ] ) : any ;
81
75
}
82
76
@@ -101,92 +95,6 @@ interface DirectivesProps {
101
95
// Main context.
102
96
const context = createContext < any > ( { } ) ;
103
97
104
- // Wrap the element props to prevent modifications.
105
- const immutableMap = new WeakMap ( ) ;
106
- const immutableError = ( ) => {
107
- throw new Error (
108
- 'Please use `data-wp-bind` to modify the attributes of an element.'
109
- ) ;
110
- } ;
111
- const immutableHandlers : ProxyHandler < object > = {
112
- get ( target , key , receiver ) {
113
- const value = Reflect . get ( target , key , receiver ) ;
114
- return ! ! value && typeof value === 'object'
115
- ? deepImmutable ( value )
116
- : value ;
117
- } ,
118
- set : immutableError ,
119
- deleteProperty : immutableError ,
120
- } ;
121
- const deepImmutable = < T extends object = { } > ( target : T ) : T => {
122
- if ( ! immutableMap . has ( target ) ) {
123
- immutableMap . set ( target , new Proxy ( target , immutableHandlers ) ) ;
124
- }
125
- return immutableMap . get ( target ) ;
126
- } ;
127
-
128
- // Store stacks for the current scope and the default namespaces and export APIs
129
- // to interact with them.
130
- const scopeStack : Scope [ ] = [ ] ;
131
- const namespaceStack : string [ ] = [ ] ;
132
-
133
- /**
134
- * Retrieves the context inherited by the element evaluating a function from the
135
- * store. The returned value depends on the element and the namespace where the
136
- * function calling `getContext()` exists.
137
- *
138
- * @param namespace Store namespace. By default, the namespace where the calling
139
- * function exists is used.
140
- * @return The context content.
141
- */
142
- export const getContext = < T extends object > ( namespace ?: string ) : T => {
143
- const scope = getScope ( ) ;
144
- if ( ! scope ) {
145
- throw Error (
146
- 'Cannot call `getContext()` outside getters and actions used by directives.'
147
- ) ;
148
- }
149
- return scope . context [ namespace || getNamespace ( ) ] ;
150
- } ;
151
-
152
- /**
153
- * Retrieves a representation of the element where a function from the store
154
- * is being evalutated. Such representation is read-only, and contains a
155
- * reference to the DOM element, its props and a local reactive state.
156
- *
157
- * @return Element representation.
158
- */
159
- export const getElement = ( ) => {
160
- if ( ! getScope ( ) ) {
161
- throw Error (
162
- 'Cannot call `getElement()` outside getters and actions used by directives.'
163
- ) ;
164
- }
165
- const { ref, attributes } = getScope ( ) ;
166
- return Object . freeze ( {
167
- ref : ref . current ,
168
- attributes : deepImmutable ( attributes ) ,
169
- } ) ;
170
- } ;
171
-
172
- export const getScope = ( ) => scopeStack . slice ( - 1 ) [ 0 ] ;
173
-
174
- export const setScope = ( scope : Scope ) => {
175
- scopeStack . push ( scope ) ;
176
- } ;
177
- export const resetScope = ( ) => {
178
- scopeStack . pop ( ) ;
179
- } ;
180
-
181
- export const getNamespace = ( ) => namespaceStack . slice ( - 1 ) [ 0 ] ;
182
-
183
- export const setNamespace = ( namespace : string ) => {
184
- namespaceStack . push ( namespace ) ;
185
- } ;
186
- export const resetNamespace = ( ) => {
187
- namespaceStack . pop ( ) ;
188
- } ;
189
-
190
98
// WordPress Directives.
191
99
const directiveCallbacks : Record < string , DirectiveCallback > = { } ;
192
100
const directivePriorities : Record < string , number > = { } ;
0 commit comments