@dooboostore/simple-web-component 1.0.6 → 1.0.8
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/README.md +161 -84
- package/dist/cjs/decorators/addEventListener.js.map +1 -1
- package/dist/cjs/decorators/elementDefine.js +78 -44
- package/dist/cjs/decorators/elementDefine.js.map +2 -2
- package/dist/cjs/decorators/query.js +27 -5
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/queryAll.js +27 -5
- package/dist/cjs/decorators/queryAll.js.map +2 -2
- package/dist/cjs/decorators/state.js.map +1 -1
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/SwcForOf.js +3 -1
- package/dist/cjs/elements/SwcForOf.js.map +2 -2
- package/dist/cjs/elements/SwcObject.js +8 -6
- package/dist/cjs/elements/SwcObject.js.map +2 -2
- package/dist/cjs/index.js +3 -6
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/is/SwcIfAnchor.js +1 -1
- package/dist/cjs/is/SwcIfAnchor.js.map +2 -2
- package/dist/cjs/is/SwcIfArea.js +1 -1
- package/dist/cjs/is/SwcIfArea.js.map +2 -2
- package/dist/cjs/is/SwcIfAudio.js +1 -1
- package/dist/cjs/is/SwcIfAudio.js.map +2 -2
- package/dist/cjs/is/SwcIfBase.js +1 -1
- package/dist/cjs/is/SwcIfBase.js.map +2 -2
- package/dist/cjs/is/SwcIfButton.js +1 -1
- package/dist/cjs/is/SwcIfButton.js.map +2 -2
- package/dist/cjs/is/SwcIfCanvas.js +1 -1
- package/dist/cjs/is/SwcIfCanvas.js.map +2 -2
- package/dist/cjs/is/SwcIfData.js +1 -1
- package/dist/cjs/is/SwcIfData.js.map +2 -2
- package/dist/cjs/is/SwcIfDataList.js +1 -1
- package/dist/cjs/is/SwcIfDataList.js.map +2 -2
- package/dist/cjs/is/SwcIfDetails.js +1 -1
- package/dist/cjs/is/SwcIfDetails.js.map +2 -2
- package/dist/cjs/is/SwcIfDialog.js +1 -1
- package/dist/cjs/is/SwcIfDialog.js.map +2 -2
- package/dist/cjs/is/SwcIfDiv.js +1 -1
- package/dist/cjs/is/SwcIfDiv.js.map +2 -2
- package/dist/cjs/is/SwcIfDl.js +1 -1
- package/dist/cjs/is/SwcIfDl.js.map +2 -2
- package/dist/cjs/is/SwcIfEmbed.js +1 -1
- package/dist/cjs/is/SwcIfEmbed.js.map +2 -2
- package/dist/cjs/is/SwcIfFieldSet.js +1 -1
- package/dist/cjs/is/SwcIfFieldSet.js.map +2 -2
- package/dist/cjs/is/SwcIfForm.js +1 -1
- package/dist/cjs/is/SwcIfForm.js.map +2 -2
- package/dist/cjs/is/SwcIfHeading.js +1 -1
- package/dist/cjs/is/SwcIfHeading.js.map +2 -2
- package/dist/cjs/is/SwcIfHr.js +1 -1
- package/dist/cjs/is/SwcIfHr.js.map +2 -2
- package/dist/cjs/is/SwcIfIFrame.js +1 -1
- package/dist/cjs/is/SwcIfIFrame.js.map +2 -2
- package/dist/cjs/is/SwcIfImage.js +1 -1
- package/dist/cjs/is/SwcIfImage.js.map +2 -2
- package/dist/cjs/is/SwcIfInput.js +1 -1
- package/dist/cjs/is/SwcIfInput.js.map +2 -2
- package/dist/cjs/is/SwcIfLabel.js +1 -1
- package/dist/cjs/is/SwcIfLabel.js.map +2 -2
- package/dist/cjs/is/SwcIfLegend.js +1 -1
- package/dist/cjs/is/SwcIfLegend.js.map +2 -2
- package/dist/cjs/is/SwcIfLi.js +1 -1
- package/dist/cjs/is/SwcIfLi.js.map +2 -2
- package/dist/cjs/is/SwcIfLink.js +1 -1
- package/dist/cjs/is/SwcIfLink.js.map +2 -2
- package/dist/cjs/is/SwcIfMap.js +1 -1
- package/dist/cjs/is/SwcIfMap.js.map +2 -2
- package/dist/cjs/is/SwcIfMeta.js +1 -1
- package/dist/cjs/is/SwcIfMeta.js.map +2 -2
- package/dist/cjs/is/SwcIfMeter.js +1 -1
- package/dist/cjs/is/SwcIfMeter.js.map +2 -2
- package/dist/cjs/is/SwcIfMod.js +1 -1
- package/dist/cjs/is/SwcIfMod.js.map +2 -2
- package/dist/cjs/is/SwcIfObject.js +1 -1
- package/dist/cjs/is/SwcIfObject.js.map +2 -2
- package/dist/cjs/is/SwcIfOl.js +1 -1
- package/dist/cjs/is/SwcIfOl.js.map +2 -2
- package/dist/cjs/is/SwcIfOptGroup.js +1 -1
- package/dist/cjs/is/SwcIfOptGroup.js.map +2 -2
- package/dist/cjs/is/SwcIfOption.js +1 -1
- package/dist/cjs/is/SwcIfOption.js.map +2 -2
- package/dist/cjs/is/SwcIfOutput.js +1 -1
- package/dist/cjs/is/SwcIfOutput.js.map +2 -2
- package/dist/cjs/is/SwcIfParagraph.js +1 -1
- package/dist/cjs/is/SwcIfParagraph.js.map +2 -2
- package/dist/cjs/is/SwcIfParam.js +1 -1
- package/dist/cjs/is/SwcIfParam.js.map +2 -2
- package/dist/cjs/is/SwcIfPicture.js +1 -1
- package/dist/cjs/is/SwcIfPicture.js.map +2 -2
- package/dist/cjs/is/SwcIfPre.js +1 -1
- package/dist/cjs/is/SwcIfPre.js.map +2 -2
- package/dist/cjs/is/SwcIfProgress.js +1 -1
- package/dist/cjs/is/SwcIfProgress.js.map +2 -2
- package/dist/cjs/is/SwcIfQuote.js +1 -1
- package/dist/cjs/is/SwcIfQuote.js.map +2 -2
- package/dist/cjs/is/SwcIfScript.js +1 -1
- package/dist/cjs/is/SwcIfScript.js.map +2 -2
- package/dist/cjs/is/SwcIfSelect.js +1 -1
- package/dist/cjs/is/SwcIfSelect.js.map +2 -2
- package/dist/cjs/is/SwcIfSlot.js +1 -1
- package/dist/cjs/is/SwcIfSlot.js.map +2 -2
- package/dist/cjs/is/SwcIfSource.js +1 -1
- package/dist/cjs/is/SwcIfSource.js.map +2 -2
- package/dist/cjs/is/SwcIfSpan.js +1 -1
- package/dist/cjs/is/SwcIfSpan.js.map +2 -2
- package/dist/cjs/is/SwcIfStyle.js +1 -1
- package/dist/cjs/is/SwcIfStyle.js.map +2 -2
- package/dist/cjs/is/SwcIfTable.js +1 -1
- package/dist/cjs/is/SwcIfTable.js.map +2 -2
- package/dist/cjs/is/SwcIfTableCell.js +1 -1
- package/dist/cjs/is/SwcIfTableCell.js.map +2 -2
- package/dist/cjs/is/SwcIfTableRow.js +1 -1
- package/dist/cjs/is/SwcIfTableRow.js.map +2 -2
- package/dist/cjs/is/SwcIfTableSection.js +1 -1
- package/dist/cjs/is/SwcIfTableSection.js.map +2 -2
- package/dist/cjs/is/SwcIfTemplate.js +1 -1
- package/dist/cjs/is/SwcIfTemplate.js.map +2 -2
- package/dist/cjs/is/SwcIfTextArea.js +1 -1
- package/dist/cjs/is/SwcIfTextArea.js.map +2 -2
- package/dist/cjs/is/SwcIfTime.js +1 -1
- package/dist/cjs/is/SwcIfTime.js.map +2 -2
- package/dist/cjs/is/SwcIfTitle.js +1 -1
- package/dist/cjs/is/SwcIfTitle.js.map +2 -2
- package/dist/cjs/is/SwcIfTrack.js +1 -1
- package/dist/cjs/is/SwcIfTrack.js.map +2 -2
- package/dist/cjs/is/SwcIfUl.js +1 -1
- package/dist/cjs/is/SwcIfUl.js.map +2 -2
- package/dist/cjs/is/SwcIfVideo.js +1 -1
- package/dist/cjs/is/SwcIfVideo.js.map +2 -2
- package/dist/cjs/utils/Utils.js +13 -22
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js.map +1 -1
- package/dist/esm/decorators/elementDefine.js +78 -44
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/query.js +27 -5
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/queryAll.js +27 -5
- package/dist/esm/decorators/queryAll.js.map +2 -2
- package/dist/esm/decorators/state.js.map +1 -1
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/SwcForOf.js +3 -1
- package/dist/esm/elements/SwcForOf.js.map +2 -2
- package/dist/esm/elements/SwcObject.js +8 -6
- package/dist/esm/elements/SwcObject.js.map +2 -2
- package/dist/esm/index.js +3 -6
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/is/SwcIfAnchor.js +1 -1
- package/dist/esm/is/SwcIfAnchor.js.map +2 -2
- package/dist/esm/is/SwcIfArea.js +1 -1
- package/dist/esm/is/SwcIfArea.js.map +2 -2
- package/dist/esm/is/SwcIfAudio.js +1 -1
- package/dist/esm/is/SwcIfAudio.js.map +2 -2
- package/dist/esm/is/SwcIfBase.js +1 -1
- package/dist/esm/is/SwcIfBase.js.map +2 -2
- package/dist/esm/is/SwcIfButton.js +1 -1
- package/dist/esm/is/SwcIfButton.js.map +2 -2
- package/dist/esm/is/SwcIfCanvas.js +1 -1
- package/dist/esm/is/SwcIfCanvas.js.map +2 -2
- package/dist/esm/is/SwcIfData.js +1 -1
- package/dist/esm/is/SwcIfData.js.map +2 -2
- package/dist/esm/is/SwcIfDataList.js +1 -1
- package/dist/esm/is/SwcIfDataList.js.map +2 -2
- package/dist/esm/is/SwcIfDetails.js +1 -1
- package/dist/esm/is/SwcIfDetails.js.map +2 -2
- package/dist/esm/is/SwcIfDialog.js +1 -1
- package/dist/esm/is/SwcIfDialog.js.map +2 -2
- package/dist/esm/is/SwcIfDiv.js +1 -1
- package/dist/esm/is/SwcIfDiv.js.map +2 -2
- package/dist/esm/is/SwcIfDl.js +1 -1
- package/dist/esm/is/SwcIfDl.js.map +2 -2
- package/dist/esm/is/SwcIfEmbed.js +1 -1
- package/dist/esm/is/SwcIfEmbed.js.map +2 -2
- package/dist/esm/is/SwcIfFieldSet.js +1 -1
- package/dist/esm/is/SwcIfFieldSet.js.map +2 -2
- package/dist/esm/is/SwcIfForm.js +1 -1
- package/dist/esm/is/SwcIfForm.js.map +2 -2
- package/dist/esm/is/SwcIfHeading.js +1 -1
- package/dist/esm/is/SwcIfHeading.js.map +2 -2
- package/dist/esm/is/SwcIfHr.js +1 -1
- package/dist/esm/is/SwcIfHr.js.map +2 -2
- package/dist/esm/is/SwcIfIFrame.js +1 -1
- package/dist/esm/is/SwcIfIFrame.js.map +2 -2
- package/dist/esm/is/SwcIfImage.js +1 -1
- package/dist/esm/is/SwcIfImage.js.map +2 -2
- package/dist/esm/is/SwcIfInput.js +1 -1
- package/dist/esm/is/SwcIfInput.js.map +2 -2
- package/dist/esm/is/SwcIfLabel.js +1 -1
- package/dist/esm/is/SwcIfLabel.js.map +2 -2
- package/dist/esm/is/SwcIfLegend.js +1 -1
- package/dist/esm/is/SwcIfLegend.js.map +2 -2
- package/dist/esm/is/SwcIfLi.js +1 -1
- package/dist/esm/is/SwcIfLi.js.map +2 -2
- package/dist/esm/is/SwcIfLink.js +1 -1
- package/dist/esm/is/SwcIfLink.js.map +2 -2
- package/dist/esm/is/SwcIfMap.js +1 -1
- package/dist/esm/is/SwcIfMap.js.map +2 -2
- package/dist/esm/is/SwcIfMeta.js +1 -1
- package/dist/esm/is/SwcIfMeta.js.map +2 -2
- package/dist/esm/is/SwcIfMeter.js +1 -1
- package/dist/esm/is/SwcIfMeter.js.map +2 -2
- package/dist/esm/is/SwcIfMod.js +1 -1
- package/dist/esm/is/SwcIfMod.js.map +2 -2
- package/dist/esm/is/SwcIfObject.js +1 -1
- package/dist/esm/is/SwcIfObject.js.map +2 -2
- package/dist/esm/is/SwcIfOl.js +1 -1
- package/dist/esm/is/SwcIfOl.js.map +2 -2
- package/dist/esm/is/SwcIfOptGroup.js +1 -1
- package/dist/esm/is/SwcIfOptGroup.js.map +2 -2
- package/dist/esm/is/SwcIfOption.js +1 -1
- package/dist/esm/is/SwcIfOption.js.map +2 -2
- package/dist/esm/is/SwcIfOutput.js +1 -1
- package/dist/esm/is/SwcIfOutput.js.map +2 -2
- package/dist/esm/is/SwcIfParagraph.js +1 -1
- package/dist/esm/is/SwcIfParagraph.js.map +2 -2
- package/dist/esm/is/SwcIfParam.js +1 -1
- package/dist/esm/is/SwcIfParam.js.map +2 -2
- package/dist/esm/is/SwcIfPicture.js +1 -1
- package/dist/esm/is/SwcIfPicture.js.map +2 -2
- package/dist/esm/is/SwcIfPre.js +1 -1
- package/dist/esm/is/SwcIfPre.js.map +2 -2
- package/dist/esm/is/SwcIfProgress.js +1 -1
- package/dist/esm/is/SwcIfProgress.js.map +2 -2
- package/dist/esm/is/SwcIfQuote.js +1 -1
- package/dist/esm/is/SwcIfQuote.js.map +2 -2
- package/dist/esm/is/SwcIfScript.js +1 -1
- package/dist/esm/is/SwcIfScript.js.map +2 -2
- package/dist/esm/is/SwcIfSelect.js +1 -1
- package/dist/esm/is/SwcIfSelect.js.map +2 -2
- package/dist/esm/is/SwcIfSlot.js +1 -1
- package/dist/esm/is/SwcIfSlot.js.map +2 -2
- package/dist/esm/is/SwcIfSource.js +1 -1
- package/dist/esm/is/SwcIfSource.js.map +2 -2
- package/dist/esm/is/SwcIfSpan.js +1 -1
- package/dist/esm/is/SwcIfSpan.js.map +2 -2
- package/dist/esm/is/SwcIfStyle.js +1 -1
- package/dist/esm/is/SwcIfStyle.js.map +2 -2
- package/dist/esm/is/SwcIfTable.js +1 -1
- package/dist/esm/is/SwcIfTable.js.map +2 -2
- package/dist/esm/is/SwcIfTableCell.js +1 -1
- package/dist/esm/is/SwcIfTableCell.js.map +2 -2
- package/dist/esm/is/SwcIfTableRow.js +1 -1
- package/dist/esm/is/SwcIfTableRow.js.map +2 -2
- package/dist/esm/is/SwcIfTableSection.js +1 -1
- package/dist/esm/is/SwcIfTableSection.js.map +2 -2
- package/dist/esm/is/SwcIfTemplate.js +1 -1
- package/dist/esm/is/SwcIfTemplate.js.map +2 -2
- package/dist/esm/is/SwcIfTextArea.js +1 -1
- package/dist/esm/is/SwcIfTextArea.js.map +2 -2
- package/dist/esm/is/SwcIfTime.js +1 -1
- package/dist/esm/is/SwcIfTime.js.map +2 -2
- package/dist/esm/is/SwcIfTitle.js +1 -1
- package/dist/esm/is/SwcIfTitle.js.map +2 -2
- package/dist/esm/is/SwcIfTrack.js +1 -1
- package/dist/esm/is/SwcIfTrack.js.map +2 -2
- package/dist/esm/is/SwcIfUl.js +1 -1
- package/dist/esm/is/SwcIfUl.js.map +2 -2
- package/dist/esm/is/SwcIfVideo.js +1 -1
- package/dist/esm/is/SwcIfVideo.js.map +2 -2
- package/dist/esm/utils/Utils.js +13 -22
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1970 -2045
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/addEventListener.d.ts +1 -1
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +5 -2
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/queryAll.d.ts +5 -2
- package/dist/types/decorators/queryAll.d.ts.map +1 -1
- package/dist/types/decorators/state.d.ts +1 -1
- package/dist/types/decorators/state.d.ts.map +1 -1
- package/dist/types/elements/SwcChoose.d.ts.map +1 -1
- package/dist/types/elements/SwcForOf.d.ts.map +1 -1
- package/dist/types/elements/SwcObject.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts +1 -1
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1970 -2045
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +4 -4
- package/src/decorators/addEventListener.ts +1 -1
- package/src/decorators/elementDefine.ts +105 -44
- package/src/decorators/query.ts +35 -8
- package/src/decorators/queryAll.ts +35 -8
- package/src/decorators/state.ts +1 -1
- package/src/elements/SwcChoose.ts +1 -5
- package/src/elements/SwcForOf.ts +2 -1
- package/src/elements/SwcObject.ts +8 -6
- package/src/index.ts +3 -6
- package/src/is/SwcIfAnchor.ts +1 -1
- package/src/is/SwcIfArea.ts +1 -1
- package/src/is/SwcIfAudio.ts +1 -1
- package/src/is/SwcIfBase.ts +1 -1
- package/src/is/SwcIfButton.ts +1 -1
- package/src/is/SwcIfCanvas.ts +1 -1
- package/src/is/SwcIfData.ts +1 -1
- package/src/is/SwcIfDataList.ts +1 -1
- package/src/is/SwcIfDetails.ts +1 -1
- package/src/is/SwcIfDialog.ts +1 -1
- package/src/is/SwcIfDiv.ts +1 -1
- package/src/is/SwcIfDl.ts +1 -1
- package/src/is/SwcIfEmbed.ts +1 -1
- package/src/is/SwcIfFieldSet.ts +1 -1
- package/src/is/SwcIfForm.ts +1 -1
- package/src/is/SwcIfHeading.ts +1 -1
- package/src/is/SwcIfHr.ts +1 -1
- package/src/is/SwcIfIFrame.ts +1 -1
- package/src/is/SwcIfImage.ts +1 -1
- package/src/is/SwcIfInput.ts +1 -1
- package/src/is/SwcIfLabel.ts +1 -1
- package/src/is/SwcIfLegend.ts +1 -1
- package/src/is/SwcIfLi.ts +1 -1
- package/src/is/SwcIfLink.ts +1 -1
- package/src/is/SwcIfMap.ts +1 -1
- package/src/is/SwcIfMeta.ts +1 -1
- package/src/is/SwcIfMeter.ts +1 -1
- package/src/is/SwcIfMod.ts +1 -1
- package/src/is/SwcIfObject.ts +1 -1
- package/src/is/SwcIfOl.ts +1 -1
- package/src/is/SwcIfOptGroup.ts +1 -1
- package/src/is/SwcIfOption.ts +1 -1
- package/src/is/SwcIfOutput.ts +1 -1
- package/src/is/SwcIfParagraph.ts +1 -1
- package/src/is/SwcIfParam.ts +1 -1
- package/src/is/SwcIfPicture.ts +1 -1
- package/src/is/SwcIfPre.ts +1 -1
- package/src/is/SwcIfProgress.ts +1 -1
- package/src/is/SwcIfQuote.ts +1 -1
- package/src/is/SwcIfScript.ts +1 -1
- package/src/is/SwcIfSelect.ts +1 -1
- package/src/is/SwcIfSlot.ts +1 -1
- package/src/is/SwcIfSource.ts +1 -1
- package/src/is/SwcIfSpan.ts +1 -1
- package/src/is/SwcIfStyle.ts +1 -1
- package/src/is/SwcIfTable.ts +1 -1
- package/src/is/SwcIfTableCell.ts +1 -1
- package/src/is/SwcIfTableRow.ts +1 -1
- package/src/is/SwcIfTableSection.ts +1 -1
- package/src/is/SwcIfTemplate.ts +1 -1
- package/src/is/SwcIfTextArea.ts +1 -1
- package/src/is/SwcIfTime.ts +1 -1
- package/src/is/SwcIfTitle.ts +1 -1
- package/src/is/SwcIfTrack.ts +1 -1
- package/src/is/SwcIfUl.ts +1 -1
- package/src/is/SwcIfVideo.ts +1 -1
- package/src/utils/Utils.ts +18 -32
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @dooboostore/simple-web-component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An ultra-lightweight, high-performance Web Component library that brings **Modern Reactivity** to **Standard Web Technologies**. Build complex, high-performance UIs using native Shadow DOM, Slots, and MutationObservers without the overhead of a Virtual DOM.
|
|
4
4
|
|
|
5
|
-
## 🚀 Key
|
|
5
|
+
## 🚀 Key Advantages
|
|
6
6
|
|
|
7
|
-
- **Standard-First**: Uses the native `is` attribute to enhance standard HTML tags (`ul`, `table`, `div`, etc.). Your markup stays clean and semantic.
|
|
8
7
|
- **Surgical Updates**: Powered by Proxy-based reactivity. It updates only the specific **Text Nodes or Attributes** bound to data—no full-tree diffing.
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **Scoped Context (`as`)**:
|
|
8
|
+
- **Standard-First**: Keep your HTML semantic. Use the native `is` attribute to enhance standard tags (`ul`, `table`, `div`, etc.).
|
|
9
|
+
- **Zero Boilerplate**: Define queries, events, and lifecycles declaratively using decorators.
|
|
10
|
+
- **Scoped Context (`as`)**: Effortlessly isolate and share data between parent and child components using explicit aliases.
|
|
11
|
+
- **Hybrid Rendering**: Seamlessly combine **Shadow DOM** and **Light DOM** in a single component.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -18,132 +18,209 @@ A ultra-lightweight, high-performance Web Component library that brings **Modern
|
|
|
18
18
|
pnpm add @dooboostore/simple-web-component
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
### Safari Support (
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
### Safari Support (Required)
|
|
22
|
+
Include this polyfill at the very top of your entry point to support the `is` attribute in Safari:
|
|
24
23
|
```javascript
|
|
25
24
|
import '@ungap/custom-elements';
|
|
25
|
+
import 'reflect-metadata';
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
## 💡 Practical
|
|
30
|
+
## 💡 Practical Showcase
|
|
31
31
|
|
|
32
|
-
### 1.
|
|
33
|
-
|
|
32
|
+
### 1. Basic Reactive Component
|
|
33
|
+
A counter where only the number part is updated in the DOM when you click.
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
import { elementDefine, innerHtml, state, addEventListener } from '@dooboostore/simple-web-component';
|
|
37
|
+
|
|
38
|
+
@elementDefine('my-counter')
|
|
39
|
+
class MyCounter extends HTMLElement {
|
|
40
|
+
@state count = 0;
|
|
41
|
+
|
|
39
42
|
@innerHtml({ useShadow: true })
|
|
40
43
|
render() {
|
|
41
44
|
return `
|
|
42
|
-
<
|
|
43
|
-
<
|
|
45
|
+
<p>Count: <strong>{{count}}</strong></p>
|
|
46
|
+
<button id="inc"> +1 </button>
|
|
44
47
|
`;
|
|
45
48
|
}
|
|
49
|
+
|
|
50
|
+
@addEventListener({ type: 'click', query: '#inc' })
|
|
51
|
+
onInc() {
|
|
52
|
+
this.count++; // 👈 Surgical Update!
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. Nested Scopes with `as="alias"`
|
|
58
|
+
Access parent data from deeply nested children without naming collisions.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
@elementDefine({ name: 'parent-comp' })
|
|
62
|
+
class Parent extends HTMLElement {
|
|
63
|
+
@state user = { name: 'Alice', score: 100 };
|
|
64
|
+
@innerHtml({ useShadow: true })
|
|
65
|
+
render() { return `<h3>User: {{p.user.name}}</h3><slot></slot>`; }
|
|
46
66
|
}
|
|
47
67
|
|
|
48
68
|
@elementDefine({ name: 'child-comp' })
|
|
49
69
|
class Child extends HTMLElement {
|
|
50
|
-
@state
|
|
70
|
+
@state score = 0;
|
|
51
71
|
@innerHtml({ useShadow: true })
|
|
52
72
|
render() {
|
|
53
73
|
return `
|
|
54
|
-
<div>Child
|
|
55
|
-
<div>Parent's
|
|
74
|
+
<div>Child Score: {{c.score}}</div>
|
|
75
|
+
<div>Parent's Score: {{p.user.score}}</div> <!-- 👈 Scoped Access -->
|
|
56
76
|
`;
|
|
57
77
|
}
|
|
58
78
|
}
|
|
59
79
|
```
|
|
60
|
-
|
|
61
80
|
```html
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
<!-- HTML Usage -->
|
|
82
|
+
<parent-comp as="p">
|
|
83
|
+
<child-comp as="c"></child-comp>
|
|
64
84
|
</parent-comp>
|
|
65
85
|
```
|
|
66
86
|
|
|
67
|
-
###
|
|
68
|
-
|
|
87
|
+
### 3. Mixed Shadow & Light DOM Rendering
|
|
88
|
+
You can distribute templates across both Shadow and Light DOM in a single component.
|
|
69
89
|
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
90
|
+
```typescript
|
|
91
|
+
@elementDefine({ name: 'hybrid-comp' })
|
|
92
|
+
class HybridComp extends HTMLElement {
|
|
93
|
+
@innerHtml({ useShadow: true })
|
|
94
|
+
renderShadow() {
|
|
95
|
+
return `<div style="border: 1px solid blue;"><slot></slot></div>`;
|
|
96
|
+
}
|
|
77
97
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
list.swcValue.push({ id: 3, name: 'Charlie' });
|
|
84
|
-
</script>
|
|
98
|
+
@innerHtml
|
|
99
|
+
renderLight() {
|
|
100
|
+
return `<p>I am in the Light DOM!</p>`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
85
103
|
```
|
|
86
104
|
|
|
87
|
-
|
|
88
|
-
Bind a complex object to a template. Updates happen instantly when properties change.
|
|
105
|
+
---
|
|
89
106
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
107
|
+
## 📑 Decorator Deep Dive
|
|
108
|
+
|
|
109
|
+
### `@elementDefine(config)`
|
|
110
|
+
Registers the class as a Custom Element.
|
|
111
|
+
- `name`: (Required) Tag name.
|
|
112
|
+
- `extends`: (Optional) Native tag to extend (e.g., `'ul'`).
|
|
113
|
+
- `autoRemoveEventListeners`: (Optional) Auto-cleanup on disconnect.
|
|
114
|
+
|
|
115
|
+
### `@innerHtml(options?)`
|
|
116
|
+
Defines markup. Supports **Async (Promises)**.
|
|
117
|
+
- `root`: `'shadow'` (Shadow DOM) or `'light'` (Light DOM). Default depends on `useShadow`.
|
|
118
|
+
- `useShadow`: Shortcut to set `root: 'shadow'`.
|
|
119
|
+
|
|
120
|
+
### `@state(alias?)`
|
|
121
|
+
Declares a property as reactive. Tracks changes in nested objects/arrays.
|
|
122
|
+
- `alias`: Custom name for templates (e.g. `{{alias.path}}`).
|
|
123
|
+
|
|
124
|
+
### `@attribute(options?)`
|
|
125
|
+
Syncs property with HTML attribute.
|
|
126
|
+
- `name`: HTML attribute name.
|
|
127
|
+
- `type`: `String`, `Number`, `Boolean`, `Object`.
|
|
128
|
+
- `disableReflect`: If `true`, stops JS -> HTML sync. Default is `false`.
|
|
129
|
+
|
|
130
|
+
### `@query(selector?, options?)`
|
|
131
|
+
Lazy-loads elements from the DOM.
|
|
132
|
+
- `selector`: CSS selector. If omitted, targets the **Host**.
|
|
133
|
+
- `root`: `'shadow' | 'light' | 'all' | 'auto'` (Default: `'auto'`).
|
|
134
|
+
|
|
135
|
+
### `@addEventListener(options)`
|
|
136
|
+
Declarative event binding. Method receives `(event, targetElement)`.
|
|
137
|
+
- `type`: Event type.
|
|
138
|
+
- `query`: CSS selector. Omit to bind to **Host**.
|
|
139
|
+
- `root`: `'shadow' | 'light' | 'all' | 'auto'`.
|
|
140
|
+
- `stopPropagation`, `preventDefault`, `stopImmediatePropagation`: Event modifiers.
|
|
96
141
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## ⏳ Lifecycle Hooks
|
|
145
|
+
Provides 6-stage hooks for precise control. Multiple methods per hook are supported.
|
|
146
|
+
|
|
147
|
+
| Hook | Timing |
|
|
148
|
+
| :--- | :--- |
|
|
149
|
+
| **`@onBeforeConnected`** | Before template injection. |
|
|
150
|
+
| **`@onAfterConnected`** | After injection (Alias: **`@onConnected`**). |
|
|
151
|
+
| **`@onBeforeDisconnected`**| Before element removal. |
|
|
152
|
+
| **`@onAfterDisconnected`** | After removal and cleanup (Alias: **`@onDisconnected`**). |
|
|
153
|
+
| **`@onAttributeChanged(key)`**| When an attribute (or `*` wildcard) changes. |
|
|
154
|
+
| **`@onAddEventListener`** | Called when a listener is attached via `@addEventListener`. |
|
|
105
155
|
|
|
106
156
|
---
|
|
107
157
|
|
|
108
|
-
##
|
|
158
|
+
## 🛠 Built-in Logic Components (`is` Variants)
|
|
109
159
|
|
|
110
|
-
|
|
160
|
+
Enhance any standard HTML tag with logic using the `is` attribute. Use **`swcValue`** to bind data.
|
|
111
161
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
| `@addEventListener(opts)`| Method | Declarative event binding. Automatically re-binds if DOM changes. |
|
|
120
|
-
| `@emitCustomEvent(type)` | Method | Dispatches a `CustomEvent`. 리턴값은 부모 템플릿의 `$data`로 전달됩니다. |
|
|
162
|
+
### 1. Looping (`swc-for-of-[tag]`)
|
|
163
|
+
High-performance rendering that keeps your markup structure.
|
|
164
|
+
```html
|
|
165
|
+
<ul is="swc-for-of-ul" swcValue="{{items}}" as="item" as-index="i">
|
|
166
|
+
<li>{{i}}. {{item.name}}</li>
|
|
167
|
+
</ul>
|
|
168
|
+
```
|
|
121
169
|
|
|
122
|
-
###
|
|
170
|
+
### 2. Conditionals (`swc-if-[tag]`)
|
|
171
|
+
Elements are physically added/removed from the DOM tree.
|
|
172
|
+
```html
|
|
173
|
+
<div is="swc-if-div" swcValue="{{isVisible}}">
|
|
174
|
+
<p>Now you see me!</p>
|
|
175
|
+
</div>
|
|
176
|
+
```
|
|
123
177
|
|
|
124
|
-
|
|
178
|
+
### 3. Branching (`swc-choose-[tag]`)
|
|
179
|
+
Switch-case style logic with physical element swapping.
|
|
180
|
+
```html
|
|
181
|
+
<div is="swc-choose-div" swcValue="{{status}}">
|
|
182
|
+
<span is="swc-when-span" test="loading">Loading...</span>
|
|
183
|
+
<span is="swc-when-span" test="error">Error!</span>
|
|
184
|
+
<div is="swc-other-div">Success!</div>
|
|
185
|
+
</div>
|
|
186
|
+
```
|
|
125
187
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
| `@onAddEventListener` | Callback when any `@addEventListener` is triggered. |
|
|
188
|
+
### 4. Object Binding (`swc-object-[tag]`)
|
|
189
|
+
Binds a single object surgically to any tag.
|
|
190
|
+
```html
|
|
191
|
+
<div is="swc-object-div" swcValue="{{user}}" as="u">
|
|
192
|
+
<h3>{{u.name}}</h3>
|
|
193
|
+
</div>
|
|
194
|
+
```
|
|
134
195
|
|
|
135
196
|
---
|
|
136
197
|
|
|
137
|
-
##
|
|
198
|
+
## 📜 Full Feature Integration Example
|
|
138
199
|
|
|
139
|
-
|
|
200
|
+
```typescript
|
|
201
|
+
@elementDefine('app-root')
|
|
202
|
+
class AppRoot extends HTMLElement {
|
|
203
|
+
@state profile = { name: 'John', loggedIn: true };
|
|
140
204
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
- **Choose**: `swc-choose-div`, `swc-choose-section` ...
|
|
144
|
-
- **Object**: `swc-object-div`, `swc-object-article` ...
|
|
205
|
+
@onConnected
|
|
206
|
+
init() { console.log('App Started'); }
|
|
145
207
|
|
|
146
|
-
|
|
208
|
+
@innerHtml({ useShadow: true })
|
|
209
|
+
render() {
|
|
210
|
+
return `
|
|
211
|
+
<div is="swc-if-div" swcValue="{{profile.loggedIn}}">
|
|
212
|
+
<h1>Welcome, {{profile.name}}!</h1>
|
|
213
|
+
<button id="logout">Logout</button>
|
|
214
|
+
</div>
|
|
215
|
+
`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@addEventListener({ type: 'click', query: '#logout' })
|
|
219
|
+
onLogout() {
|
|
220
|
+
this.profile.loggedIn = false; // Surgical UI disappearance
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
147
224
|
|
|
148
|
-
##
|
|
225
|
+
## License
|
|
149
226
|
MIT
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/decorators/addEventListener.ts"],
|
|
4
|
-
"sourcesContent": ["import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\n\nexport interface AddEventListenerOptions extends EventListenerOptions {\n query?: string;\n type: string;\n
|
|
4
|
+
"sourcesContent": ["import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\n\nexport interface AddEventListenerOptions extends EventListenerOptions {\n query?: string;\n type: string;\n root?: 'light' | 'shadow' | 'all' | 'auto';\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n stopPropagation?: boolean;\n stopImmediatePropagation?: boolean;\n preventDefault?: boolean;\n}\n\nexport interface AddEventListenerMetadata {\n options: AddEventListenerOptions;\n propertyKey: string | symbol;\n}\n\nexport const ADD_EVENT_LISTENER_METADATA_KEY = Symbol('simple-web-component:add-event-listener');\n\nexport function addEventListener(type: string, query?: string): MethodDecorator;\nexport function addEventListener(options: AddEventListenerOptions): MethodDecorator;\nexport function addEventListener(arg1: string | AddEventListenerOptions, arg2?: string): MethodDecorator {\n return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const constructor = target.constructor;\n const options: AddEventListenerOptions = typeof arg1 === 'string' ? { type: arg1, query: arg2 } : arg1;\n\n let listeners = ReflectUtils.getMetadata<AddEventListenerMetadata[]>(ADD_EVENT_LISTENER_METADATA_KEY, constructor);\n if (!listeners) {\n listeners = [];\n ReflectUtils.defineMetadata(ADD_EVENT_LISTENER_METADATA_KEY, listeners, constructor);\n }\n listeners.push({ options, propertyKey });\n };\n}\n\nexport const getAddEventListenerMetadata = (target: any): AddEventListenerMetadata[] | undefined => {\n const constructor = target instanceof Function ? target : target.constructor;\n return ReflectUtils.getMetadata(ADD_EVENT_LISTENER_METADATA_KEY, constructor);\n};\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA6B;AAmBtB,MAAM,kCAAkC,OAAO,yCAAyC;AAIxF,SAAS,iBAAiB,MAAwC,MAAgC;AACvG,SAAO,CAAC,QAAgB,aAA8B,eAAmC;AACvF,UAAM,cAAc,OAAO;AAC3B,UAAM,UAAmC,OAAO,SAAS,WAAW,EAAE,MAAM,MAAM,OAAO,KAAK,IAAI;AAElG,QAAI,YAAY,iCAAa,YAAwC,iCAAiC,WAAW;AACjH,QAAI,CAAC,WAAW;AACd,kBAAY,CAAC;AACb,uCAAa,eAAe,iCAAiC,WAAW,WAAW;AAAA,IACrF;AACA,cAAU,KAAK,EAAE,SAAS,YAAY,CAAC;AAAA,EACzC;AACF;AAEO,MAAM,8BAA8B,CAAC,WAAwD;AAClG,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,SAAO,iCAAa,YAAY,iCAAiC,WAAW;AAC9E;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -161,19 +161,37 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
161
161
|
}
|
|
162
162
|
_syncDecorators() {
|
|
163
163
|
this._buildStateMap();
|
|
164
|
+
const getSearchRoots = (rootOption) => {
|
|
165
|
+
const roots = [];
|
|
166
|
+
if (rootOption === "shadow") {
|
|
167
|
+
if (this.shadowRoot) roots.push(this.shadowRoot);
|
|
168
|
+
} else if (rootOption === "light") {
|
|
169
|
+
roots.push(this);
|
|
170
|
+
} else if (rootOption === "all") {
|
|
171
|
+
if (this.shadowRoot) roots.push(this.shadowRoot);
|
|
172
|
+
roots.push(this);
|
|
173
|
+
} else {
|
|
174
|
+
roots.push(this.shadowRoot || this);
|
|
175
|
+
}
|
|
176
|
+
return roots;
|
|
177
|
+
};
|
|
164
178
|
const queryMetadata = (0, import_query.getQueryMetadata)(this);
|
|
165
179
|
if (queryMetadata) {
|
|
166
180
|
queryMetadata.filter((it) => it.isMethod).forEach((it) => {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
181
|
+
const searchRoots = getSearchRoots(it.options.root);
|
|
182
|
+
let foundEl = null;
|
|
183
|
+
for (const root of searchRoots) {
|
|
184
|
+
foundEl = it.selector ? root.querySelector(it.selector) : this;
|
|
185
|
+
if (foundEl) break;
|
|
186
|
+
}
|
|
187
|
+
if (foundEl) {
|
|
188
|
+
let bound = this._boundElements.get(foundEl);
|
|
171
189
|
if (!bound) {
|
|
172
190
|
bound = /* @__PURE__ */ new Set();
|
|
173
|
-
this._boundElements.set(
|
|
191
|
+
this._boundElements.set(foundEl, bound);
|
|
174
192
|
}
|
|
175
193
|
if (!bound.has(it.propertyKey)) {
|
|
176
|
-
this[it.propertyKey](
|
|
194
|
+
this[it.propertyKey](foundEl);
|
|
177
195
|
bound.add(it.propertyKey);
|
|
178
196
|
}
|
|
179
197
|
}
|
|
@@ -182,48 +200,52 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
182
200
|
const queryAllMetadata = (0, import_queryAll.getQueryAllMetadata)(this);
|
|
183
201
|
if (queryAllMetadata) {
|
|
184
202
|
queryAllMetadata.filter((it) => it.isMethod).forEach((it) => {
|
|
185
|
-
const
|
|
186
|
-
const
|
|
187
|
-
|
|
203
|
+
const searchRoots = getSearchRoots(it.options.root);
|
|
204
|
+
const allElements = [];
|
|
205
|
+
searchRoots.forEach((root) => {
|
|
206
|
+
const found = it.selector ? root.querySelectorAll(it.selector) : [this];
|
|
207
|
+
allElements.push(...Array.from(found));
|
|
208
|
+
});
|
|
209
|
+
this[it.propertyKey](allElements);
|
|
188
210
|
});
|
|
189
211
|
}
|
|
190
212
|
const eventListeners = (0, import_addEventListener.getAddEventListenerMetadata)(this);
|
|
191
213
|
if (eventListeners) {
|
|
192
214
|
eventListeners.forEach((it) => {
|
|
193
|
-
const { query, type,
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
215
|
+
const { query, type, root: rootOption, ...options } = it.options;
|
|
216
|
+
const searchRoots = getSearchRoots(rootOption);
|
|
217
|
+
searchRoots.forEach((root) => {
|
|
218
|
+
const targetElements = query ? root.querySelectorAll(query) : [this];
|
|
219
|
+
targetElements.forEach((targetElement) => {
|
|
220
|
+
if (targetElement) {
|
|
221
|
+
let bound = this._boundElements.get(targetElement);
|
|
222
|
+
if (!bound) {
|
|
223
|
+
bound = /* @__PURE__ */ new Set();
|
|
224
|
+
this._boundElements.set(targetElement, bound);
|
|
225
|
+
}
|
|
226
|
+
const eventKey = `event:${String(it.propertyKey)}:${type}`;
|
|
227
|
+
if (!bound.has(eventKey)) {
|
|
228
|
+
const handler = (event) => {
|
|
229
|
+
if (it.options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
230
|
+
if (it.options.stopPropagation) event.stopPropagation();
|
|
231
|
+
if (it.options.preventDefault) event.preventDefault();
|
|
232
|
+
this[it.propertyKey](event, targetElement);
|
|
233
|
+
};
|
|
234
|
+
targetElement.addEventListener(type, handler, options);
|
|
235
|
+
bound.add(eventKey);
|
|
236
|
+
if (config.autoRemoveEventListeners) this._activeListeners.push({ el: targetElement, type, handler, options });
|
|
237
|
+
const addEventMethods = (0, import_lifecycles.getLifecycleMetadata)(this, import_lifecycles.ON_ADD_EVENT_LISTENER_METADATA_KEY);
|
|
238
|
+
addEventMethods?.forEach((m) => {
|
|
239
|
+
if (typeof this[m] === "function") this[m](targetElement, type, handler);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
202
242
|
}
|
|
203
|
-
|
|
204
|
-
if (!bound.has(eventKey)) {
|
|
205
|
-
const handler = (event) => {
|
|
206
|
-
if (it.options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
207
|
-
if (it.options.stopPropagation) event.stopPropagation();
|
|
208
|
-
if (it.options.preventDefault) event.preventDefault();
|
|
209
|
-
this[it.propertyKey](event, targetElement);
|
|
210
|
-
};
|
|
211
|
-
targetElement.addEventListener(type, handler, options);
|
|
212
|
-
bound.add(eventKey);
|
|
213
|
-
if (config.autoRemoveEventListeners) this._activeListeners.push({ el: targetElement, type, handler, options });
|
|
214
|
-
const addEventMethods = (0, import_lifecycles.getLifecycleMetadata)(this, import_lifecycles.ON_ADD_EVENT_LISTENER_METADATA_KEY);
|
|
215
|
-
addEventMethods?.forEach((m) => {
|
|
216
|
-
if (typeof this[m] === "function") this[m](targetElement, type, handler);
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
243
|
+
});
|
|
220
244
|
});
|
|
221
245
|
});
|
|
222
246
|
}
|
|
223
247
|
}
|
|
224
248
|
_buildStateMap() {
|
|
225
|
-
this._stateBindings.clear();
|
|
226
|
-
this._externalSources.clear();
|
|
227
249
|
const scan = (root) => {
|
|
228
250
|
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
|
|
229
251
|
let node = null;
|
|
@@ -232,7 +254,7 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
232
254
|
else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
233
255
|
const el = node;
|
|
234
256
|
const alias = el.getAttribute("as");
|
|
235
|
-
if (alias) {
|
|
257
|
+
if (alias && !this._externalSources.has(alias)) {
|
|
236
258
|
this._externalSources.set(alias, el);
|
|
237
259
|
el.addEventListener(STATE_CHANGE_EVENT, () => this._updateState(alias));
|
|
238
260
|
}
|
|
@@ -244,9 +266,12 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
244
266
|
scan(this);
|
|
245
267
|
}
|
|
246
268
|
_parseAndBind(node, type, owner) {
|
|
247
|
-
const
|
|
269
|
+
const tplKey = `__swc_original_${this._swcId}`;
|
|
270
|
+
const isAlreadyBound = node.__swc_bound_ids?.has(this._swcId);
|
|
271
|
+
const content = node[tplKey] || node.textContent || "";
|
|
248
272
|
const matches = Array.from(content.matchAll(/{{(.*?)}}/g));
|
|
249
273
|
if (matches.length === 0) return;
|
|
274
|
+
if (isAlreadyBound) return;
|
|
250
275
|
matches.forEach((match) => {
|
|
251
276
|
const fullPath = match[1].trim();
|
|
252
277
|
const rootName = fullPath.split(".")[0];
|
|
@@ -256,8 +281,9 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
256
281
|
const isSelfAlias = this.getAttribute("as") === rootName;
|
|
257
282
|
if (!isState && !isLogicKey && !isExternal && !isSelfAlias) return;
|
|
258
283
|
if (!this._stateBindings.has(rootName)) this._stateBindings.set(rootName, []);
|
|
259
|
-
const tplKey = `__swc_original_${this._swcId}`;
|
|
260
284
|
if (!node[tplKey]) node[tplKey] = content;
|
|
285
|
+
if (!node.__swc_bound_ids) node.__swc_bound_ids = /* @__PURE__ */ new Set();
|
|
286
|
+
node.__swc_bound_ids.add(this._swcId);
|
|
261
287
|
this._stateBindings.get(rootName).push({ node, type, owner, path: fullPath });
|
|
262
288
|
this._updateState(rootName);
|
|
263
289
|
});
|
|
@@ -275,7 +301,9 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
275
301
|
const tplKey = `__swc_original_${this._swcId}`;
|
|
276
302
|
bindings.forEach((bin) => {
|
|
277
303
|
let text = bin.node[tplKey];
|
|
304
|
+
if (!text) return;
|
|
278
305
|
const matches = Array.from(text.matchAll(/{{(.*?)}}/g));
|
|
306
|
+
let updatedText = text;
|
|
279
307
|
for (const match of matches) {
|
|
280
308
|
const path = match[1].trim();
|
|
281
309
|
const root = path.split(".")[0];
|
|
@@ -307,14 +335,20 @@ const elementDefine = (inConfig) => (constructor) => {
|
|
|
307
335
|
}
|
|
308
336
|
if (val !== void 0) {
|
|
309
337
|
const strVal = val === null || val === void 0 ? "" : typeof val === "object" ? "[Object]" : String(val);
|
|
310
|
-
|
|
338
|
+
updatedText = updatedText.replace(match[0], strVal);
|
|
311
339
|
if (bin.type === "attribute" && bin.owner) {
|
|
312
|
-
|
|
313
|
-
|
|
340
|
+
const attrName = bin.node.name;
|
|
341
|
+
if (val === null || val === void 0) bin.owner.removeAttribute(attrName);
|
|
342
|
+
else {
|
|
343
|
+
bin.owner.setAttribute(attrName, updatedText);
|
|
344
|
+
if ((attrName === "value" || attrName === "checked") && bin.owner.tagName.match(/INPUT|TEXTAREA|SELECT/)) {
|
|
345
|
+
bin.owner[attrName] = updatedText;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
314
348
|
}
|
|
315
349
|
}
|
|
316
350
|
}
|
|
317
|
-
if (bin.type === "text") bin.node.textContent =
|
|
351
|
+
if (bin.type === "text") bin.node.textContent = updatedText;
|
|
318
352
|
});
|
|
319
353
|
}
|
|
320
354
|
disconnectedCallback() {
|