@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/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 "./utility";
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 depth = window.location.pathname.split("/").length - 1;
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
- * Synchronously determines and executes the action for a single operator token.
135
- * @returns {string} The final string value for the token.
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
- * @returns {string} The aggregated string value.
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
 
@@ -1,5 +1,18 @@
1
1
  import utils from "@cocreate/utils";
2
2
 
3
- Element.prototype.queryElements = function (options = {}) {
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
- value = el.setAttribute("value", value);
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 TerserPlugin = require("terser-webpack-plugin")
3
- const MiniCssExtractPlugin = require("mini-css-extract-plugin")
4
- const { CleanWebpackPlugin } = require("clean-webpack-plugin")
5
-
6
- module.exports = (env, argv) => {
7
- let isProduction = false
8
- if (argv.mode === 'production')
9
- isProduction = true
10
-
11
- const config = {
12
- entry: {
13
- "CoCreate-element-prototype": "./src/index.js",
14
- },
15
- output: {
16
- path: path.resolve(__dirname, "dist"),
17
- filename: isProduction ? "[name].min.js" : "[name].js",
18
- libraryTarget: "umd",
19
- libraryExport: "default",
20
- library: ["CoCreate", "element-prototype"],
21
- globalObject: "this",
22
- },
23
-
24
- plugins: [
25
- new CleanWebpackPlugin(),
26
- new MiniCssExtractPlugin({
27
- filename: "[name].css",
28
- }),
29
- ],
30
- // Default mode for Webpack is production.
31
- // Depending on mode Webpack will apply different things
32
- // on final bundle. For now we don't need production's JavaScript
33
- // minifying and other thing so let's set mode to development
34
- mode: isProduction ? "production" : "development",
35
- module: {
36
- rules: [
37
- {
38
- test: /.js$/,
39
- exclude: /(node_modules)/,
40
- use: {
41
- loader: "babel-loader",
42
- options: {
43
- plugins: ["@babel/plugin-transform-modules-commonjs"],
44
- },
45
- },
46
- },
47
- {
48
- test: /.css$/i,
49
- use: [
50
- { loader: "style-loader", options: { injectType: "linkTag" } },
51
- "file-loader",
52
- ],
53
- },
54
- ],
55
- },
56
-
57
- // add source map
58
- ...(isProduction ? {} : { devtool: "eval-source-map" }),
59
-
60
- optimization: {
61
- minimize: true,
62
- minimizer: [
63
- new TerserPlugin({
64
- extractComments: true,
65
- // cache: true,
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
+ };