0
# Compilation
1
2
Advanced selector compilation functionality for creating optimized resolver functions and managing the compilation pipeline. NWSAPI uses metaprogramming to transform CSS selectors into high-performance JavaScript functions.
3
4
## Capabilities
5
6
### Compile Function
7
8
Compiles a CSS selector into an optimized JavaScript resolver function using the specified source template and compilation mode.
9
10
```javascript { .api }
11
/**
12
* Compiles CSS selector into JavaScript resolver function
13
* @param selector - CSS selector string to compile
14
* @param mode - Compilation mode (true=select, false=match, null=collect)
15
* @param callback - Optional callback function for result processing
16
* @returns Compiled resolver function
17
*/
18
function compile(selector, mode, callback);
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
const nwsapi = require("nwsapi");
25
26
// Basic compilation for selection
27
const selectResolver = nwsapi.compile(
28
'div.container > p',
29
true // select mode
30
);
31
32
// Basic compilation for matching
33
const matchResolver = nwsapi.compile(
34
'.active',
35
false // match mode
36
);
37
38
// Compilation with callback
39
const callbackResolver = nwsapi.compile(
40
'button',
41
true, // select mode
42
function(element) { console.log('Found button:', element); }
43
);
44
45
// Use compiled resolver
46
const elements = selectResolver(document, null, [], []);
47
const matches = matchResolver(element);
48
```
49
50
## Compilation Modes
51
52
### Match Mode (false)
53
54
Compiles selectors for element matching operations (used by `match()` function).
55
56
```javascript { .api }
57
/**
58
* Match compilation mode
59
* @value false
60
*/
61
const MATCH_MODE = false;
62
```
63
64
**Characteristics:**
65
- Returns boolean result
66
- Optimized for single element testing
67
- Uses minimal memory allocation
68
- Fast execution for repeated matching operations
69
70
### Select Mode (true)
71
72
Compiles selectors for element selection operations (used by `select()` and `first()` functions).
73
74
```javascript { .api }
75
/**
76
* Select compilation mode
77
* @value true
78
*/
79
const SELECT_MODE = true;
80
```
81
82
**Characteristics:**
83
- Returns array of matching elements
84
- Optimized for traversing DOM trees
85
- Includes result collection logic
86
- Supports early termination for `first()` queries
87
88
### Collect Mode (null)
89
90
Compiles selectors for element collection operations with advanced filtering.
91
92
```javascript { .api }
93
/**
94
* Collect compilation mode
95
* @value null
96
*/
97
const COLLECT_MODE = null;
98
```
99
100
**Characteristics:**
101
- Advanced collection with deduplication
102
- Supports complex DOM traversal patterns
103
- Includes document order sorting
104
- Used for complex selector combinations
105
106
## Compilation Templates
107
108
### Source Templates
109
110
The compilation system uses configurable templates for different operational modes:
111
112
```javascript { .api }
113
/**
114
* Compilation body templates
115
*/
116
const S_BODY = 'r[++j]=c[k];'; // Select body template
117
const M_BODY = ''; // Match body template
118
const N_BODY = 'r[++j]=c.item(k);'; // NodeList body template
119
120
/**
121
* Compilation test templates
122
*/
123
const S_TEST = 'if(f(c[k])){break main;}'; // Select test template
124
const M_TEST = 'f(c);'; // Match test template
125
const N_TEST = 'if(f(c.item(k))){break main;}'; // NodeList test template
126
```
127
128
**Usage in Custom Compilation:**
129
130
```javascript
131
const nwsapi = require("nwsapi");
132
133
// Access compilation templates
134
const templates = {
135
selectBody: nwsapi.S_BODY,
136
matchBody: nwsapi.M_BODY,
137
selectTest: nwsapi.S_TEST,
138
matchTest: nwsapi.M_TEST
139
};
140
141
// Custom source template
142
const customSource = `
143
var elements = [];
144
var index = 0;
145
// Custom logic here
146
${nwsapi.S_BODY}
147
`;
148
149
const customResolver = nwsapi.compile('.my-selector', customSource, 1);
150
```
151
152
## Advanced Compilation Features
153
154
### Resolver Caching
155
156
Compilation results are automatically cached for performance:
157
158
```javascript
159
const nwsapi = require("nwsapi");
160
161
// First compilation - creates and caches resolver
162
console.time('first-compile');
163
const resolver1 = nwsapi.compile('.test', source, 1);
164
console.timeEnd('first-compile');
165
166
// Second compilation - returns cached resolver
167
console.time('second-compile');
168
const resolver2 = nwsapi.compile('.test', source, 1);
169
console.timeEnd('second-compile');
170
171
// resolver1 === resolver2 (same cached function)
172
```
173
174
### Custom Resolver Integration
175
176
```javascript
177
const nwsapi = require("nwsapi");
178
179
// Create specialized resolver
180
function createCustomResolver(selector) {
181
const source = `
182
var results = [];
183
var walker = document.createTreeWalker(
184
context,
185
NodeFilter.SHOW_ELEMENT,
186
null,
187
false
188
);
189
190
var node;
191
while (node = walker.nextNode()) {
192
if (/* custom matching logic */) {
193
${nwsapi.S_BODY.replace('c[k]', 'node')}
194
}
195
}
196
`;
197
198
return nwsapi.compile(selector, source, 1);
199
}
200
201
const customResolver = createCustomResolver('.special');
202
```
203
204
### Performance Optimization
205
206
```javascript
207
const nwsapi = require("nwsapi");
208
209
// Pre-compile frequently used selectors
210
const commonSelectors = ['.button', '.nav-item', '.content'];
211
const precompiledResolvers = commonSelectors.map(selector => ({
212
selector,
213
resolver: nwsapi.compile(selector, nwsapi.S_BODY, 1)
214
}));
215
216
// Use pre-compiled resolvers
217
function fastSelect(selector, context) {
218
const cached = precompiledResolvers.find(r => r.selector === selector);
219
if (cached) {
220
return cached.resolver(context, null, [], []);
221
}
222
return nwsapi.select(selector, context);
223
}
224
```
225
226
## Compilation Diagnostics
227
228
### Error Handling
229
230
```javascript
231
const nwsapi = require("nwsapi");
232
233
try {
234
const resolver = nwsapi.compile('invalid::selector', source, 1);
235
} catch (error) {
236
console.error('Compilation failed:', error.message);
237
}
238
239
// Validate selector before compilation
240
function safeCompile(selector, source, mode) {
241
try {
242
return nwsapi.compile(selector, source, mode);
243
} catch (error) {
244
console.warn(`Failed to compile selector "${selector}":`, error.message);
245
return null;
246
}
247
}
248
```
249
250
### Compilation Analysis
251
252
```javascript
253
const nwsapi = require("nwsapi");
254
255
// Analyze compilation performance
256
function analyzeCompilation(selector) {
257
const startTime = performance.now();
258
const resolver = nwsapi.compile(selector, nwsapi.S_BODY, 1);
259
const compileTime = performance.now() - startTime;
260
261
// Test resolver performance
262
const testStart = performance.now();
263
resolver(document, null, [], []);
264
const executeTime = performance.now() - testStart;
265
266
return {
267
selector,
268
compileTime,
269
executeTime,
270
resolver
271
};
272
}
273
274
const analysis = analyzeCompilation('div.container > p.highlight');
275
console.log('Compilation analysis:', analysis);
276
```
277
278
## Compilation Context
279
280
### Snapshot Object
281
282
Internal state object containing document context and method references passed to resolver functions during compilation.
283
284
```javascript { .api }
285
/**
286
* Compilation context and state information
287
* @type object
288
*/
289
const Snapshot: {
290
doc: Document; // Current document context
291
from: Element | Document; // Starting context element
292
root: Element; // Document root element
293
294
// Method references available to resolvers
295
byTag: Function; // Tag lookup method
296
first: Function; // First match method
297
match: Function; // Element matching method
298
ancestor: Function; // Ancestor traversal method
299
nthOfType: Function; // nth-of-type calculation
300
nthElement: Function; // nth-child calculation
301
302
// State utilities
303
isFocusable: Function; // Focus state checker
304
isContentEditable: Function; // Content editable checker
305
hasAttributeNS: Function; // Namespaced attribute checker
306
307
// Dynamic properties (set during compilation)
308
HOVER?: Element; // Currently hovered element
309
};
310
```
311
312
**Usage Examples:**
313
314
```javascript
315
const nwsapi = require("nwsapi");
316
317
// Access current compilation context
318
console.log('Current document:', nwsapi.Snapshot.doc);
319
console.log('Root element:', nwsapi.Snapshot.root);
320
321
// Check document context during compilation
322
function checkContext() {
323
if (nwsapi.Snapshot.doc !== document) {
324
console.log('Working with different document context');
325
}
326
327
console.log('Compilation from element:', nwsapi.Snapshot.from);
328
}
329
330
// The Snapshot object is primarily used internally by compiled resolvers
331
// but can be accessed for debugging compilation behavior
332
function debugResolver(element) {
333
console.log('Snapshot during resolution:', {
334
doc: nwsapi.Snapshot.doc === element.ownerDocument,
335
root: nwsapi.Snapshot.root === element.ownerDocument.documentElement,
336
context: nwsapi.Snapshot.from
337
});
338
}
339
```
340
341
## Best Practices
342
343
### When to Use Direct Compilation
344
345
- **High-frequency operations**: Pre-compile selectors used in loops
346
- **Custom logic**: When you need specialized DOM traversal
347
- **Performance critical**: When standard methods have too much overhead
348
- **Integration**: When embedding NWSAPI in other libraries
349
350
### When to Avoid Direct Compilation
351
352
- **Simple queries**: Use `select()`, `match()`, etc. for standard operations
353
- **One-off operations**: Compilation overhead not worth it for single use
354
- **Dynamic selectors**: Let NWSAPI handle caching automatically
355
- **Debugging**: Compiled functions are harder to debug than high-level methods