@es-joy/jsoe 0.31.0 → 0.32.0
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/CHANGES.md +4 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/search/fundamentalTypes/arraySearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/bigintSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/blobSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/booleanSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/catchSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/dateSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/domexceptionSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/enumSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/fileSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/filelistSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/functionSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/mapSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/numberSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/objectSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/promiseSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/regexpSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/setSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/stringSearchType.d.ts.map +1 -1
- package/dist/search/fundamentalTypes/symbolSearchType.d.ts.map +1 -1
- package/dist/search/index.d.ts +2 -0
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/searchDispatch.d.ts +11 -3
- package/dist/search/searchDispatch.d.ts.map +1 -1
- package/dist/search/searchElementUtils.d.ts +31 -1
- package/dist/search/searchElementUtils.d.ts.map +1 -1
- package/dist/search/searchUtils.d.ts +180 -0
- package/dist/search/searchUtils.d.ts.map +1 -1
- package/dist/search/subTypes/blobHTMLSearchType.d.ts.map +1 -1
- package/dist/search/subTypes/recordSearchType.d.ts.map +1 -1
- package/dist/search/subTypes/tupleSearchType.d.ts.map +1 -1
- package/dist/search/superTypes/SpecialRealNumberSearchType.d.ts.map +1 -1
- package/dist/search/superTypes/buffersourceSearchType.d.ts.map +1 -1
- package/dist/search/unions/unionFamilySearchType.d.ts.map +1 -1
- package/dist/utils/json6Stringify.d.ts +2 -0
- package/dist/utils/json6Stringify.d.ts.map +1 -0
- package/dist/utils/rawTypesonEditor.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/search/fundamentalTypes/arraySearchType.js +28 -5
- package/src/search/fundamentalTypes/bigintSearchType.js +14 -3
- package/src/search/fundamentalTypes/blobSearchType.js +21 -3
- package/src/search/fundamentalTypes/booleanSearchType.js +15 -3
- package/src/search/fundamentalTypes/catchSearchType.js +20 -3
- package/src/search/fundamentalTypes/dateSearchType.js +42 -3
- package/src/search/fundamentalTypes/domexceptionSearchType.js +18 -4
- package/src/search/fundamentalTypes/enumSearchType.js +15 -3
- package/src/search/fundamentalTypes/fileSearchType.js +15 -3
- package/src/search/fundamentalTypes/filelistSearchType.js +25 -5
- package/src/search/fundamentalTypes/functionSearchType.js +31 -4
- package/src/search/fundamentalTypes/mapSearchType.js +33 -5
- package/src/search/fundamentalTypes/numberSearchType.js +15 -3
- package/src/search/fundamentalTypes/objectSearchType.js +94 -5
- package/src/search/fundamentalTypes/promiseSearchType.js +20 -3
- package/src/search/fundamentalTypes/regexpSearchType.js +24 -4
- package/src/search/fundamentalTypes/setSearchType.js +25 -5
- package/src/search/fundamentalTypes/stringSearchType.js +25 -3
- package/src/search/fundamentalTypes/symbolSearchType.js +21 -3
- package/src/search/index.js +22 -0
- package/src/search/searchDispatch.js +14 -5
- package/src/search/searchElementUtils.js +98 -10
- package/src/search/searchUtils.js +368 -0
- package/src/search/subTypes/blobHTMLSearchType.js +43 -3
- package/src/search/subTypes/recordSearchType.js +30 -4
- package/src/search/subTypes/tupleSearchType.js +43 -5
- package/src/search/superTypes/SpecialRealNumberSearchType.js +15 -3
- package/src/search/superTypes/buffersourceSearchType.js +14 -3
- package/src/search/unions/unionFamilySearchType.js +45 -3
- package/src/utils/json6Stringify.js +50 -0
- package/src/utils/rawTypesonEditor.js +1 -51
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {buildPathLabel} from '../searchUtils.js';
|
|
1
|
+
import {buildPathLabel, extractLeafOfKind} from '../searchUtils.js';
|
|
2
2
|
import {makePassThroughLeaf} from '../queryTreeBuilders.js';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
findSearchElement, getQueryViaElement, hasGetQuery,
|
|
5
|
+
applyQueryViaElement, hasApplyQuery
|
|
6
|
+
} from '../searchElementUtils.js';
|
|
4
7
|
import {buildSearchWidget} from '../searchDispatch.js';
|
|
5
8
|
|
|
6
9
|
/**
|
|
@@ -48,6 +51,19 @@ const promiseSearchType = {
|
|
|
48
51
|
return childQuery === undefined
|
|
49
52
|
? undefined
|
|
50
53
|
: makePassThroughLeaf(searchPath, childQuery);
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* @this {HTMLElement}
|
|
57
|
+
* @param {import('../queryTree.js').QueryNode|undefined} queryNode
|
|
58
|
+
* @returns {void}
|
|
59
|
+
*/
|
|
60
|
+
applyQuery (queryNode) {
|
|
61
|
+
const {matched} = extractLeafOfKind(queryNode, 'passThrough');
|
|
62
|
+
const searchPath = this.dataset.searchPath ?? '';
|
|
63
|
+
const childEl = findSearchElement(this, searchPath);
|
|
64
|
+
if (childEl && hasApplyQuery(childEl)) {
|
|
65
|
+
childEl.applyQuery(matched?.query);
|
|
66
|
+
}
|
|
51
67
|
}
|
|
52
68
|
}
|
|
53
69
|
}, [
|
|
@@ -55,7 +71,8 @@ const promiseSearchType = {
|
|
|
55
71
|
childArr
|
|
56
72
|
]];
|
|
57
73
|
},
|
|
58
|
-
getQuery: getQueryViaElement
|
|
74
|
+
getQuery: getQueryViaElement,
|
|
75
|
+
applyQuery: applyQueryViaElement
|
|
59
76
|
};
|
|
60
77
|
|
|
61
78
|
export default promiseSearchType;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
buildPathLabel, buildLiteralRegexControls, readLiteralRegexQuery,
|
|
3
|
-
buildMultiSelect, readMultiSelect, findOwnControl
|
|
2
|
+
buildPathLabel, buildLiteralRegexControls, readLiteralRegexQuery, applyLiteralRegexQuery,
|
|
3
|
+
buildMultiSelect, readMultiSelect, applyMultiSelect, findOwnControl, extractLeafOfKind
|
|
4
4
|
} from '../searchUtils.js';
|
|
5
5
|
import {makeMultiSelectLeaf, combineAnd} from '../queryTreeBuilders.js';
|
|
6
|
-
import {getQueryViaElement} from '../searchElementUtils.js';
|
|
6
|
+
import {getQueryViaElement, applyQueryViaElement} from '../searchElementUtils.js';
|
|
7
7
|
import regexpType from '../../fundamentalTypes/regexpType.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -43,6 +43,25 @@ const regexpSearchType = {
|
|
|
43
43
|
? makeMultiSelectLeaf(searchPath, {$in: selectedFlags})
|
|
44
44
|
: undefined;
|
|
45
45
|
return combineAnd([sourceLeaf, flagsLeaf]);
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* @this {HTMLElement}
|
|
49
|
+
* @param {import('../queryTree.js').QueryNode|undefined} queryNode
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
applyQuery (queryNode) {
|
|
53
|
+
const {matched: flagsLeaf, rest: sourceLeaf} = extractLeafOfKind(queryNode, 'multiSelect');
|
|
54
|
+
// Sets Mode/Value first (dispatching the `change` that also
|
|
55
|
+
// toggles the Flags multi-select's own `hidden` state via this
|
|
56
|
+
// widget's `onModeChange`), then Flags.
|
|
57
|
+
applyLiteralRegexQuery(
|
|
58
|
+
this,
|
|
59
|
+
/**
|
|
60
|
+
* @type {import('../queryTree.js').QueryLiteralSetLeaf|
|
|
61
|
+
*import('../queryTree.js').QueryRegexLeaf|
|
|
62
|
+
import('../queryTree.js').QueryNotContainsLeaf|undefined} */ (sourceLeaf)
|
|
63
|
+
);
|
|
64
|
+
applyMultiSelect(this, flagsLeaf?.$in ?? []);
|
|
46
65
|
}
|
|
47
66
|
}
|
|
48
67
|
}, [
|
|
@@ -66,7 +85,8 @@ const regexpSearchType = {
|
|
|
66
85
|
]]
|
|
67
86
|
]];
|
|
68
87
|
},
|
|
69
|
-
getQuery: getQueryViaElement
|
|
88
|
+
getQuery: getQueryViaElement,
|
|
89
|
+
applyQuery: applyQueryViaElement
|
|
70
90
|
};
|
|
71
91
|
|
|
72
92
|
export default regexpSearchType;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
buildPathLabel, buildLengthSizeControls, readLengthSizeQuery,
|
|
3
|
-
buildOptInFieldset, readOptInChecked, wireOptInFieldset,
|
|
4
|
-
buildAtLeastOneSentinel, syncAtLeastOneCheck
|
|
2
|
+
buildPathLabel, buildLengthSizeControls, readLengthSizeQuery, applyLengthSizeQuery,
|
|
3
|
+
buildOptInFieldset, readOptInChecked, wireOptInFieldset, applyOptIn,
|
|
4
|
+
buildAtLeastOneSentinel, syncAtLeastOneCheck, extractLeafOfKind
|
|
5
5
|
} from '../searchUtils.js';
|
|
6
6
|
import {combineAnd} from '../queryTreeBuilders.js';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
findSearchElement, getQueryViaElement, hasGetQuery,
|
|
9
|
+
applyQueryViaElement, hasApplyQuery
|
|
10
|
+
} from '../searchElementUtils.js';
|
|
8
11
|
import {buildSearchWidget} from '../searchDispatch.js';
|
|
9
12
|
|
|
10
13
|
/**
|
|
@@ -69,6 +72,22 @@ const setSearchType = {
|
|
|
69
72
|
? elementEl.getQuery()
|
|
70
73
|
: undefined;
|
|
71
74
|
return combineAnd([lengthLeaf, elementLeaf]);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* @this {HTMLElement}
|
|
78
|
+
* @param {import('../queryTree.js').QueryNode|undefined} queryNode
|
|
79
|
+
* @returns {void}
|
|
80
|
+
*/
|
|
81
|
+
applyQuery (queryNode) {
|
|
82
|
+
const searchPath = this.dataset.searchPath ?? '';
|
|
83
|
+
const {matched: lengthLeaf, rest} = extractLeafOfKind(queryNode, 'lengthSize');
|
|
84
|
+
applyLengthSizeQuery(this, lengthLeaf);
|
|
85
|
+
applyOptIn(this, rest !== undefined, '');
|
|
86
|
+
const elementEl = findSearchElement(this, `${searchPath}/*`);
|
|
87
|
+
if (elementEl && hasApplyQuery(elementEl)) {
|
|
88
|
+
elementEl.applyQuery(rest);
|
|
89
|
+
}
|
|
90
|
+
syncSetValidity(this);
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
93
|
}, [
|
|
@@ -85,7 +104,8 @@ const setSearchType = {
|
|
|
85
104
|
buildAtLeastOneSentinel()
|
|
86
105
|
]];
|
|
87
106
|
},
|
|
88
|
-
getQuery: getQueryViaElement
|
|
107
|
+
getQuery: getQueryViaElement,
|
|
108
|
+
applyQuery: applyQueryViaElement
|
|
89
109
|
};
|
|
90
110
|
|
|
91
111
|
export default setSearchType;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
buildPathLabel, buildLiteralRegexControls, readLiteralRegexQuery, applyLiteralRegexQuery
|
|
3
|
+
} from '../searchUtils.js';
|
|
4
|
+
import {getQueryViaElement, applyQueryViaElement} from '../searchElementUtils.js';
|
|
3
5
|
import regexpType from '../../fundamentalTypes/regexpType.js';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -31,6 +33,25 @@ const stringSearchType = {
|
|
|
31
33
|
/** @this {HTMLElement} */
|
|
32
34
|
getQuery () {
|
|
33
35
|
return readLiteralRegexQuery(this, this.dataset.searchPath ?? '');
|
|
36
|
+
},
|
|
37
|
+
/**
|
|
38
|
+
* `getQuery` returns a bare leaf here (no other facet to combine it
|
|
39
|
+
* with via `$and`), so `queryNode` normally already is one -
|
|
40
|
+
* unwrapping a trivial one-element `$and` too just tolerates a
|
|
41
|
+
* hand-edited raw query that wraps it anyway.
|
|
42
|
+
* @this {HTMLElement}
|
|
43
|
+
* @param {import('../queryTree.js').QueryNode|undefined} queryNode
|
|
44
|
+
* @returns {void}
|
|
45
|
+
*/
|
|
46
|
+
applyQuery (queryNode) {
|
|
47
|
+
const leaf = queryNode && '$and' in queryNode ? queryNode.$and[0] : queryNode;
|
|
48
|
+
applyLiteralRegexQuery(
|
|
49
|
+
this,
|
|
50
|
+
/**
|
|
51
|
+
* @type {import('../queryTree.js').QueryLiteralSetLeaf|
|
|
52
|
+
*import('../queryTree.js').QueryRegexLeaf|
|
|
53
|
+
import('../queryTree.js').QueryNotContainsLeaf|undefined} */ (leaf)
|
|
54
|
+
);
|
|
34
55
|
}
|
|
35
56
|
}
|
|
36
57
|
}, [
|
|
@@ -38,7 +59,8 @@ const stringSearchType = {
|
|
|
38
59
|
buildLiteralRegexControls({name, flagOptions: regexpType.allowedFlags})
|
|
39
60
|
]];
|
|
40
61
|
},
|
|
41
|
-
getQuery: getQueryViaElement
|
|
62
|
+
getQuery: getQueryViaElement,
|
|
63
|
+
applyQuery: applyQueryViaElement
|
|
42
64
|
};
|
|
43
65
|
|
|
44
66
|
export default stringSearchType;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
buildPathLabel, buildLiteralRegexControls, readLiteralRegexQuery, applyLiteralRegexQuery
|
|
3
|
+
} from '../searchUtils.js';
|
|
4
|
+
import {getQueryViaElement, applyQueryViaElement} from '../searchElementUtils.js';
|
|
3
5
|
import regexpType from '../../fundamentalTypes/regexpType.js';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -26,6 +28,21 @@ const symbolSearchType = {
|
|
|
26
28
|
/** @this {HTMLElement} */
|
|
27
29
|
getQuery () {
|
|
28
30
|
return readLiteralRegexQuery(this, this.dataset.searchPath ?? '');
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* @this {HTMLElement}
|
|
34
|
+
* @param {import('../queryTree.js').QueryNode|undefined} queryNode
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
applyQuery (queryNode) {
|
|
38
|
+
const leaf = queryNode && '$and' in queryNode ? queryNode.$and[0] : queryNode;
|
|
39
|
+
applyLiteralRegexQuery(
|
|
40
|
+
this,
|
|
41
|
+
/**
|
|
42
|
+
* @type {import('../queryTree.js').QueryLiteralSetLeaf|
|
|
43
|
+
*import('../queryTree.js').QueryRegexLeaf|
|
|
44
|
+
import('../queryTree.js').QueryNotContainsLeaf|undefined} */ (leaf)
|
|
45
|
+
);
|
|
29
46
|
}
|
|
30
47
|
}
|
|
31
48
|
}, [
|
|
@@ -33,7 +50,8 @@ const symbolSearchType = {
|
|
|
33
50
|
buildLiteralRegexControls({name, flagOptions: regexpType.allowedFlags})
|
|
34
51
|
]];
|
|
35
52
|
},
|
|
36
|
-
getQuery: getQueryViaElement
|
|
53
|
+
getQuery: getQueryViaElement,
|
|
54
|
+
applyQuery: applyQueryViaElement
|
|
37
55
|
};
|
|
38
56
|
|
|
39
57
|
export default symbolSearchType;
|
package/src/search/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {getSearchTypeObject, buildSearchWidget, resolveIntersection} from './sea
|
|
|
5
5
|
* @typedef {{
|
|
6
6
|
* container: HTMLFormElement,
|
|
7
7
|
* $getQuery: () => import('./queryTree.js').QueryAnd,
|
|
8
|
+
* $applyQuery: (queryDoc: import('./queryTree.js').QueryAnd) => void,
|
|
8
9
|
* whenReady: Promise<void>
|
|
9
10
|
* }} SearchChoicesControl
|
|
10
11
|
*/
|
|
@@ -91,6 +92,27 @@ export function buildSearchChoices ({schemaContent, typeNamespace, topRoot, type
|
|
|
91
92
|
});
|
|
92
93
|
return {$and: result === undefined ? [] : [result]};
|
|
93
94
|
},
|
|
95
|
+
/**
|
|
96
|
+
* The "Edit raw" round-trip's entry point - the inverse of `$getQuery`,
|
|
97
|
+
* unwrapping its own `{$and: [...]}` convention back to a bare
|
|
98
|
+
* `QueryNode` (or `undefined` for an empty `$and`, "no constraint")
|
|
99
|
+
* before handing off to the root schema's own `applyQuery`, which
|
|
100
|
+
* recurses through the whole tree exactly as `getQuery` does.
|
|
101
|
+
* @param {import('./queryTree.js').QueryAnd} queryDoc
|
|
102
|
+
* @returns {void}
|
|
103
|
+
*/
|
|
104
|
+
$applyQuery (queryDoc) {
|
|
105
|
+
const {$and: clauses} = queryDoc;
|
|
106
|
+
let queryNode;
|
|
107
|
+
if (clauses.length === 1) {
|
|
108
|
+
[queryNode] = clauses;
|
|
109
|
+
} else if (clauses.length > 1) {
|
|
110
|
+
queryNode = {$and: clauses};
|
|
111
|
+
}
|
|
112
|
+
getSearchTypeObject(schemaObject).applyQuery({
|
|
113
|
+
root: container, path, queryNode
|
|
114
|
+
});
|
|
115
|
+
},
|
|
94
116
|
whenReady: Promise.resolve()
|
|
95
117
|
};
|
|
96
118
|
}
|
|
@@ -41,9 +41,12 @@ import blobHTMLSearchType from './subTypes/blobHTMLSearchType.js';
|
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* The search-side analogue of `TypeObject` (`src/types.js:308-408`):
|
|
45
|
-
* methods, `buildUI` (a `jml` array)
|
|
46
|
-
*
|
|
44
|
+
* The search-side analogue of `TypeObject` (`src/types.js:308-408`): three
|
|
45
|
+
* methods, `buildUI` (a `jml` array), `getQuery` (reads the built DOM back
|
|
46
|
+
* into a `QueryNode`, or `undefined` when no constraint was entered), and
|
|
47
|
+
* `applyQuery` (the inverse - drives the built DOM back into the state a
|
|
48
|
+
* previously-read, or hand-edited, `QueryNode` describes, for the "Edit raw"
|
|
49
|
+
* round-trip, `SearchChoicesControl.$applyQuery`, `src/search/index.js`).
|
|
47
50
|
* @typedef {{
|
|
48
51
|
* buildUI: (cfg: {
|
|
49
52
|
* schemaObject: import('../formats/schema.js').ZodexSchema,
|
|
@@ -56,7 +59,12 @@ import blobHTMLSearchType from './subTypes/blobHTMLSearchType.js';
|
|
|
56
59
|
* getQuery: (cfg: {
|
|
57
60
|
* root: HTMLElement,
|
|
58
61
|
* path: string
|
|
59
|
-
* }) => QueryNode|undefined
|
|
62
|
+
* }) => QueryNode|undefined,
|
|
63
|
+
* applyQuery: (cfg: {
|
|
64
|
+
* root: HTMLElement,
|
|
65
|
+
* path: string,
|
|
66
|
+
* queryNode: QueryNode|undefined
|
|
67
|
+
* }) => void
|
|
60
68
|
* }} SearchTypeObject
|
|
61
69
|
*/
|
|
62
70
|
|
|
@@ -71,7 +79,8 @@ import blobHTMLSearchType from './subTypes/blobHTMLSearchType.js';
|
|
|
71
79
|
function stubSearchType (searchSchemaType) {
|
|
72
80
|
return {
|
|
73
81
|
buildUI: () => ['span', [`TODO: ${searchSchemaType}`]],
|
|
74
|
-
getQuery: () => undefined
|
|
82
|
+
getQuery: () => undefined,
|
|
83
|
+
applyQuery () {}
|
|
75
84
|
};
|
|
76
85
|
}
|
|
77
86
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildPathLabel, buildCheckbox, readCheckbox,
|
|
3
|
-
buildLiteralRegexControls, readLiteralRegexQuery,
|
|
4
|
-
buildRangeInputsPair, readRangeInputsPair, syncRangeValidity,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
buildLiteralRegexControls, readLiteralRegexQuery, applyOptInLiteralRegexFacet,
|
|
4
|
+
buildRangeInputsPair, readRangeInputsPair, syncRangeValidity, applyOptInRangeFacet,
|
|
5
|
+
applyRangeQuery,
|
|
6
|
+
buildTriStateSelect, readTriStateSelect, applyTriState,
|
|
7
|
+
buildOptInFieldset, readOptInChecked, wireOptInFieldset, applyOptIn,
|
|
8
|
+
buildAtLeastOneSentinel, syncAtLeastOneCheck,
|
|
9
|
+
extractLeafOfKind
|
|
8
10
|
} from './searchUtils.js';
|
|
9
11
|
import {combineAnd, makeRangeLeaf, makeDomShapeLeaf} from './queryTreeBuilders.js';
|
|
10
12
|
import regexpType from '../fundamentalTypes/regexpType.js';
|
|
@@ -27,7 +29,8 @@ export function findSearchElement (root, path) {
|
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* @typedef {HTMLElement & {
|
|
30
|
-
* getQuery: () => import('./queryTree.js').QueryNode|undefined
|
|
32
|
+
* getQuery: () => import('./queryTree.js').QueryNode|undefined,
|
|
33
|
+
* applyQuery?: (queryNode: import('./queryTree.js').QueryNode|undefined) => void
|
|
31
34
|
* }} SearchElement
|
|
32
35
|
*/
|
|
33
36
|
|
|
@@ -45,6 +48,24 @@ export function getQueryViaElement ({root, path}) {
|
|
|
45
48
|
return el?.getQuery();
|
|
46
49
|
}
|
|
47
50
|
|
|
51
|
+
/**
|
|
52
|
+
* The `SearchTypeObject.applyQuery` every module implements identically -
|
|
53
|
+
* the "Edit raw" round-trip's counterpart to `getQueryViaElement`: locate
|
|
54
|
+
* the element built under `root` and delegate to its own `applyQuery(...)`
|
|
55
|
+
* method.
|
|
56
|
+
* @param {{
|
|
57
|
+
* root: HTMLElement, path: string,
|
|
58
|
+
* queryNode: import('./queryTree.js').QueryNode|undefined
|
|
59
|
+
* }} cfg
|
|
60
|
+
* @returns {void}
|
|
61
|
+
*/
|
|
62
|
+
export function applyQueryViaElement ({root, path, queryNode}) {
|
|
63
|
+
const el = /** @type {SearchElement|undefined} */ (
|
|
64
|
+
findSearchElement(root, path)
|
|
65
|
+
);
|
|
66
|
+
el?.applyQuery?.(queryNode);
|
|
67
|
+
}
|
|
68
|
+
|
|
48
69
|
/**
|
|
49
70
|
* Type-predicate guard distinguishing a built search element (leaf or
|
|
50
71
|
* container, either answers to `.getQuery()`) from a plain DOM node - used
|
|
@@ -60,6 +81,20 @@ export function hasGetQuery (el) {
|
|
|
60
81
|
'function';
|
|
61
82
|
}
|
|
62
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Same as `hasGetQuery`, for `applyQuery` - a container walking its own
|
|
86
|
+
* children to recurse an "Edit raw" apply into each needs to know which
|
|
87
|
+
* ones answer to it, same reasoning as `hasGetQuery`'s own doc.
|
|
88
|
+
* @param {Element} el
|
|
89
|
+
* @returns {el is SearchElement & {applyQuery: (
|
|
90
|
+
* queryNode: import('./queryTree.js').QueryNode|undefined
|
|
91
|
+
* ) => void}}
|
|
92
|
+
*/
|
|
93
|
+
export function hasApplyQuery (el) {
|
|
94
|
+
return typeof (/** @type {{applyQuery?: unknown}} */ (el)).applyQuery ===
|
|
95
|
+
'function';
|
|
96
|
+
}
|
|
97
|
+
|
|
63
98
|
/**
|
|
64
99
|
* Factory for the README's "no variants to allow for distinct search"
|
|
65
100
|
* leaves (`undefined`/`void`, `null`, `NaN`): the only meaningful question
|
|
@@ -89,7 +124,10 @@ export function makePresenceOnlySearchType ({tagName}) {
|
|
|
89
124
|
return checked
|
|
90
125
|
? {kind: 'presence', path: this.dataset.searchPath ?? '', $exists: true}
|
|
91
126
|
: undefined;
|
|
92
|
-
}
|
|
127
|
+
},
|
|
128
|
+
// The checkbox is permanently checked and `disabled` - nothing
|
|
129
|
+
// for a raw query to change here either way.
|
|
130
|
+
applyQuery () {}
|
|
93
131
|
}
|
|
94
132
|
}, [
|
|
95
133
|
['span', {class: 'searchLabel'}, [label]],
|
|
@@ -98,7 +136,8 @@ export function makePresenceOnlySearchType ({tagName}) {
|
|
|
98
136
|
})
|
|
99
137
|
]];
|
|
100
138
|
},
|
|
101
|
-
getQuery: getQueryViaElement
|
|
139
|
+
getQuery: getQueryViaElement,
|
|
140
|
+
applyQuery: applyQueryViaElement
|
|
102
141
|
};
|
|
103
142
|
}
|
|
104
143
|
|
|
@@ -211,11 +250,27 @@ export function makeErrorFamilySearchType ({tagName}) {
|
|
|
211
250
|
});
|
|
212
251
|
});
|
|
213
252
|
return combineAnd([...stringLeaves, ...numberLeaves]);
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* @this {HTMLElement}
|
|
256
|
+
* @param {import('./queryTree.js').QueryNode|undefined} queryNode
|
|
257
|
+
* @returns {void}
|
|
258
|
+
*/
|
|
259
|
+
applyQuery (queryNode) {
|
|
260
|
+
const searchPath = this.dataset.searchPath ?? '';
|
|
261
|
+
errorStringProps.forEach((prop) => {
|
|
262
|
+
applyOptInLiteralRegexFacet(this, queryNode, `${searchPath}/${prop}`, prop);
|
|
263
|
+
});
|
|
264
|
+
errorNumberProps.forEach((prop) => {
|
|
265
|
+
applyOptInRangeFacet(this, queryNode, `${searchPath}/${prop}`, prop);
|
|
266
|
+
});
|
|
267
|
+
syncErrorFamilyValidity(this);
|
|
214
268
|
}
|
|
215
269
|
}
|
|
216
270
|
}, buildErrorFamilyChildren({label, name})];
|
|
217
271
|
},
|
|
218
|
-
getQuery: getQueryViaElement
|
|
272
|
+
getQuery: getQueryViaElement,
|
|
273
|
+
applyQuery: applyQueryViaElement
|
|
219
274
|
};
|
|
220
275
|
}
|
|
221
276
|
|
|
@@ -362,12 +417,45 @@ export function makeDomShapeSearchType ({
|
|
|
362
417
|
? {}
|
|
363
418
|
: {dimensionCheck: dimensionCheck ? 3 : 2})
|
|
364
419
|
});
|
|
420
|
+
},
|
|
421
|
+
/**
|
|
422
|
+
* @this {HTMLElement}
|
|
423
|
+
* @param {import('./queryTree.js').QueryNode|undefined} queryNode
|
|
424
|
+
* @returns {void}
|
|
425
|
+
*/
|
|
426
|
+
applyQuery (queryNode) {
|
|
427
|
+
// A `domShape` leaf embeds each dimension's own `range` leaf
|
|
428
|
+
// directly (`dimensions`), not via `$and` - so, unlike
|
|
429
|
+
// `makeErrorFamilySearchType`'s flat properties,
|
|
430
|
+
// `extractClauseForPath` (which `applyOptInRangeFacet` uses)
|
|
431
|
+
// isn't needed here: read the whole leaf once and apply each
|
|
432
|
+
// dimension straight from it.
|
|
433
|
+
const {matched} = extractLeafOfKind(queryNode, 'domShape');
|
|
434
|
+
dimensionKeys.forEach((dim) => {
|
|
435
|
+
const dimLeaf = matched?.dimensions[dim];
|
|
436
|
+
applyOptIn(this, dimLeaf !== undefined, dim);
|
|
437
|
+
applyRangeQuery(this, dimLeaf, dim);
|
|
438
|
+
});
|
|
439
|
+
if (includeReadonly) {
|
|
440
|
+
applyTriState(this, matched?.readonlyCheck, 'readonly');
|
|
441
|
+
}
|
|
442
|
+
if (includeDimensionCheck) {
|
|
443
|
+
applyTriState(
|
|
444
|
+
this,
|
|
445
|
+
matched?.dimensionCheck === undefined
|
|
446
|
+
? undefined
|
|
447
|
+
: matched.dimensionCheck === 3,
|
|
448
|
+
'dimension'
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
syncDomShapeValidity({root: this, dimensionKeys, includeReadonly, includeDimensionCheck});
|
|
365
452
|
}
|
|
366
453
|
}
|
|
367
454
|
}, buildDomShapeChildren({
|
|
368
455
|
label, name, dimensionKeys, includeReadonly, includeDimensionCheck
|
|
369
456
|
})];
|
|
370
457
|
},
|
|
371
|
-
getQuery: getQueryViaElement
|
|
458
|
+
getQuery: getQueryViaElement,
|
|
459
|
+
applyQuery: applyQueryViaElement
|
|
372
460
|
};
|
|
373
461
|
}
|