@webqit/oohtml 1.10.2 → 1.10.4

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/src/util.js CHANGED
@@ -1,180 +1,180 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import domInit from '@webqit/browser-pie/src/dom/index.js';
6
- import { _wrapped, _unwrap, _before, _after } from '@webqit/util/str/index.js';
7
- import { _from as _arrFrom } from '@webqit/util/arr/index.js';
8
- import { _internals }from '@webqit/util/js/index.js';
9
- import { _merge } from '@webqit/util/obj/index.js';
10
- import Lexer from '@webqit/util/str/Lexer.js';
11
-
12
- /**
13
- * A OOHTML's meta tag props reader.
14
- *
15
- * @param Object defaults
16
- *
17
- * @return Object
18
- */
19
- export function config(defaults, overrides = {}) {
20
- const WebQit = domInit.call(this);
21
- if (!WebQit.OOHTML) {
22
- // For feature modules that will call outside of ./index.js module
23
- WebQit.OOHTML = {};
24
- }
25
- if (!WebQit.OOHTML.meta) {
26
- WebQit.OOHTML.meta = WebQit.DOM.meta('oohtml', true/* readWrite */);
27
- }
28
- WebQit.OOHTML.meta.defaults(_merge(3, defaults, overrides));
29
- return WebQit.OOHTML.meta;
30
- }
31
-
32
- /**
33
- * Runs a "scope-query" against a context.
34
- *
35
- * @param Array contexts
36
- * @param String query
37
- * @param Function collectionCallback
38
- * @param Function advancementCallback
39
- *
40
- * @return Array
41
- */
42
- export function scopeQuery(contexts, query, collectionCallback, advancementCallback = null) {
43
- var queryPath = query.split('#')[0].split('/').map(n => n.trim()).filter(n => n);
44
- return execScopeQuery(contexts, queryPath, collectionCallback, advancementCallback);
45
- }
46
-
47
- /**
48
- * Parses a "scope-query" reference expression to seperate the "reference" and its "modifiers".
49
- *
50
- * @param String expr
51
- *
52
- * @return Array
53
- */
54
- export function parseScopeReferenceExpr(reference) {
55
- var split = Lexer.split(reference.trim(), [':']);
56
- reference = split.shift();
57
- var modifiers = split.reduce((_modifiers, _modifier) => {
58
- var [ name, parentheses ] = Lexer.split(_modifier.trim(), []);
59
- _modifiers[name] = _unwrap(parentheses, '(', ')');
60
- return _modifiers;
61
- }, {});
62
- return [ reference, modifiers ];
63
- }
64
-
65
- /**
66
- * Determines if a given path matches a "scope-query".
67
- *
68
- * @param String query
69
- * @param String path
70
- *
71
- * @return Bool
72
- */
73
- export function queryMatchPath(query, path) {
74
- path = path.split('#')[0].split('/').map(n => n.trim()).filter(n => n);
75
- query = query.split('#')[0].split('/').map(n => n.trim()).filter(n => n);
76
- return !query.length ? false : query.reduce((prev, segment, i) => {
77
- if (!prev) return false;
78
- return Lexer.split(segment.trim(), ['|', '+']).reduce((_prev, _reference) => {
79
- var [ _reference, modifiers ] = parseScopeReferenceExpr(_reference);
80
- _reference = _reference.trim();
81
- var sementIsMatch = _reference === path[i];
82
- if (!sementIsMatch && (('deep' in modifiers) || ('deepest' in modifiers))) {
83
- var _sementIsMatch = path.slice(i + 1).reduce((prev, s, i) => {
84
- return prev > -1 && ('deep' in modifiers) ? prev : (s === _reference ? i : prev);
85
- }, -1);
86
- if (_sementIsMatch > -1) {
87
- var e = path.splice(i, _sementIsMatch + 1);
88
- sementIsMatch = true;
89
- }
90
- }
91
- return _prev || sementIsMatch;
92
- }, false);
93
- }, true);
94
- }
95
-
96
- const evalAssertExpr = (segment, callback) => {
97
- return Lexer.split(segment.trim(), ['|', '+'], { preserveDelims: true }).reduce((_result, _reference) => {
98
- var operator;
99
- if (_reference.startsWith('|') || _reference.startsWith('+')) {
100
- operator = _reference.substr(0, 1);
101
- _reference = _reference.substr(1).trim();
102
- }
103
- if (_result.theEnd || (operator === '|' && _result.length)) {
104
- _result.theEnd = true;
105
- return _result;
106
- }
107
- return _result.concat(callback(_reference.trim()));
108
- }, []).filter(t => t);
109
- };
110
-
111
- const evalModuleExpr = (contexts, segment, collectionCallback) => {
112
- const lookAhead = contexts => contexts.reduce((_list, _module) => _list.concat(...collectionCallback(_module).values()), []);
113
- return evalAssertExpr(segment, _reference => {
114
- var [ _reference, modifiers ] = parseScopeReferenceExpr(_reference);
115
- // ------------
116
- return contexts.reduce((list, context) => {
117
- var collection = collectionCallback(context);
118
- if (_reference === '*') {
119
- _reference = '(' + collection.keys().join('+') + ')';
120
- }
121
- var itemArray = _wrapped(_reference, '(', ')') ? evalModuleExpr([context], _unwrap(_reference, '(', ')'), collectionCallback) : _arrFrom(collection.get(_reference), false);
122
- // ------------
123
- var appliedModifiers = [], reapplyAppliedModifiers = expr => `${expr}${appliedModifiers.map(m => `:${m}(${modifiers[m]})`).join('')}`;
124
- Object.keys(modifiers).forEach(modifier => {
125
- if (modifier === 'deep' || modifier === 'deepest') {
126
- var nextLevel = [context];
127
- while ((modifier === 'deepest' || !itemArray.length) && (nextLevel = lookAhead(nextLevel)).length) {
128
- var _itemArray = evalModuleExpr(nextLevel, reapplyAppliedModifiers(_reference), collectionCallback);
129
- if (_itemArray.length) {
130
- itemArray = _itemArray;
131
- }
132
- }
133
- } else {
134
- if (modifier === 'having' || modifier === 'not-having') {
135
- itemArray = itemArray.filter(module => {
136
- var filterHavingsResult = evalAssertExpr(modifiers[modifier], _filterHavings => collectionCallback(module, _filterHavings));
137
- return modifier === 'not-having' ? !filterHavingsResult.length : filterHavingsResult.length;
138
- });
139
- }
140
- appliedModifiers.push(modifier);
141
- }
142
- });
143
- return list.concat(itemArray);
144
- }, []);
145
- });
146
- };
147
-
148
- const execScopeQuery = function(contexts, path, collectionCallback, advancementCallback = null, level = 0) {
149
-
150
- if (!path.length) {
151
- return [];
152
- }
153
-
154
- let segment = path.shift(), isStopSegmentIfCount;
155
- if (segment.endsWith('.')) {
156
- isStopSegmentIfCount = true;
157
- segment = segment.substr(0, segment.length - 1).trim();
158
- }
159
- // -----------
160
- let modules = evalModuleExpr(contexts, segment, collectionCallback);
161
- modules.forEach(context => {
162
- if (_internals(context, 'oohtml').has('queryCallback')) {
163
- _internals(context, 'oohtml').get('queryCallback')();
164
- }
165
- });
166
- // -----------
167
- if (modules.length && isStopSegmentIfCount) {
168
- return modules;
169
- }
170
- // -----------
171
- if (path.length) {
172
- let submodules = execScopeQuery(modules, path.slice(), collectionCallback, advancementCallback, level + 1);
173
- if (submodules === -1) {
174
- return advancementCallback(modules, level, true);
175
- }
176
- return submodules;
177
- }
178
-
179
- return advancementCallback ? advancementCallback(modules, level) : modules;
180
- };
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import domInit from '@webqit/browser-pie/src/dom/index.js';
6
+ import { _wrapped, _unwrap, _before, _after } from '@webqit/util/str/index.js';
7
+ import { _from as _arrFrom } from '@webqit/util/arr/index.js';
8
+ import { _internals }from '@webqit/util/js/index.js';
9
+ import { _merge } from '@webqit/util/obj/index.js';
10
+ import Lexer from '@webqit/util/str/Lexer.js';
11
+
12
+ /**
13
+ * A OOHTML's meta tag props reader.
14
+ *
15
+ * @param Object defaults
16
+ *
17
+ * @return Object
18
+ */
19
+ export function config(defaults, overrides = {}) {
20
+ const WebQit = domInit.call(this);
21
+ if (!WebQit.OOHTML) {
22
+ // For feature modules that will call outside of ./index.js module
23
+ WebQit.OOHTML = {};
24
+ }
25
+ if (!WebQit.OOHTML.meta) {
26
+ WebQit.OOHTML.meta = WebQit.DOM.meta('oohtml', true/* readWrite */);
27
+ }
28
+ WebQit.OOHTML.meta.defaults(_merge(3, defaults, overrides));
29
+ return WebQit.OOHTML.meta;
30
+ }
31
+
32
+ /**
33
+ * Runs a "scope-query" against a context.
34
+ *
35
+ * @param Array contexts
36
+ * @param String query
37
+ * @param Function collectionCallback
38
+ * @param Function advancementCallback
39
+ *
40
+ * @return Array
41
+ */
42
+ export function scopeQuery(contexts, query, collectionCallback, advancementCallback = null) {
43
+ var queryPath = query.split('#')[0].split('/').map(n => n.trim()).filter(n => n);
44
+ return execScopeQuery(contexts, queryPath, collectionCallback, advancementCallback);
45
+ }
46
+
47
+ /**
48
+ * Parses a "scope-query" reference expression to seperate the "reference" and its "modifiers".
49
+ *
50
+ * @param String expr
51
+ *
52
+ * @return Array
53
+ */
54
+ export function parseScopeReferenceExpr(reference) {
55
+ var split = Lexer.split(reference.trim(), [':']);
56
+ reference = split.shift();
57
+ var modifiers = split.reduce((_modifiers, _modifier) => {
58
+ var [ name, parentheses ] = Lexer.split(_modifier.trim(), []);
59
+ _modifiers[name] = _unwrap(parentheses, '(', ')');
60
+ return _modifiers;
61
+ }, {});
62
+ return [ reference, modifiers ];
63
+ }
64
+
65
+ /**
66
+ * Determines if a given path matches a "scope-query".
67
+ *
68
+ * @param String query
69
+ * @param String path
70
+ *
71
+ * @return Bool
72
+ */
73
+ export function queryMatchPath(query, path) {
74
+ path = path.split('#')[0].split('/').map(n => n.trim()).filter(n => n);
75
+ query = query.split('#')[0].split('/').map(n => n.trim()).filter(n => n);
76
+ return !query.length ? false : query.reduce((prev, segment, i) => {
77
+ if (!prev) return false;
78
+ return Lexer.split(segment.trim(), ['|', '+']).reduce((_prev, _reference) => {
79
+ var [ _reference, modifiers ] = parseScopeReferenceExpr(_reference);
80
+ _reference = _reference.trim();
81
+ var sementIsMatch = _reference === path[i];
82
+ if (!sementIsMatch && (('deep' in modifiers) || ('deepest' in modifiers))) {
83
+ var _sementIsMatch = path.slice(i + 1).reduce((prev, s, i) => {
84
+ return prev > -1 && ('deep' in modifiers) ? prev : (s === _reference ? i : prev);
85
+ }, -1);
86
+ if (_sementIsMatch > -1) {
87
+ var e = path.splice(i, _sementIsMatch + 1);
88
+ sementIsMatch = true;
89
+ }
90
+ }
91
+ return _prev || sementIsMatch;
92
+ }, false);
93
+ }, true);
94
+ }
95
+
96
+ const evalAssertExpr = (segment, callback) => {
97
+ return Lexer.split(segment.trim(), ['|', '+'], { preserveDelims: true }).reduce((_result, _reference) => {
98
+ var operator;
99
+ if (_reference.startsWith('|') || _reference.startsWith('+')) {
100
+ operator = _reference.substr(0, 1);
101
+ _reference = _reference.substr(1).trim();
102
+ }
103
+ if (_result.theEnd || (operator === '|' && _result.length)) {
104
+ _result.theEnd = true;
105
+ return _result;
106
+ }
107
+ return _result.concat(callback(_reference.trim()));
108
+ }, []).filter(t => t);
109
+ };
110
+
111
+ const evalModuleExpr = (contexts, segment, collectionCallback) => {
112
+ const lookAhead = contexts => contexts.reduce((_list, _module) => _list.concat(...collectionCallback(_module).values()), []);
113
+ return evalAssertExpr(segment, _reference => {
114
+ var [ _reference, modifiers ] = parseScopeReferenceExpr(_reference);
115
+ // ------------
116
+ return contexts.reduce((list, context) => {
117
+ var collection = collectionCallback(context);
118
+ if (_reference === '*') {
119
+ _reference = '(' + collection.keys().join('+') + ')';
120
+ }
121
+ var itemArray = _wrapped(_reference, '(', ')') ? evalModuleExpr([context], _unwrap(_reference, '(', ')'), collectionCallback) : _arrFrom(collection.get(_reference), false);
122
+ // ------------
123
+ var appliedModifiers = [], reapplyAppliedModifiers = expr => `${expr}${appliedModifiers.map(m => `:${m}(${modifiers[m]})`).join('')}`;
124
+ Object.keys(modifiers).forEach(modifier => {
125
+ if (modifier === 'deep' || modifier === 'deepest') {
126
+ var nextLevel = [context];
127
+ while ((modifier === 'deepest' || !itemArray.length) && (nextLevel = lookAhead(nextLevel)).length) {
128
+ var _itemArray = evalModuleExpr(nextLevel, reapplyAppliedModifiers(_reference), collectionCallback);
129
+ if (_itemArray.length) {
130
+ itemArray = _itemArray;
131
+ }
132
+ }
133
+ } else {
134
+ if (modifier === 'having' || modifier === 'not-having') {
135
+ itemArray = itemArray.filter(module => {
136
+ var filterHavingsResult = evalAssertExpr(modifiers[modifier], _filterHavings => collectionCallback(module, _filterHavings));
137
+ return modifier === 'not-having' ? !filterHavingsResult.length : filterHavingsResult.length;
138
+ });
139
+ }
140
+ appliedModifiers.push(modifier);
141
+ }
142
+ });
143
+ return list.concat(itemArray);
144
+ }, []);
145
+ });
146
+ };
147
+
148
+ const execScopeQuery = function(contexts, path, collectionCallback, advancementCallback = null, level = 0) {
149
+
150
+ if (!path.length) {
151
+ return [];
152
+ }
153
+
154
+ let segment = path.shift(), isStopSegmentIfCount;
155
+ if (segment.endsWith('.')) {
156
+ isStopSegmentIfCount = true;
157
+ segment = segment.substr(0, segment.length - 1).trim();
158
+ }
159
+ // -----------
160
+ let modules = evalModuleExpr(contexts, segment, collectionCallback);
161
+ modules.forEach(context => {
162
+ if (_internals(context, 'oohtml').has('queryCallback')) {
163
+ _internals(context, 'oohtml').get('queryCallback')();
164
+ }
165
+ });
166
+ // -----------
167
+ if (modules.length && isStopSegmentIfCount) {
168
+ return modules;
169
+ }
170
+ // -----------
171
+ if (path.length) {
172
+ let submodules = execScopeQuery(modules, path.slice(), collectionCallback, advancementCallback, level + 1);
173
+ if (submodules === -1) {
174
+ return advancementCallback(modules, level, true);
175
+ }
176
+ return submodules;
177
+ }
178
+
179
+ return advancementCallback ? advancementCallback(modules, level) : modules;
180
+ };