snice 3.9.0 → 3.10.0

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/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v3.8.0
2
+ * snice v3.9.0
3
3
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -987,7 +987,22 @@ function prepareTemplate(result) {
987
987
  const htmlParts = [];
988
988
  const attrNamesForParts = [];
989
989
  for (let i = 0; i < strings.length; i++) {
990
- const str = strings[i];
990
+ let str = strings[i];
991
+ // Encode slashes in attribute names to prevent browser from splitting them
992
+ // HTML doesn't allow / in attribute names - browser treats it as whitespace
993
+ // Replace / with __SLASH__ in attribute context only (before = sign, after last >)
994
+ if (i < strings.length - 1) {
995
+ const lastEquals = str.lastIndexOf('=');
996
+ const lastCloseTag = str.lastIndexOf('>');
997
+ if (lastEquals > lastCloseTag) {
998
+ // We're in an attribute context - encode slashes in the attribute name
999
+ const beforeEquals = str.substring(0, lastEquals);
1000
+ const attrStartIdx = beforeEquals.lastIndexOf('>') + 1;
1001
+ const attrPart = beforeEquals.substring(attrStartIdx);
1002
+ const encodedAttrPart = attrPart.replace(/\//g, '__SLASH__');
1003
+ str = beforeEquals.substring(0, attrStartIdx) + encodedAttrPart + str.substring(lastEquals);
1004
+ }
1005
+ }
991
1006
  htmlParts.push(str);
992
1007
  if (i < strings.length - 1) {
993
1008
  // Check if we're in an attribute context
@@ -995,13 +1010,15 @@ function prepareTemplate(result) {
995
1010
  const lastEquals = str.lastIndexOf('=');
996
1011
  const lastCloseTag = str.lastIndexOf('>');
997
1012
  if (lastEquals > lastCloseTag) {
998
- // We're in an attribute value - extract and preserve the original attribute name
1013
+ // We're in an attribute value - extract and preserve the original attribute name (before encoding)
999
1014
  let attrStart = lastEquals - 1;
1000
1015
  while (attrStart >= 0 && /\S/.test(str[attrStart])) {
1001
1016
  attrStart--;
1002
1017
  }
1003
1018
  const attrName = str.substring(attrStart + 1, lastEquals).trim();
1004
- attrNamesForParts.push(attrName);
1019
+ // Decode the slash encoding to get original name
1020
+ const originalAttrName = attrName.replace(/__SLASH__/g, '/');
1021
+ attrNamesForParts.push(originalAttrName);
1005
1022
  htmlParts.push(marker);
1006
1023
  }
1007
1024
  else {