web-manager 4.0.19 → 4.0.20

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.
@@ -35,82 +35,106 @@ class Bindings {
35
35
  bindElements.forEach(element => {
36
36
  const bindValue = element.getAttribute('data-wm-bind');
37
37
 
38
- // Parse action and expression
38
+ // Split by comma to support multiple actions
39
+ const bindings = this._parseBindings(bindValue);
40
+
41
+ // Execute each action
42
+ bindings.forEach(({ action, expression }) => {
43
+ this._executeAction(element, action, expression, context);
44
+ });
45
+
46
+ // Add bound class to indicate element has been processed
47
+ if (!element.classList.contains('wm-bound')) {
48
+ element.classList.add('wm-bound');
49
+ }
50
+ });
51
+ }
52
+
53
+ // Parse binding string into separate actions
54
+ _parseBindings(bindValue) {
55
+ const bindings = [];
56
+
57
+ // Split by comma, but be smart about it
58
+ // We need to handle cases where commas might be inside expressions
59
+ const parts = bindValue.split(',').map(p => p.trim());
60
+
61
+ parts.forEach(part => {
39
62
  let action = '@text'; // Default action
40
- let expression = bindValue;
63
+ let expression = part;
41
64
 
42
65
  // Check if it starts with an action keyword
43
- if (bindValue.startsWith('@')) {
44
- const spaceIndex = bindValue.indexOf(' ');
66
+ if (part.startsWith('@')) {
67
+ const spaceIndex = part.indexOf(' ');
45
68
  if (spaceIndex > -1) {
46
- action = bindValue.slice(0, spaceIndex);
47
- expression = bindValue.slice(spaceIndex + 1);
69
+ action = part.slice(0, spaceIndex);
70
+ expression = part.slice(spaceIndex + 1).trim();
48
71
  } else {
49
72
  // No space means it's just an action with no expression (like @hide)
50
- action = bindValue;
73
+ action = part;
51
74
  expression = '';
52
75
  }
53
76
  }
54
77
 
55
- // Execute the action
56
- switch (action) {
57
- case '@show':
58
- // Show element if condition is true (or always if no condition)
59
- const shouldShow = expression ? this._evaluateCondition(expression, context) : true;
60
- if (shouldShow) {
61
- element.removeAttribute('hidden');
62
- } else {
63
- element.setAttribute('hidden', '');
64
- }
65
- break;
66
-
67
- case '@hide':
68
- // Hide element if condition is true (or always if no condition)
69
- const shouldHide = expression ? this._evaluateCondition(expression, context) : true;
70
- if (shouldHide) {
71
- element.setAttribute('hidden', '');
72
- } else {
73
- element.removeAttribute('hidden');
74
- }
75
- break;
76
-
77
- case '@attr':
78
- // Set attribute value
79
- // Format: @attr attributeName expression
80
- const attrParts = expression.split(' ');
81
- const attrName = attrParts[0];
82
- const attrExpression = attrParts.slice(1).join(' ');
83
- const attrValue = this._resolvePath(context, attrExpression) || '';
84
-
85
- if (attrValue) {
86
- element.setAttribute(attrName, attrValue);
87
- } else {
88
- element.removeAttribute(attrName);
89
- }
90
- break;
91
-
92
- case '@text':
93
- default:
94
- // Set text content (default behavior)
95
- const value = this._resolvePath(context, expression) || '';
96
-
97
- if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
98
- element.value = value;
99
- } else {
100
- element.textContent = value;
101
- }
102
- break;
103
-
104
- // Future actions can be added here:
105
- // case '@class':
106
- // case '@style':
107
- }
108
-
109
- // Add bound class to indicate element has been processed
110
- if (!element.classList.contains('wm-bound')) {
111
- element.classList.add('wm-bound');
112
- }
78
+ bindings.push({ action, expression });
113
79
  });
80
+
81
+ return bindings;
82
+ }
83
+
84
+ // Execute a single action on an element
85
+ _executeAction(element, action, expression, context) {
86
+ switch (action) {
87
+ case '@show':
88
+ // Show element if condition is true (or always if no condition)
89
+ const shouldShow = expression ? this._evaluateCondition(expression, context) : true;
90
+ if (shouldShow) {
91
+ element.removeAttribute('hidden');
92
+ } else {
93
+ element.setAttribute('hidden', '');
94
+ }
95
+ break;
96
+
97
+ case '@hide':
98
+ // Hide element if condition is true (or always if no condition)
99
+ const shouldHide = expression ? this._evaluateCondition(expression, context) : true;
100
+ if (shouldHide) {
101
+ element.setAttribute('hidden', '');
102
+ } else {
103
+ element.removeAttribute('hidden');
104
+ }
105
+ break;
106
+
107
+ case '@attr':
108
+ // Set attribute value
109
+ // Format: @attr attributeName expression
110
+ const attrParts = expression.split(' ');
111
+ const attrName = attrParts[0];
112
+ const attrExpression = attrParts.slice(1).join(' ');
113
+ const attrValue = this._resolvePath(context, attrExpression) || '';
114
+
115
+ if (attrValue) {
116
+ element.setAttribute(attrName, attrValue);
117
+ } else {
118
+ element.removeAttribute(attrName);
119
+ }
120
+ break;
121
+
122
+ case '@text':
123
+ default:
124
+ // Set text content (default behavior)
125
+ const value = this._resolvePath(context, expression) || '';
126
+
127
+ if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
128
+ element.value = value;
129
+ } else {
130
+ element.textContent = value;
131
+ }
132
+ break;
133
+
134
+ // Future actions can be added here:
135
+ // case '@class':
136
+ // case '@style':
137
+ }
114
138
  }
115
139
 
116
140
  // Resolve nested object path
@@ -6,3 +6,11 @@
6
6
  [debug] [2025-10-20T10:38:46.422Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
7
7
  [debug] [2025-10-20T10:38:46.422Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
8
8
  [debug] [2025-10-20T10:38:46.422Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
9
+ [debug] [2025-10-20T11:33:46.238Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
10
+ [debug] [2025-10-20T11:33:46.237Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
11
+ [debug] [2025-10-20T11:33:46.239Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
12
+ [debug] [2025-10-20T11:33:46.240Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
13
+ [debug] [2025-10-20T11:33:46.240Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
14
+ [debug] [2025-10-20T11:33:46.239Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
15
+ [debug] [2025-10-20T11:33:46.240Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
16
+ [debug] [2025-10-20T11:33:46.240Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-manager",
3
- "version": "4.0.19",
3
+ "version": "4.0.20",
4
4
  "description": "Easily access important variables such as the query string, current domain, and current page in a single object.",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",