clarity-pattern-parser 11.0.26 → 11.0.28
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/TODO.md +1 -4
- package/dist/index.browser.js +449 -8
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +448 -9
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +449 -8
- package/dist/index.js.map +1 -1
- package/dist/patterns/Expression.d.ts +1 -0
- package/dist/patterns/Reference.d.ts +2 -1
- package/dist/patterns/Repeat.d.ts +8 -0
- package/dist/query/query.d.ts +27 -0
- package/dist/query/selector.d.ts +21 -0
- package/dist/query/selector_parser.d.ts +1 -0
- package/package.json +1 -1
- package/src/generator/generator.test.ts +24 -0
- package/src/generator/generator.ts +108 -0
- package/src/generator/igenerator.ts +6 -0
- package/src/generator/ivisitor.ts +23 -0
- package/src/generator/typescriptVisitor.ts +158 -0
- package/src/grammar/Grammar.ts +2 -2
- package/src/index.ts +4 -0
- package/src/patterns/Expression.ts +5 -1
- package/src/patterns/Reference.ts +8 -6
- package/src/patterns/Repeat.ts +8 -0
- package/src/query/query.test.ts +34 -0
- package/src/query/query.ts +20 -0
- package/tsconfig.json +1 -1
package/dist/index.js
CHANGED
|
@@ -850,10 +850,11 @@ class Reference {
|
|
|
850
850
|
get startedOnIndex() {
|
|
851
851
|
return this._firstIndex;
|
|
852
852
|
}
|
|
853
|
-
constructor(name) {
|
|
853
|
+
constructor(name, referencePatternName) {
|
|
854
854
|
this._id = `reference-${idIndex$7++}`;
|
|
855
855
|
this._type = "reference";
|
|
856
856
|
this._name = name;
|
|
857
|
+
this._referencePatternName = referencePatternName || name;
|
|
857
858
|
this._parent = null;
|
|
858
859
|
this._pattern = null;
|
|
859
860
|
this._cachedPattern = null;
|
|
@@ -912,9 +913,9 @@ class Reference {
|
|
|
912
913
|
pattern = this._cachedPattern;
|
|
913
914
|
}
|
|
914
915
|
if (pattern === null) {
|
|
915
|
-
throw new Error(`Couldn't find '${this.
|
|
916
|
+
throw new Error(`Couldn't find '${this._referencePatternName}' pattern within tree.`);
|
|
916
917
|
}
|
|
917
|
-
const clonedPattern = pattern.clone();
|
|
918
|
+
const clonedPattern = pattern.clone(this._name);
|
|
918
919
|
clonedPattern.parent = this;
|
|
919
920
|
this._pattern = clonedPattern;
|
|
920
921
|
this._children = [this._pattern];
|
|
@@ -928,7 +929,7 @@ class Reference {
|
|
|
928
929
|
pattern = pattern.parent;
|
|
929
930
|
continue;
|
|
930
931
|
}
|
|
931
|
-
const foundPattern = pattern.getPatternWithinContext(this.
|
|
932
|
+
const foundPattern = pattern.getPatternWithinContext(this._referencePatternName);
|
|
932
933
|
if (foundPattern != null && this._isValidPattern(foundPattern)) {
|
|
933
934
|
return foundPattern;
|
|
934
935
|
}
|
|
@@ -936,7 +937,7 @@ class Reference {
|
|
|
936
937
|
}
|
|
937
938
|
const root = this._getRoot();
|
|
938
939
|
return findPattern(root, (pattern) => {
|
|
939
|
-
return pattern.name === this.
|
|
940
|
+
return pattern.name === this._referencePatternName && this._isValidPattern(pattern);
|
|
940
941
|
});
|
|
941
942
|
}
|
|
942
943
|
_isValidPattern(pattern) {
|
|
@@ -995,7 +996,7 @@ class Reference {
|
|
|
995
996
|
return null;
|
|
996
997
|
}
|
|
997
998
|
clone(name = this._name) {
|
|
998
|
-
const clone = new Reference(name);
|
|
999
|
+
const clone = new Reference(name, this._referencePatternName);
|
|
999
1000
|
clone._id = this._id;
|
|
1000
1001
|
// Optimize future clones, by caching the pattern we already found.
|
|
1001
1002
|
if (this._pattern != null) {
|
|
@@ -1617,6 +1618,12 @@ class Repeat {
|
|
|
1617
1618
|
get startedOnIndex() {
|
|
1618
1619
|
return this._repeatPattern.startedOnIndex;
|
|
1619
1620
|
}
|
|
1621
|
+
get pattern() {
|
|
1622
|
+
return this._pattern;
|
|
1623
|
+
}
|
|
1624
|
+
get options() {
|
|
1625
|
+
return this._options;
|
|
1626
|
+
}
|
|
1620
1627
|
constructor(name, pattern, options = {}) {
|
|
1621
1628
|
this._id = `repeat-${idIndex$3++}`;
|
|
1622
1629
|
this._pattern = pattern;
|
|
@@ -2678,6 +2685,9 @@ class Expression {
|
|
|
2678
2685
|
get binaryPatterns() {
|
|
2679
2686
|
return this._binaryPatterns;
|
|
2680
2687
|
}
|
|
2688
|
+
get originalPatterns() {
|
|
2689
|
+
return this._originalPatterns;
|
|
2690
|
+
}
|
|
2681
2691
|
get startedOnIndex() {
|
|
2682
2692
|
return this._firstIndex;
|
|
2683
2693
|
}
|
|
@@ -3589,8 +3599,8 @@ class Grammar {
|
|
|
3589
3599
|
const aliasPattern = this._getPattern(aliasName);
|
|
3590
3600
|
// This solves the problem for an alias pointing to a reference.
|
|
3591
3601
|
if (aliasPattern.type === "reference") {
|
|
3592
|
-
const
|
|
3593
|
-
this._parseContext.patternsByName.set(name,
|
|
3602
|
+
const reference = new Reference(name, aliasName);
|
|
3603
|
+
this._parseContext.patternsByName.set(name, reference);
|
|
3594
3604
|
}
|
|
3595
3605
|
else {
|
|
3596
3606
|
const alias = aliasPattern.clone(name);
|
|
@@ -3858,6 +3868,435 @@ function patterns(strings, ...values) {
|
|
|
3858
3868
|
return result;
|
|
3859
3869
|
}
|
|
3860
3870
|
|
|
3871
|
+
const { expression } = patterns `
|
|
3872
|
+
number = /[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?/
|
|
3873
|
+
spaces = /\\s+/
|
|
3874
|
+
single-quote-string-literal = /'(?:\\\\.|[^'\\\\])*'/
|
|
3875
|
+
name = /[a-zA-Z_-]+[a-zA-Z0-9_-]*/
|
|
3876
|
+
comma = /\\s*,\\s*/
|
|
3877
|
+
wild-card = "*"
|
|
3878
|
+
equal = "="
|
|
3879
|
+
not-equal = "!="
|
|
3880
|
+
starts-with = "^="
|
|
3881
|
+
ends-with = "$="
|
|
3882
|
+
contains = "*="
|
|
3883
|
+
greater-than-or-equal = ">="
|
|
3884
|
+
less-than-or-equal = "<="
|
|
3885
|
+
greater-than = ">"
|
|
3886
|
+
less-than = "<"
|
|
3887
|
+
operators = equal |
|
|
3888
|
+
not-equal |
|
|
3889
|
+
starts-with |
|
|
3890
|
+
ends-with |
|
|
3891
|
+
contains |
|
|
3892
|
+
greater-than-or-equal |
|
|
3893
|
+
less-than-or-equal |
|
|
3894
|
+
greater-than |
|
|
3895
|
+
less-than
|
|
3896
|
+
|
|
3897
|
+
attribute-name = name
|
|
3898
|
+
value = name
|
|
3899
|
+
attribute-value = single-quote-string-literal | number | value
|
|
3900
|
+
attribute-selector = "[" + spaces? + attribute-name + spaces? + operators + spaces? + attribute-value + "]"
|
|
3901
|
+
|
|
3902
|
+
adjacent = spaces? + "+" + spaces?
|
|
3903
|
+
after = spaces? + "~" + spaces?
|
|
3904
|
+
direct-child = spaces? + ">" + spaces?
|
|
3905
|
+
descendant = spaces
|
|
3906
|
+
|
|
3907
|
+
combinators = adjacent | after | direct-child | descendant
|
|
3908
|
+
name-selector = name-selector-expression + attribute-selector
|
|
3909
|
+
name-selector-expression = name-selector | name
|
|
3910
|
+
node-selector = wild-card | attribute-selector | name-selector-expression
|
|
3911
|
+
or-selector = (node-selector, comma){2}
|
|
3912
|
+
|
|
3913
|
+
selector-expression = expression + combinators + expression
|
|
3914
|
+
expression = selector-expression | or-selector | node-selector
|
|
3915
|
+
`;
|
|
3916
|
+
const selectorParser = expression;
|
|
3917
|
+
|
|
3918
|
+
const combinatorMap = {
|
|
3919
|
+
"adjacent": true,
|
|
3920
|
+
"after": true,
|
|
3921
|
+
"descendant": true,
|
|
3922
|
+
"direct-child": true
|
|
3923
|
+
};
|
|
3924
|
+
const operatorMap = {
|
|
3925
|
+
"equal": true,
|
|
3926
|
+
"not-equal": true,
|
|
3927
|
+
"starts-with": true,
|
|
3928
|
+
"ends-with": true,
|
|
3929
|
+
"contains": true,
|
|
3930
|
+
"greater-than-or-equal": true,
|
|
3931
|
+
"less-than-or-equal": true,
|
|
3932
|
+
"greater-than": true,
|
|
3933
|
+
"less-than": true
|
|
3934
|
+
};
|
|
3935
|
+
class Selector {
|
|
3936
|
+
constructor(selector) {
|
|
3937
|
+
this._selectedNodes = [];
|
|
3938
|
+
this._combinator = null;
|
|
3939
|
+
const result = selectorParser.exec(selector);
|
|
3940
|
+
if (result.ast == null) {
|
|
3941
|
+
const message = generateErrorMessage(selectorParser, result.cursor);
|
|
3942
|
+
throw new Error(`[Invalid Selector] ${message}`);
|
|
3943
|
+
}
|
|
3944
|
+
this._selectorAst = result.ast;
|
|
3945
|
+
}
|
|
3946
|
+
find(nodes) {
|
|
3947
|
+
this._selectedNodes = nodes;
|
|
3948
|
+
const ast = this._selectorAst;
|
|
3949
|
+
ast.walkUp((node) => {
|
|
3950
|
+
this._process(node);
|
|
3951
|
+
});
|
|
3952
|
+
return this._selectedNodes;
|
|
3953
|
+
}
|
|
3954
|
+
filter(nodes) {
|
|
3955
|
+
if (nodes.length < 1) {
|
|
3956
|
+
return [];
|
|
3957
|
+
}
|
|
3958
|
+
const nodeMap = new Map();
|
|
3959
|
+
nodes.forEach(n => nodeMap.set(n, n));
|
|
3960
|
+
this._selectedNodes = [nodes[0].findRoot()];
|
|
3961
|
+
const ast = this._selectorAst;
|
|
3962
|
+
ast.walkUp((node) => {
|
|
3963
|
+
this._process(node);
|
|
3964
|
+
});
|
|
3965
|
+
return this._selectedNodes.filter(n => nodeMap.has(n));
|
|
3966
|
+
}
|
|
3967
|
+
not(nodes) {
|
|
3968
|
+
if (nodes.length < 1) {
|
|
3969
|
+
return [];
|
|
3970
|
+
}
|
|
3971
|
+
this._selectedNodes = [nodes[0].findRoot()];
|
|
3972
|
+
const ast = this._selectorAst;
|
|
3973
|
+
ast.walkUp((node) => {
|
|
3974
|
+
this._process(node);
|
|
3975
|
+
});
|
|
3976
|
+
const selectedNodeMap = new Map();
|
|
3977
|
+
this._selectedNodes.forEach(n => selectedNodeMap.set(n, n));
|
|
3978
|
+
return nodes.filter(n => !selectedNodeMap.has(n));
|
|
3979
|
+
}
|
|
3980
|
+
parents(nodes) {
|
|
3981
|
+
if (nodes.length < 1) {
|
|
3982
|
+
return [];
|
|
3983
|
+
}
|
|
3984
|
+
this._selectedNodes = [nodes[0].findRoot()];
|
|
3985
|
+
const ast = this._selectorAst;
|
|
3986
|
+
ast.walkUp((node) => {
|
|
3987
|
+
this._process(node);
|
|
3988
|
+
});
|
|
3989
|
+
const result = new Set();
|
|
3990
|
+
const ancestorMap = new Map();
|
|
3991
|
+
this._selectedNodes.forEach(n => ancestorMap.set(n, true));
|
|
3992
|
+
nodes.forEach(n => {
|
|
3993
|
+
const ancestor = n.findAncestor(a => ancestorMap.has(a));
|
|
3994
|
+
if (ancestor != null) {
|
|
3995
|
+
result.add(ancestor);
|
|
3996
|
+
}
|
|
3997
|
+
});
|
|
3998
|
+
return Array.from(result);
|
|
3999
|
+
}
|
|
4000
|
+
_process(ast) {
|
|
4001
|
+
const nodeName = ast.name;
|
|
4002
|
+
if (nodeName === "wild-card") {
|
|
4003
|
+
this._selectedNodes = this._processWildCard();
|
|
4004
|
+
}
|
|
4005
|
+
else if (nodeName === "or-selector") {
|
|
4006
|
+
this._selectedNodes = this._processOrSelector(ast);
|
|
4007
|
+
}
|
|
4008
|
+
else if (nodeName === "name-selector" || (nodeName === "name" && (ast.parent == null || ast.parent.name === "selector-expression"))) {
|
|
4009
|
+
this._selectedNodes = this._processNameSelector(ast);
|
|
4010
|
+
}
|
|
4011
|
+
else if (nodeName === "attribute-selector" && (ast.parent == null || ast.parent.name === "selector-expression")) {
|
|
4012
|
+
this._selectedNodes = this._processAttributeSelector(ast);
|
|
4013
|
+
}
|
|
4014
|
+
else if (combinatorMap[nodeName]) {
|
|
4015
|
+
this._combinator = nodeName;
|
|
4016
|
+
}
|
|
4017
|
+
else if (nodeName === "selector-expression") {
|
|
4018
|
+
this._combinator = null;
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
_processWildCard() {
|
|
4022
|
+
return this._selectedNodes.map(n => {
|
|
4023
|
+
return this._selectWithCombinator(n, () => true);
|
|
4024
|
+
}).flat();
|
|
4025
|
+
}
|
|
4026
|
+
_processOrSelector(ast) {
|
|
4027
|
+
const selectorNodes = ast.children.filter(n => n.name !== "comma");
|
|
4028
|
+
const set = new Set();
|
|
4029
|
+
const selectors = selectorNodes.map(n => new Selector(n.toString()));
|
|
4030
|
+
selectors.map(s => {
|
|
4031
|
+
return s.find(this._selectedNodes.slice());
|
|
4032
|
+
}).flat().forEach((node) => {
|
|
4033
|
+
set.add(node);
|
|
4034
|
+
});
|
|
4035
|
+
return Array.from(set);
|
|
4036
|
+
}
|
|
4037
|
+
_processNameSelector(ast) {
|
|
4038
|
+
if (ast.children.length > 1) {
|
|
4039
|
+
return this._selectedNodes.map(n => {
|
|
4040
|
+
const name = ast.children[0].value;
|
|
4041
|
+
return this._selectWithCombinator(n, (node) => {
|
|
4042
|
+
return node.name === name && this._isAttributeMatch(node, ast);
|
|
4043
|
+
});
|
|
4044
|
+
}).flat();
|
|
4045
|
+
}
|
|
4046
|
+
else {
|
|
4047
|
+
return this._selectedNodes.map(n => {
|
|
4048
|
+
return this._selectWithCombinator(n, (node) => node.name === ast.value);
|
|
4049
|
+
}).flat();
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
_processAttributeSelector(ast) {
|
|
4053
|
+
return this._selectedNodes.map(n => {
|
|
4054
|
+
return this._selectWithCombinator(n, (node) => {
|
|
4055
|
+
return this._isAttributeMatch(node, ast);
|
|
4056
|
+
});
|
|
4057
|
+
}).flat();
|
|
4058
|
+
}
|
|
4059
|
+
_selectWithCombinator(node, predicate) {
|
|
4060
|
+
if (this._combinator === "adjacent") {
|
|
4061
|
+
const sibling = node.nextSibling();
|
|
4062
|
+
if (sibling == null) {
|
|
4063
|
+
return [];
|
|
4064
|
+
}
|
|
4065
|
+
if (predicate(sibling)) {
|
|
4066
|
+
return [sibling];
|
|
4067
|
+
}
|
|
4068
|
+
else {
|
|
4069
|
+
return [];
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
else if (this._combinator === "after") {
|
|
4073
|
+
const parent = node.parent;
|
|
4074
|
+
if (parent == null) {
|
|
4075
|
+
return [];
|
|
4076
|
+
}
|
|
4077
|
+
const index = parent.findChildIndex(node);
|
|
4078
|
+
const after = parent.children.slice(index + 1);
|
|
4079
|
+
return after.filter(predicate);
|
|
4080
|
+
}
|
|
4081
|
+
else if (this._combinator === "direct-child") {
|
|
4082
|
+
return node.children.filter(predicate);
|
|
4083
|
+
}
|
|
4084
|
+
else if (this._combinator === "descendant" || this._combinator == null) {
|
|
4085
|
+
return node.findAll(predicate);
|
|
4086
|
+
}
|
|
4087
|
+
else {
|
|
4088
|
+
return [];
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
_isAttributeMatch(node, ast) {
|
|
4092
|
+
const name = this._getAttributeName(ast);
|
|
4093
|
+
const operator = this._getAttributeOperator(ast);
|
|
4094
|
+
const value = this._getAttributeValue(ast);
|
|
4095
|
+
const anyNode = node;
|
|
4096
|
+
if (anyNode[name] == null) {
|
|
4097
|
+
return false;
|
|
4098
|
+
}
|
|
4099
|
+
if (operator === "equal") {
|
|
4100
|
+
return anyNode[name] === value;
|
|
4101
|
+
}
|
|
4102
|
+
else if (operator === "not-equal") {
|
|
4103
|
+
return anyNode[name] !== value;
|
|
4104
|
+
}
|
|
4105
|
+
else if (operator === "starts-with") {
|
|
4106
|
+
return anyNode[name].toString().startsWith(value);
|
|
4107
|
+
}
|
|
4108
|
+
else if (operator === "ends-with") {
|
|
4109
|
+
return anyNode[name].toString().endsWith(value);
|
|
4110
|
+
}
|
|
4111
|
+
else if (operator === "contains") {
|
|
4112
|
+
return anyNode[name].toString().includes(value);
|
|
4113
|
+
}
|
|
4114
|
+
else if (operator === "greater-than-or-equal") {
|
|
4115
|
+
return anyNode[name] >= value;
|
|
4116
|
+
}
|
|
4117
|
+
else if (operator === "less-than-or-equal") {
|
|
4118
|
+
return anyNode[name] <= value;
|
|
4119
|
+
}
|
|
4120
|
+
else if (operator === "greater-than") {
|
|
4121
|
+
return anyNode[name] > value;
|
|
4122
|
+
}
|
|
4123
|
+
else if (operator === "less-than") {
|
|
4124
|
+
return anyNode[name] < value;
|
|
4125
|
+
}
|
|
4126
|
+
return false;
|
|
4127
|
+
}
|
|
4128
|
+
_getAttributeName(ast) {
|
|
4129
|
+
return ast.find(n => n.name === "attribute-name").value;
|
|
4130
|
+
}
|
|
4131
|
+
_getAttributeValue(ast) {
|
|
4132
|
+
let valueNode = ast.find(n => n.name === "single-quote-string-literal");
|
|
4133
|
+
if (valueNode != null) {
|
|
4134
|
+
return valueNode.value.slice(1, -1);
|
|
4135
|
+
}
|
|
4136
|
+
else {
|
|
4137
|
+
valueNode = ast.find(n => n.name === "value");
|
|
4138
|
+
}
|
|
4139
|
+
if (valueNode != null) {
|
|
4140
|
+
return valueNode.value;
|
|
4141
|
+
}
|
|
4142
|
+
else {
|
|
4143
|
+
valueNode = ast.find(n => n.name === "number");
|
|
4144
|
+
}
|
|
4145
|
+
return valueNode.value;
|
|
4146
|
+
}
|
|
4147
|
+
_getAttributeOperator(ast) {
|
|
4148
|
+
return ast.find(n => operatorMap[n.name]).name;
|
|
4149
|
+
}
|
|
4150
|
+
}
|
|
4151
|
+
|
|
4152
|
+
class Query {
|
|
4153
|
+
constructor(context, prevQuery = null) {
|
|
4154
|
+
this._context = context;
|
|
4155
|
+
this._prevQuery = prevQuery;
|
|
4156
|
+
}
|
|
4157
|
+
toArray() {
|
|
4158
|
+
return this._context.slice();
|
|
4159
|
+
}
|
|
4160
|
+
// Modifiers
|
|
4161
|
+
append(visitor) {
|
|
4162
|
+
this._context.forEach(n => {
|
|
4163
|
+
const parent = n.parent;
|
|
4164
|
+
if (parent == null) {
|
|
4165
|
+
return;
|
|
4166
|
+
}
|
|
4167
|
+
const newNode = visitor(n);
|
|
4168
|
+
n.appendChild(newNode);
|
|
4169
|
+
});
|
|
4170
|
+
return this;
|
|
4171
|
+
}
|
|
4172
|
+
prepend(visitor) {
|
|
4173
|
+
this._context.forEach(n => {
|
|
4174
|
+
const parent = n.parent;
|
|
4175
|
+
if (parent == null) {
|
|
4176
|
+
return;
|
|
4177
|
+
}
|
|
4178
|
+
const newNode = visitor(n);
|
|
4179
|
+
n.insertBefore(newNode, n.children[0]);
|
|
4180
|
+
});
|
|
4181
|
+
return this;
|
|
4182
|
+
}
|
|
4183
|
+
after(visitor) {
|
|
4184
|
+
this._context.forEach(n => {
|
|
4185
|
+
const parent = n.parent;
|
|
4186
|
+
if (parent == null) {
|
|
4187
|
+
return;
|
|
4188
|
+
}
|
|
4189
|
+
const index = parent.findChildIndex(n);
|
|
4190
|
+
const newNode = visitor(n);
|
|
4191
|
+
parent.spliceChildren(index + 1, 0, newNode);
|
|
4192
|
+
});
|
|
4193
|
+
return this;
|
|
4194
|
+
}
|
|
4195
|
+
before(visitor) {
|
|
4196
|
+
this._context.forEach(n => {
|
|
4197
|
+
const parent = n.parent;
|
|
4198
|
+
if (parent == null) {
|
|
4199
|
+
return;
|
|
4200
|
+
}
|
|
4201
|
+
const index = parent.findChildIndex(n);
|
|
4202
|
+
const newNode = visitor(n);
|
|
4203
|
+
parent.spliceChildren(index, 0, newNode);
|
|
4204
|
+
});
|
|
4205
|
+
return this;
|
|
4206
|
+
}
|
|
4207
|
+
replaceWith(visitor) {
|
|
4208
|
+
this._context.forEach(n => {
|
|
4209
|
+
const newNode = visitor(n);
|
|
4210
|
+
n.replaceWith(newNode);
|
|
4211
|
+
});
|
|
4212
|
+
return this;
|
|
4213
|
+
}
|
|
4214
|
+
compact() {
|
|
4215
|
+
this._context.forEach(n => {
|
|
4216
|
+
n.compact();
|
|
4217
|
+
});
|
|
4218
|
+
return this;
|
|
4219
|
+
}
|
|
4220
|
+
setValue(value) {
|
|
4221
|
+
this.replaceWith((n) => {
|
|
4222
|
+
return Node.createValueNode(n.type, n.name, value);
|
|
4223
|
+
});
|
|
4224
|
+
return this;
|
|
4225
|
+
}
|
|
4226
|
+
normalize() {
|
|
4227
|
+
const first = this._context[0];
|
|
4228
|
+
if (first != null) {
|
|
4229
|
+
first.findRoot().normalize();
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
remove() {
|
|
4233
|
+
this._context.forEach(n => {
|
|
4234
|
+
n.remove();
|
|
4235
|
+
});
|
|
4236
|
+
return this;
|
|
4237
|
+
}
|
|
4238
|
+
// Filters from the currently matched nodes
|
|
4239
|
+
slice(start, end) {
|
|
4240
|
+
return new Query(this._context.slice(start, end));
|
|
4241
|
+
}
|
|
4242
|
+
filter(selectorString) {
|
|
4243
|
+
const selector = new Selector(selectorString);
|
|
4244
|
+
const newContext = selector.filter(this._context);
|
|
4245
|
+
return new Query(newContext, this);
|
|
4246
|
+
}
|
|
4247
|
+
// Selects out of all descedants of currently matched nodes
|
|
4248
|
+
find(selectorString) {
|
|
4249
|
+
const selector = new Selector(selectorString);
|
|
4250
|
+
const newContext = selector.find(this._context);
|
|
4251
|
+
return new Query(newContext, this);
|
|
4252
|
+
}
|
|
4253
|
+
// Remove nodes from the set of matched nodes.
|
|
4254
|
+
not(selectorString) {
|
|
4255
|
+
const selector = new Selector(selectorString);
|
|
4256
|
+
const newContext = selector.not(this._context);
|
|
4257
|
+
return new Query(newContext, this);
|
|
4258
|
+
}
|
|
4259
|
+
// Select the parent of currently matched nodes
|
|
4260
|
+
parent() {
|
|
4261
|
+
const parents = this._context.map(n => n.parent);
|
|
4262
|
+
const result = new Set();
|
|
4263
|
+
parents.forEach((n) => {
|
|
4264
|
+
if (n != null) {
|
|
4265
|
+
result.add(n);
|
|
4266
|
+
}
|
|
4267
|
+
});
|
|
4268
|
+
return new Query(Array.from(result), this);
|
|
4269
|
+
}
|
|
4270
|
+
// Select the ancestors of currently matched nodes
|
|
4271
|
+
parents(selectorString) {
|
|
4272
|
+
const selector = new Selector(selectorString);
|
|
4273
|
+
const newContext = selector.parents(this._context);
|
|
4274
|
+
const result = new Set();
|
|
4275
|
+
newContext.forEach((n) => {
|
|
4276
|
+
if (n != null) {
|
|
4277
|
+
result.add(n);
|
|
4278
|
+
}
|
|
4279
|
+
});
|
|
4280
|
+
return new Query(Array.from(result), this);
|
|
4281
|
+
}
|
|
4282
|
+
first() {
|
|
4283
|
+
return new Query(this._context.slice(0, 1), this);
|
|
4284
|
+
}
|
|
4285
|
+
last() {
|
|
4286
|
+
return new Query(this._context.slice(-1), this);
|
|
4287
|
+
}
|
|
4288
|
+
// Pop query stack
|
|
4289
|
+
end() {
|
|
4290
|
+
if (this._prevQuery) {
|
|
4291
|
+
return this._prevQuery;
|
|
4292
|
+
}
|
|
4293
|
+
return this;
|
|
4294
|
+
}
|
|
4295
|
+
length() {
|
|
4296
|
+
return this._context.length;
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
|
|
3861
4300
|
exports.AutoComplete = AutoComplete;
|
|
3862
4301
|
exports.Context = Context;
|
|
3863
4302
|
exports.Cursor = Cursor;
|
|
@@ -3870,10 +4309,12 @@ exports.Not = Not;
|
|
|
3870
4309
|
exports.Optional = Optional;
|
|
3871
4310
|
exports.Options = Options;
|
|
3872
4311
|
exports.ParseError = ParseError;
|
|
4312
|
+
exports.Query = Query;
|
|
3873
4313
|
exports.Reference = Reference;
|
|
3874
4314
|
exports.Regex = Regex;
|
|
3875
4315
|
exports.Repeat = Repeat;
|
|
3876
4316
|
exports.RightAssociated = RightAssociated;
|
|
4317
|
+
exports.Selector = Selector;
|
|
3877
4318
|
exports.Sequence = Sequence;
|
|
3878
4319
|
exports.compact = compact;
|
|
3879
4320
|
exports.grammar = grammar;
|