wrec 0.25.0 → 0.25.2
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/wrec-ssr.d.ts +1 -0
- package/dist/wrec.d.ts +1 -0
- package/dist/wrec.es.js +7 -3
- package/package.json +1 -1
- package/scripts/lint.js +79 -5
package/dist/wrec-ssr.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export declare abstract class Wrec extends HTMLElementBase implements ChangeList
|
|
|
62
62
|
static getPropName(attrName: string): string;
|
|
63
63
|
static get observedAttributes(): string[];
|
|
64
64
|
propertyChangedCallback(_propName: string, _oldValue: unknown, _newValue: unknown): void;
|
|
65
|
+
ready(): void;
|
|
65
66
|
setAttributeSafe(name: string, value: string): void;
|
|
66
67
|
setFormValue(propName: string, value: string): void;
|
|
67
68
|
static ssr(properties?: StringToAny): string;
|
package/dist/wrec.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export declare abstract class Wrec extends HTMLElementBase implements ChangeList
|
|
|
62
62
|
static getPropName(attrName: string): string;
|
|
63
63
|
static get observedAttributes(): string[];
|
|
64
64
|
propertyChangedCallback(_propName: string, _oldValue: unknown, _newValue: unknown): void;
|
|
65
|
+
ready(): void;
|
|
65
66
|
setAttributeSafe(name: string, value: string): void;
|
|
66
67
|
setFormValue(propName: string, value: string): void;
|
|
67
68
|
static ssr(properties?: StringToAny): string;
|
package/dist/wrec.es.js
CHANGED
|
@@ -413,7 +413,7 @@ const w = class w extends Ct {
|
|
|
413
413
|
this[e] = s;
|
|
414
414
|
}
|
|
415
415
|
async connectedCallback() {
|
|
416
|
-
a(this, i, Yt).call(this), a(this, i, _t).call(this), await a(this, i, Bt).call(this), this.hasAttribute("disabled") && a(this, i, ht).call(this), a(this, i, wt).call(this, this.shadowRoot), a(this, i, pt).call(this, this.shadowRoot), a(this, i, Zt).call(this), a(this, i, Dt).call(this);
|
|
416
|
+
a(this, i, Yt).call(this), a(this, i, _t).call(this), await a(this, i, Bt).call(this), this.hasAttribute("disabled") && a(this, i, ht).call(this), a(this, i, wt).call(this, this.shadowRoot), a(this, i, pt).call(this, this.shadowRoot), a(this, i, Zt).call(this), a(this, i, Dt).call(this), this.ready();
|
|
417
417
|
}
|
|
418
418
|
disconnectedCallback() {
|
|
419
419
|
for (const { state: t } of h(this, P).values())
|
|
@@ -486,6 +486,10 @@ const w = class w extends Ct {
|
|
|
486
486
|
// Subclasses can override this to add functionality.
|
|
487
487
|
propertyChangedCallback(t, e, s) {
|
|
488
488
|
}
|
|
489
|
+
// Subclasses can override this to be notified when
|
|
490
|
+
// the component DOM has been built and made reactive.
|
|
491
|
+
ready() {
|
|
492
|
+
}
|
|
489
493
|
// This follows the best practice
|
|
490
494
|
// "Do not override author-set, global attributes."
|
|
491
495
|
setAttributeSafe(t, e) {
|
|
@@ -739,7 +743,7 @@ J = function(t, e, s = void 0) {
|
|
|
739
743
|
s ? rt(e, s, l) : a(this, i, gt).call(this, e, l);
|
|
740
744
|
}, Jt = function(t, e) {
|
|
741
745
|
const s = e?.trim() ?? "", o = h(this, m).properties[s];
|
|
742
|
-
o || a(this, i, O).call(this, t, "ref", s), o.type !== Ct && a(this, i, g).call(this, t, "ref", `refers to property "${s}" whose type is not HTMLElement`), this[s] = t;
|
|
746
|
+
o || a(this, i, O).call(this, t, "ref", s), o.type !== Ct && a(this, i, g).call(this, t, "ref", `refers to property "${s}" whose type is not HTMLElement`), this[s] && a(this, i, g).call(this, t, "ref", `is a duplicate reference to the property "${s}"`), this[s] = t;
|
|
743
747
|
}, g = function(t, e, s) {
|
|
744
748
|
const o = t instanceof HTMLElement ? t.localName : "CSS rule";
|
|
745
749
|
throw new v(
|
|
@@ -841,7 +845,7 @@ Zt = function() {
|
|
|
841
845
|
}, Yt = function() {
|
|
842
846
|
const t = new Set(Object.keys(h(this, m).properties));
|
|
843
847
|
for (const e of this.getAttributeNames())
|
|
844
|
-
if (!oe.has(e) && !e.startsWith("on")) {
|
|
848
|
+
if (!oe.has(e) && !e.startsWith("on") && e !== "ref") {
|
|
845
849
|
if (e === "form-assoc") {
|
|
846
850
|
a(this, i, ut).call(this);
|
|
847
851
|
continue;
|
package/package.json
CHANGED
package/scripts/lint.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
// - invalid `useState` map entries
|
|
22
22
|
// - unsupported HTML attributes in templates
|
|
23
23
|
// - invalid HTML element nesting in templates
|
|
24
|
+
// - duplicate ref attribute values
|
|
24
25
|
|
|
25
26
|
import fs from 'node:fs';
|
|
26
27
|
import path from 'node:path';
|
|
@@ -617,7 +618,8 @@ function extractProperties(sourceFile, checker, classNode) {
|
|
|
617
618
|
function extractTemplateExpressions(
|
|
618
619
|
classNode,
|
|
619
620
|
findings,
|
|
620
|
-
componentPropertyMaps
|
|
621
|
+
componentPropertyMaps,
|
|
622
|
+
supportedProps
|
|
621
623
|
) {
|
|
622
624
|
const expressions = [];
|
|
623
625
|
|
|
@@ -676,7 +678,14 @@ function extractTemplateExpressions(
|
|
|
676
678
|
}
|
|
677
679
|
|
|
678
680
|
const root = parse(rendered, {comment: true});
|
|
679
|
-
walkHtmlNode(
|
|
681
|
+
walkHtmlNode(
|
|
682
|
+
root,
|
|
683
|
+
expressions,
|
|
684
|
+
findings,
|
|
685
|
+
componentPropertyMaps,
|
|
686
|
+
supportedProps,
|
|
687
|
+
new Set()
|
|
688
|
+
);
|
|
680
689
|
}
|
|
681
690
|
|
|
682
691
|
return expressions;
|
|
@@ -731,6 +740,7 @@ function formatReport(
|
|
|
731
740
|
findings.reservedProperties.length > 0 ||
|
|
732
741
|
findings.invalidUsedByReferences.length > 0 ||
|
|
733
742
|
findings.invalidComputedProperties.length > 0 ||
|
|
743
|
+
findings.invalidRefAttributes.length > 0 ||
|
|
734
744
|
findings.invalidValuesConfigurations.length > 0 ||
|
|
735
745
|
findings.invalidDefaultValues.length > 0 ||
|
|
736
746
|
findings.invalidFormAssocValues.length > 0 ||
|
|
@@ -798,6 +808,13 @@ function formatReport(
|
|
|
798
808
|
);
|
|
799
809
|
}
|
|
800
810
|
|
|
811
|
+
if (findings.invalidRefAttributes.length > 0) {
|
|
812
|
+
lines.push('invalid ref attributes:');
|
|
813
|
+
findings.invalidRefAttributes.forEach(message =>
|
|
814
|
+
lines.push(` ${message}`)
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
|
|
801
818
|
if (findings.invalidValuesConfigurations.length > 0) {
|
|
802
819
|
lines.push('invalid values configurations:');
|
|
803
820
|
findings.invalidValuesConfigurations.forEach(message =>
|
|
@@ -1228,6 +1245,7 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1228
1245
|
invalidEventHandlers: [],
|
|
1229
1246
|
invalidFormAssocValues: [],
|
|
1230
1247
|
invalidHtmlNesting: [],
|
|
1248
|
+
invalidRefAttributes: [],
|
|
1231
1249
|
invalidUseStateMaps: [],
|
|
1232
1250
|
invalidUsedByReferences: [],
|
|
1233
1251
|
invalidValuesConfigurations: [],
|
|
@@ -1244,7 +1262,8 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1244
1262
|
const templateExprs = extractTemplateExpressions(
|
|
1245
1263
|
classNode,
|
|
1246
1264
|
findings,
|
|
1247
|
-
componentPropertyMaps
|
|
1265
|
+
componentPropertyMaps,
|
|
1266
|
+
supportedProps
|
|
1248
1267
|
);
|
|
1249
1268
|
const allExpressions = [...templateExprs, ...computedExprs];
|
|
1250
1269
|
|
|
@@ -1327,6 +1346,7 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1327
1346
|
findings.invalidEventHandlers.sort();
|
|
1328
1347
|
findings.invalidFormAssocValues.sort();
|
|
1329
1348
|
findings.invalidHtmlNesting.sort();
|
|
1349
|
+
findings.invalidRefAttributes.sort();
|
|
1330
1350
|
findings.invalidUseStateMaps.sort();
|
|
1331
1351
|
findings.invalidUsedByReferences.sort();
|
|
1332
1352
|
findings.invalidValuesConfigurations.sort();
|
|
@@ -1670,6 +1690,7 @@ function validateHtmlAttribute(node, attrName, findings) {
|
|
|
1670
1690
|
if (attrName.startsWith('aria-') || attrName.startsWith('data-')) return;
|
|
1671
1691
|
if (attrName.startsWith('on')) return;
|
|
1672
1692
|
if (attrName === 'form-assoc') return;
|
|
1693
|
+
if (attrName === 'ref') return;
|
|
1673
1694
|
|
|
1674
1695
|
const [baseAttrName] = attrName.split(':');
|
|
1675
1696
|
if (HTML_GLOBAL_ATTRIBUTES.has(baseAttrName)) return;
|
|
@@ -1697,6 +1718,42 @@ function validateValueBindingEvent(node, attrName, findings) {
|
|
|
1697
1718
|
);
|
|
1698
1719
|
}
|
|
1699
1720
|
|
|
1721
|
+
function validateRefAttribute(
|
|
1722
|
+
attrValue,
|
|
1723
|
+
supportedProps,
|
|
1724
|
+
findings,
|
|
1725
|
+
seenRefProps
|
|
1726
|
+
) {
|
|
1727
|
+
if (!attrValue) return;
|
|
1728
|
+
|
|
1729
|
+
const propName = attrValue.trim();
|
|
1730
|
+
if (!propName) return;
|
|
1731
|
+
|
|
1732
|
+
const propInfo = supportedProps.get(propName);
|
|
1733
|
+
if (!propInfo) {
|
|
1734
|
+
findings.invalidRefAttributes.push(
|
|
1735
|
+
`ref="${attrValue}" refers to missing property "${propName}"`
|
|
1736
|
+
);
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
if (propInfo.typeText !== 'HTMLElement') {
|
|
1741
|
+
findings.invalidRefAttributes.push(
|
|
1742
|
+
`ref="${attrValue}" refers to property "${propName}" whose type is not HTMLElement`
|
|
1743
|
+
);
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
if (seenRefProps.has(propName)) {
|
|
1748
|
+
findings.invalidRefAttributes.push(
|
|
1749
|
+
`ref="${attrValue}" is a duplicate reference to the property "${propName}"`
|
|
1750
|
+
);
|
|
1751
|
+
return;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
seenRefProps.add(propName);
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1700
1757
|
function getHtmlTagName(node) {
|
|
1701
1758
|
const tagName = node.rawTagName || node.tagName;
|
|
1702
1759
|
return typeof tagName === 'string' ? tagName.toLowerCase() : '';
|
|
@@ -1737,7 +1794,14 @@ function validateHtmlNesting(node, findings) {
|
|
|
1737
1794
|
}
|
|
1738
1795
|
}
|
|
1739
1796
|
|
|
1740
|
-
function walkHtmlNode(
|
|
1797
|
+
function walkHtmlNode(
|
|
1798
|
+
node,
|
|
1799
|
+
expressions,
|
|
1800
|
+
findings,
|
|
1801
|
+
componentPropertyMaps,
|
|
1802
|
+
supportedProps,
|
|
1803
|
+
seenRefProps
|
|
1804
|
+
) {
|
|
1741
1805
|
if (node.nodeType === 1) {
|
|
1742
1806
|
validateHtmlNesting(node, findings);
|
|
1743
1807
|
|
|
@@ -1753,6 +1817,9 @@ function walkHtmlNode(node, expressions, findings, componentPropertyMaps) {
|
|
|
1753
1817
|
);
|
|
1754
1818
|
validateHtmlAttribute(node, attrName, findings);
|
|
1755
1819
|
validateValueBindingEvent(node, attrName, findings);
|
|
1820
|
+
if (attrName === 'ref') {
|
|
1821
|
+
validateRefAttribute(attrValue, supportedProps, findings, seenRefProps);
|
|
1822
|
+
}
|
|
1756
1823
|
if (
|
|
1757
1824
|
REFS_TEST_RE.test(attrValue) ||
|
|
1758
1825
|
(attrName.startsWith('on') && IDENTIFIER_RE.test(attrValue))
|
|
@@ -1785,7 +1852,14 @@ function walkHtmlNode(node, expressions, findings, componentPropertyMaps) {
|
|
|
1785
1852
|
}
|
|
1786
1853
|
|
|
1787
1854
|
for (const child of node.childNodes ?? []) {
|
|
1788
|
-
walkHtmlNode(
|
|
1855
|
+
walkHtmlNode(
|
|
1856
|
+
child,
|
|
1857
|
+
expressions,
|
|
1858
|
+
findings,
|
|
1859
|
+
componentPropertyMaps,
|
|
1860
|
+
supportedProps,
|
|
1861
|
+
seenRefProps
|
|
1862
|
+
);
|
|
1789
1863
|
}
|
|
1790
1864
|
}
|
|
1791
1865
|
|