@cocreate/element-prototype 1.29.0 → 1.29.1
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/CHANGELOG.md +17 -0
- package/docs/index.html +221 -221
- package/package.json +5 -9
- package/src/getAttribute.js +28 -4
- package/src/getValue.js +535 -255
- package/src/index.js +1 -1
- package/src/{utility.js → operators.js} +62 -7
- package/src/queryElements.js +15 -2
- package/src/setValue.js +1 -1
- package/webpack.config.js +65 -90
package/src/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import { getAttribute } from "./getAttribute";
|
|
|
24
24
|
import { setValue } from "./setValue";
|
|
25
25
|
import { getValue } from "./getValue";
|
|
26
26
|
import { queryElements } from "./queryElements";
|
|
27
|
-
import { processOperators } from "./
|
|
27
|
+
import { processOperators } from "./operators";
|
|
28
28
|
|
|
29
29
|
export default {
|
|
30
30
|
getAttribute,
|
|
@@ -22,7 +22,8 @@ const customOperators = new Map(
|
|
|
22
22
|
$object_id: () => ObjectId().toString(),
|
|
23
23
|
"ObjectId()": () => ObjectId().toString(),
|
|
24
24
|
$relativePath: () => {
|
|
25
|
-
let
|
|
25
|
+
let currentPath = window.location.pathname.replace(/\/[^\/]*$/, ""); // Remove file or last segment from path
|
|
26
|
+
let depth = currentPath.split("/").filter(Boolean).length; // Count actual directory levels
|
|
26
27
|
return depth > 0 ? "../".repeat(depth) : "./";
|
|
27
28
|
},
|
|
28
29
|
$path: () => {
|
|
@@ -131,69 +132,123 @@ function processOperators(element, value, exclude = [], parent) {
|
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
/**
|
|
134
|
-
|
|
135
|
-
*
|
|
135
|
+
/**
|
|
136
|
+
* Synchronously determines and executes the action for processing a single operator token.
|
|
137
|
+
* @param {HTMLElement|null} element - The context element from which to derive values or execute methods.
|
|
138
|
+
* @param {string} operator - The operator to apply, indicating what actions or property/method to evaluate.
|
|
139
|
+
* @param {string|Array} args - Arguments that may be used by the operator, which could be further processed if they contain a nested operator.
|
|
140
|
+
* @param {string} parent - Context in which the function is called, potentially affecting behavior or processing.
|
|
141
|
+
* @returns {string} The final resolved value after applying the operator to the given elements.
|
|
136
142
|
*/
|
|
137
143
|
function resolveOperator(element, operator, args, parent) {
|
|
144
|
+
// If args contain any operators (indicated by '$'), process them recursively
|
|
138
145
|
if (args && args.includes("$")) {
|
|
146
|
+
// Reprocess args to resolve any nested operators
|
|
139
147
|
args = processOperators(element, args, "", operator);
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
// Initialize an array of elements to operate on, starting with the single element reference if provided
|
|
142
151
|
let targetElements = element ? [element] : [];
|
|
152
|
+
|
|
153
|
+
// If args are provided as a string, treat it as a selector to find applicable target elements
|
|
143
154
|
if (args && typeof args === "string") {
|
|
144
155
|
targetElements = queryElements({
|
|
145
|
-
element,
|
|
146
|
-
args
|
|
156
|
+
element, // Use the context element as the base for querying
|
|
157
|
+
selector: args // Selector from args to find matching elements
|
|
147
158
|
});
|
|
159
|
+
|
|
160
|
+
// If no elements are found matching the selector in args, return args unmodified
|
|
161
|
+
if (!targetElements.length) return args;
|
|
148
162
|
}
|
|
149
163
|
|
|
164
|
+
// Generate a processed value by applying the operator to each of the target elements
|
|
150
165
|
let value = processValues(targetElements, operator, args, parent);
|
|
166
|
+
|
|
167
|
+
// If the result is a string and still contains unresolved operators, process them further
|
|
151
168
|
if (value && typeof value === "string" && value.includes("$")) {
|
|
169
|
+
// Resolve any remaining operators within the value string
|
|
152
170
|
value = processOperators(element, value, parent);
|
|
153
171
|
}
|
|
154
172
|
|
|
173
|
+
// Return the final processed value, fully resolved
|
|
155
174
|
return value;
|
|
156
175
|
}
|
|
157
176
|
|
|
158
177
|
/**
|
|
159
|
-
* Synchronously aggregates values.
|
|
160
|
-
* @
|
|
178
|
+
* Synchronously processes and aggregates values from a set of elements based on a specified operator.
|
|
179
|
+
* @param {Array<HTMLElement>} elements - Array of elements to be processed.
|
|
180
|
+
* @param {string} operator - The operator to apply to each element, indicating which property or method to use.
|
|
181
|
+
* @param {string|Array} args - Arguments that may be passed to the method if the operator corresponds to a function.
|
|
182
|
+
* @param {string} parent - Context in which the function is called, possibly influencing behavior (e.g., special handling for "$param").
|
|
183
|
+
* @returns {string} The combined string value obtained by processing elements with the specified operator.
|
|
161
184
|
*/
|
|
162
185
|
function processValues(elements, operator, args, parent) {
|
|
186
|
+
// Attempt to fetch a custom operator function associated with the operator
|
|
163
187
|
let customOp = customOperators.get(operator);
|
|
188
|
+
|
|
189
|
+
// Initialize an empty string to accumulate results from processing each element
|
|
164
190
|
let aggregatedString = "";
|
|
191
|
+
|
|
192
|
+
// Iterate over each element in the provided elements array
|
|
165
193
|
for (const el of elements) {
|
|
194
|
+
// If the element is null or undefined, skip to the next iteration
|
|
166
195
|
if (!el) continue;
|
|
196
|
+
|
|
197
|
+
// Determine the raw value from the custom operator or by accessing a property/method directly on the element
|
|
167
198
|
let rawValue = customOp || el?.[operator.substring(1)];
|
|
199
|
+
|
|
200
|
+
// Check if the rawValue is a function and process it using provided arguments
|
|
168
201
|
if (typeof rawValue === "function") {
|
|
202
|
+
// If arguments are provided as an array
|
|
169
203
|
if (Array.isArray(args)) {
|
|
204
|
+
// If there are arguments, exit by returning an empty string (assumes args should not be used here)
|
|
170
205
|
if (args.length) {
|
|
171
206
|
return "";
|
|
172
207
|
}
|
|
208
|
+
// Invoke the function using the element and spread array arguments
|
|
173
209
|
rawValue = rawValue(el, ...args);
|
|
174
210
|
} else {
|
|
211
|
+
// Otherwise, invoke the function using the element and direct arguments
|
|
175
212
|
rawValue = rawValue(el, args);
|
|
176
213
|
}
|
|
177
214
|
}
|
|
178
215
|
|
|
216
|
+
// If the parent context requires parameter resolution
|
|
179
217
|
if (parent === "$param") {
|
|
218
|
+
// Return the first evaluated rawValue that is not null or undefined
|
|
180
219
|
if (rawValue) {
|
|
181
220
|
return rawValue;
|
|
182
221
|
}
|
|
183
222
|
} else {
|
|
223
|
+
// Otherwise, append the stringified rawValue to the aggregated result, defaulting to an empty string if it's nullish
|
|
184
224
|
aggregatedString += String(rawValue ?? "");
|
|
185
225
|
}
|
|
186
226
|
}
|
|
187
227
|
|
|
228
|
+
// Return the final aggregated string containing all processed values
|
|
188
229
|
return aggregatedString;
|
|
189
230
|
}
|
|
190
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Extracts the subdomain from the current window's hostname.
|
|
234
|
+
* @returns {string|null} - The subdomain part of the hostname if it exists, or null if there is none.
|
|
235
|
+
*/
|
|
191
236
|
function getSubdomain() {
|
|
237
|
+
// Retrieve the hostname from the current window's location
|
|
192
238
|
const hostname = window.location.hostname;
|
|
239
|
+
|
|
240
|
+
// Split the hostname into parts divided by dots ('.')
|
|
193
241
|
const parts = hostname.split(".");
|
|
242
|
+
|
|
243
|
+
// Check if the hostname has more than two parts and ensure the last part isn't a number (a common TLD check)
|
|
244
|
+
// A typical domain structure might look like "sub.domain.com",
|
|
245
|
+
// where "sub" is the subdomain, "domain" is the second-level domain, and "com" is the top-level domain.
|
|
194
246
|
if (parts.length > 2 && isNaN(parseInt(parts[parts.length - 1]))) {
|
|
247
|
+
// Join all parts except the last two (which are assumed to be the domain and TLD) to get the subdomain
|
|
195
248
|
return parts.slice(0, parts.length - 2).join(".");
|
|
196
249
|
}
|
|
250
|
+
|
|
251
|
+
// Return null if there's no valid subdomain structure
|
|
197
252
|
return null;
|
|
198
253
|
}
|
|
199
254
|
|
package/src/queryElements.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import utils from "@cocreate/utils";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Custom method to query elements in the context of a specific DOM element.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options - Options to customize the query.
|
|
7
|
+
* @returns {NodeListOf<Element>} - A list of elements found based on the query criteria.
|
|
8
|
+
*/
|
|
9
|
+
function queryElements(options = {}) {
|
|
10
|
+
// Use `this` as the element context and pass additional options to utils.queryElements
|
|
4
11
|
return utils.queryElements({ element: this, ...options });
|
|
5
|
-
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Attach the method to Element's prototype to allow its use as an instance method
|
|
15
|
+
Element.prototype.queryElements = queryElements;
|
|
16
|
+
|
|
17
|
+
// Export the function for direct use in other parts of your application
|
|
18
|
+
export { queryElements };
|
package/src/setValue.js
CHANGED
|
@@ -116,7 +116,7 @@ const setValue = (el, value, dispatch) => {
|
|
|
116
116
|
} else if (el.tagName === "SCRIPT") {
|
|
117
117
|
setScript(el, value);
|
|
118
118
|
} else if (el.hasAttribute("value")) {
|
|
119
|
-
|
|
119
|
+
el.setAttribute("value", value);
|
|
120
120
|
} else {
|
|
121
121
|
if (el.hasAttribute("contenteditable") && el == document.activeElement)
|
|
122
122
|
return;
|
package/webpack.config.js
CHANGED
|
@@ -1,90 +1,65 @@
|
|
|
1
|
-
const path = require("path")
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
module.exports = (env, argv) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
parallel: true,
|
|
67
|
-
// sourceMap: true, // Must be set to true if using source-maps in production
|
|
68
|
-
terserOptions: {
|
|
69
|
-
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
|
|
70
|
-
// extractComments: 'all',
|
|
71
|
-
compress: {
|
|
72
|
-
drop_console: true,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
}),
|
|
76
|
-
],
|
|
77
|
-
splitChunks: {
|
|
78
|
-
chunks: "all",
|
|
79
|
-
minSize: 200,
|
|
80
|
-
// maxSize: 99999,
|
|
81
|
-
//minChunks: 1,
|
|
82
|
-
|
|
83
|
-
cacheGroups: {
|
|
84
|
-
defaultVendors: false,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
}
|
|
89
|
-
return config
|
|
90
|
-
}
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
3
|
+
const { EsbuildPlugin } = require("esbuild-loader");
|
|
4
|
+
const { FileUploader } = require("@cocreate/webpack");
|
|
5
|
+
|
|
6
|
+
module.exports = async (env, argv) => {
|
|
7
|
+
const isProduction = argv && argv.mode === "production";
|
|
8
|
+
const config = {
|
|
9
|
+
entry: {
|
|
10
|
+
"CoCreate-element-prototype": "./src/index.js"
|
|
11
|
+
},
|
|
12
|
+
output: {
|
|
13
|
+
path: path.resolve(__dirname, "dist"),
|
|
14
|
+
filename: isProduction ? "[name].min.js" : "[name].js",
|
|
15
|
+
libraryExport: "default",
|
|
16
|
+
library: ["CoCreate", "elementPrototype"],
|
|
17
|
+
clean: true
|
|
18
|
+
},
|
|
19
|
+
plugins: [
|
|
20
|
+
new MiniCssExtractPlugin({
|
|
21
|
+
filename: isProduction ? "[name].min.css" : "[name].css"
|
|
22
|
+
}),
|
|
23
|
+
new FileUploader(env, argv)
|
|
24
|
+
],
|
|
25
|
+
mode: isProduction ? "production" : "development",
|
|
26
|
+
devtool: isProduction ? "source-map" : "eval-source-map",
|
|
27
|
+
module: {
|
|
28
|
+
rules: [
|
|
29
|
+
{
|
|
30
|
+
test: /.js$/,
|
|
31
|
+
exclude: /node_modules/,
|
|
32
|
+
use: {
|
|
33
|
+
loader: "esbuild-loader",
|
|
34
|
+
options: {
|
|
35
|
+
loader: "js",
|
|
36
|
+
target: "es2017"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
test: /.css$/i,
|
|
42
|
+
use: [MiniCssExtractPlugin.loader, "css-loader"]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
optimization: {
|
|
47
|
+
minimize: isProduction,
|
|
48
|
+
minimizer: [
|
|
49
|
+
new EsbuildPlugin({
|
|
50
|
+
target: "es2017",
|
|
51
|
+
css: true
|
|
52
|
+
})
|
|
53
|
+
],
|
|
54
|
+
splitChunks: {
|
|
55
|
+
cacheGroups: {
|
|
56
|
+
defaultVendors: false
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
performance: {
|
|
61
|
+
hints: isProduction ? "warning" : false
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return config;
|
|
65
|
+
};
|