@wcstack/state 1.6.4 → 1.7.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/README.ja.md +100 -0
- package/README.md +100 -0
- package/dist/index.esm.js +206 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -1015,6 +1015,106 @@ customElements.define("my-component", MyComponent);
|
|
|
1015
1015
|
</template>
|
|
1016
1016
|
```
|
|
1017
1017
|
|
|
1018
|
+
## 宣言的カスタムコンポーネント (DCC)
|
|
1019
|
+
|
|
1020
|
+
JavaScript のクラス定義なしで、**HTML だけ**でカスタム要素を定義できます。`data-wc-definition` と Declarative Shadow DOM (`<template shadowrootmode>`) を使い、リアクティブな状態を持つ再利用可能なコンポーネントをインラインで宣言します。
|
|
1021
|
+
|
|
1022
|
+
### 基本的な定義
|
|
1023
|
+
|
|
1024
|
+
```html
|
|
1025
|
+
<!-- 1. コンポーネントを定義(CSSで非表示) -->
|
|
1026
|
+
<my-counter data-wc-definition>
|
|
1027
|
+
<template shadowrootmode="open">
|
|
1028
|
+
<p>{{ count }}</p>
|
|
1029
|
+
<button data-wcs="onclick: increment">+1</button>
|
|
1030
|
+
<wcs-state>
|
|
1031
|
+
<script type="module">
|
|
1032
|
+
export default {
|
|
1033
|
+
count: 0,
|
|
1034
|
+
increment() { this.count++; },
|
|
1035
|
+
$bindables: ["count"]
|
|
1036
|
+
};
|
|
1037
|
+
</script>
|
|
1038
|
+
</wcs-state>
|
|
1039
|
+
</template>
|
|
1040
|
+
</my-counter>
|
|
1041
|
+
|
|
1042
|
+
<!-- 2. 使う — 各インスタンスが独自の状態を持つ -->
|
|
1043
|
+
<my-counter></my-counter>
|
|
1044
|
+
<my-counter></my-counter>
|
|
1045
|
+
```
|
|
1046
|
+
|
|
1047
|
+
`<wcs-state>` が `data-wc-definition` 付きのホスト内にあることを検出すると:
|
|
1048
|
+
|
|
1049
|
+
1. 状態オブジェクトをロード(`<script type="module">` または `src="*.js"`)
|
|
1050
|
+
2. getter/setter/メソッドをプロトタイプに定義したカスタム要素クラスを生成
|
|
1051
|
+
3. `customElements.define()` で登録
|
|
1052
|
+
|
|
1053
|
+
定義要素は非表示になり、各インスタンスはテンプレートを自身の Shadow DOM にクローンして、独自の `<wcs-state>` を初期化します。
|
|
1054
|
+
|
|
1055
|
+
### 推奨 CSS
|
|
1056
|
+
|
|
1057
|
+
```css
|
|
1058
|
+
:not(:defined) { display: none; }
|
|
1059
|
+
[data-wc-definition] { display: none; }
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
### `$bindables` と wc-bindable プロトコル
|
|
1063
|
+
|
|
1064
|
+
`$bindables` 配列は、変更イベント付きのコンポーネントプロパティとして公開する状態プロパティを宣言します。[wc-bindable プロトコル](https://github.com/nicenemo/nicenemo/blob/main/docs/wc-bindable-protocol.md)に準拠しています:
|
|
1065
|
+
|
|
1066
|
+
```javascript
|
|
1067
|
+
export default {
|
|
1068
|
+
count: 0,
|
|
1069
|
+
increment() { this.count++; },
|
|
1070
|
+
$bindables: ["count"]
|
|
1071
|
+
};
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
これにより以下が生成されます:
|
|
1075
|
+
|
|
1076
|
+
- クラスの `static wcBindable` — フレームワークアダプタ用のプロトコルメタデータ
|
|
1077
|
+
- プロトタイプの getter/setter — リアクティブプロキシ経由で読み書き
|
|
1078
|
+
- `CustomEvent` のディスパッチ — 値が変更されるたびに `my-counter:count-changed` が発火
|
|
1079
|
+
|
|
1080
|
+
### DCC プロパティへのバインディング
|
|
1081
|
+
|
|
1082
|
+
他の `<wcs-state>` インスタンスから、通常の Web Component と同じように DCC プロパティにバインドできます:
|
|
1083
|
+
|
|
1084
|
+
```html
|
|
1085
|
+
<my-counter data-wcs="count: parentCount"></my-counter>
|
|
1086
|
+
|
|
1087
|
+
<wcs-state>
|
|
1088
|
+
<script type="module">
|
|
1089
|
+
export default { parentCount: 0 };
|
|
1090
|
+
</script>
|
|
1091
|
+
</wcs-state>
|
|
1092
|
+
<div data-wcs="textContent: parentCount"></div>
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
### Shadow Root モード
|
|
1096
|
+
|
|
1097
|
+
`open` と `closed` の両モードに対応しています:
|
|
1098
|
+
|
|
1099
|
+
```html
|
|
1100
|
+
<my-component data-wc-definition>
|
|
1101
|
+
<template shadowrootmode="closed">
|
|
1102
|
+
<!-- closed shadow DOM -->
|
|
1103
|
+
</template>
|
|
1104
|
+
</my-component>
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
### 内部プロパティ
|
|
1108
|
+
|
|
1109
|
+
`$` プレフィックス付きのプロパティは内部用で、コンポーネントのプロトタイプには公開されません:
|
|
1110
|
+
|
|
1111
|
+
| プロパティ | 用途 |
|
|
1112
|
+
|----------|---------|
|
|
1113
|
+
| `$bindables` | 観測可能プロパティの宣言 |
|
|
1114
|
+
| `$connectedCallback` | ライフサイクルフック(各インスタンスで実行) |
|
|
1115
|
+
| `$disconnectedCallback` | クリーンアップフック |
|
|
1116
|
+
| `$updatedCallback` | 状態変更後に呼ばれる |
|
|
1117
|
+
|
|
1018
1118
|
## SVG サポート
|
|
1019
1119
|
|
|
1020
1120
|
全てのバインディングが `<svg>` 要素内で動作します。SVG 属性には `attr.*` を使用します:
|
package/README.md
CHANGED
|
@@ -1015,6 +1015,106 @@ customElements.define("my-component", MyComponent);
|
|
|
1015
1015
|
</template>
|
|
1016
1016
|
```
|
|
1017
1017
|
|
|
1018
|
+
## Declarative Custom Components (DCC)
|
|
1019
|
+
|
|
1020
|
+
Define custom elements **entirely in HTML** — no JavaScript class definition needed. Using `data-wc-definition` and Declarative Shadow DOM (`<template shadowrootmode>`), you can declare reusable components with reactive state inline.
|
|
1021
|
+
|
|
1022
|
+
### Basic Definition
|
|
1023
|
+
|
|
1024
|
+
```html
|
|
1025
|
+
<!-- 1. Define the component (hidden by CSS) -->
|
|
1026
|
+
<my-counter data-wc-definition>
|
|
1027
|
+
<template shadowrootmode="open">
|
|
1028
|
+
<p>{{ count }}</p>
|
|
1029
|
+
<button data-wcs="onclick: increment">+1</button>
|
|
1030
|
+
<wcs-state>
|
|
1031
|
+
<script type="module">
|
|
1032
|
+
export default {
|
|
1033
|
+
count: 0,
|
|
1034
|
+
increment() { this.count++; },
|
|
1035
|
+
$bindables: ["count"]
|
|
1036
|
+
};
|
|
1037
|
+
</script>
|
|
1038
|
+
</wcs-state>
|
|
1039
|
+
</template>
|
|
1040
|
+
</my-counter>
|
|
1041
|
+
|
|
1042
|
+
<!-- 2. Use it — each instance gets its own state -->
|
|
1043
|
+
<my-counter></my-counter>
|
|
1044
|
+
<my-counter></my-counter>
|
|
1045
|
+
```
|
|
1046
|
+
|
|
1047
|
+
When `<wcs-state>` detects it is inside a `data-wc-definition` host, it:
|
|
1048
|
+
|
|
1049
|
+
1. Loads the state object (from `<script type="module">` or `src="*.js"`)
|
|
1050
|
+
2. Generates a custom element class with getter/setter/method properties on the prototype
|
|
1051
|
+
3. Registers it via `customElements.define()`
|
|
1052
|
+
|
|
1053
|
+
The definition element is hidden; each instance clones the template into its own Shadow DOM and initializes its own `<wcs-state>`.
|
|
1054
|
+
|
|
1055
|
+
### Recommended CSS
|
|
1056
|
+
|
|
1057
|
+
```css
|
|
1058
|
+
:not(:defined) { display: none; }
|
|
1059
|
+
[data-wc-definition] { display: none; }
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
### `$bindables` and wc-bindable Protocol
|
|
1063
|
+
|
|
1064
|
+
The `$bindables` array declares which state properties are exposed as component properties with change events, following the [wc-bindable protocol](https://github.com/nicenemo/nicenemo/blob/main/docs/wc-bindable-protocol.md):
|
|
1065
|
+
|
|
1066
|
+
```javascript
|
|
1067
|
+
export default {
|
|
1068
|
+
count: 0,
|
|
1069
|
+
increment() { this.count++; },
|
|
1070
|
+
$bindables: ["count"]
|
|
1071
|
+
};
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
This generates:
|
|
1075
|
+
|
|
1076
|
+
- `static wcBindable` on the class — protocol metadata for framework adapters
|
|
1077
|
+
- Getter/setter on the prototype — reads/writes go through the reactive proxy
|
|
1078
|
+
- `CustomEvent` dispatch — `my-counter:count-changed` fires on every mutation
|
|
1079
|
+
|
|
1080
|
+
### Binding to DCC Properties
|
|
1081
|
+
|
|
1082
|
+
Other `<wcs-state>` instances can bind to DCC properties just like any Web Component:
|
|
1083
|
+
|
|
1084
|
+
```html
|
|
1085
|
+
<my-counter data-wcs="count: parentCount"></my-counter>
|
|
1086
|
+
|
|
1087
|
+
<wcs-state>
|
|
1088
|
+
<script type="module">
|
|
1089
|
+
export default { parentCount: 0 };
|
|
1090
|
+
</script>
|
|
1091
|
+
</wcs-state>
|
|
1092
|
+
<div data-wcs="textContent: parentCount"></div>
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
### Shadow Root Mode
|
|
1096
|
+
|
|
1097
|
+
Both `open` and `closed` modes are supported:
|
|
1098
|
+
|
|
1099
|
+
```html
|
|
1100
|
+
<my-component data-wc-definition>
|
|
1101
|
+
<template shadowrootmode="closed">
|
|
1102
|
+
<!-- closed shadow DOM -->
|
|
1103
|
+
</template>
|
|
1104
|
+
</my-component>
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
### Internal Properties
|
|
1108
|
+
|
|
1109
|
+
Properties prefixed with `$` are internal and not exposed on the component prototype:
|
|
1110
|
+
|
|
1111
|
+
| Property | Purpose |
|
|
1112
|
+
|----------|---------|
|
|
1113
|
+
| `$bindables` | Declares observable properties |
|
|
1114
|
+
| `$connectedCallback` | Lifecycle hook (runs on each instance) |
|
|
1115
|
+
| `$disconnectedCallback` | Cleanup hook |
|
|
1116
|
+
| `$updatedCallback` | Called after state mutations |
|
|
1117
|
+
|
|
1018
1118
|
## SVG Support
|
|
1019
1119
|
|
|
1020
1120
|
All bindings work inside `<svg>` elements. Use `attr.*` for SVG attributes:
|
package/dist/index.esm.js
CHANGED
|
@@ -59,7 +59,7 @@ function setConfig(partialConfig) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
var version$1 = "1.
|
|
62
|
+
var version$1 = "1.7.0";
|
|
63
63
|
var pkg = {
|
|
64
64
|
version: version$1};
|
|
65
65
|
|
|
@@ -186,6 +186,8 @@ const STATE_CONNECTED_CALLBACK_NAME = "$connectedCallback";
|
|
|
186
186
|
const STATE_DISCONNECTED_CALLBACK_NAME = "$disconnectedCallback";
|
|
187
187
|
const STATE_UPDATED_CALLBACK_NAME = "$updatedCallback";
|
|
188
188
|
const WEBCOMPONENT_STATE_READY_CALLBACK_NAME = "$stateReadyCallback";
|
|
189
|
+
const STATE_BINDABLES_NAME = "$bindables";
|
|
190
|
+
const DCC_DEFINITION_ATTRIBUTE = "data-wc-definition";
|
|
189
191
|
|
|
190
192
|
const _cache$4 = new Map();
|
|
191
193
|
let id = 0;
|
|
@@ -4819,6 +4821,153 @@ function createLoopContextStack() {
|
|
|
4819
4821
|
return new LoopContextStack();
|
|
4820
4822
|
}
|
|
4821
4823
|
|
|
4824
|
+
function getterFn(name) {
|
|
4825
|
+
return function () {
|
|
4826
|
+
const stateEl = this.stateElement;
|
|
4827
|
+
if (!stateEl)
|
|
4828
|
+
return undefined;
|
|
4829
|
+
let value;
|
|
4830
|
+
try {
|
|
4831
|
+
stateEl.createState("readonly", (state) => {
|
|
4832
|
+
value = state[name];
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
catch {
|
|
4836
|
+
return undefined;
|
|
4837
|
+
}
|
|
4838
|
+
return value;
|
|
4839
|
+
};
|
|
4840
|
+
}
|
|
4841
|
+
function setterFn(name) {
|
|
4842
|
+
return function (value) {
|
|
4843
|
+
const stateEl = this.stateElement;
|
|
4844
|
+
if (!stateEl)
|
|
4845
|
+
return;
|
|
4846
|
+
stateEl.initializePromise.then(() => {
|
|
4847
|
+
stateEl.createState("writable", (state) => {
|
|
4848
|
+
state[name] = value;
|
|
4849
|
+
});
|
|
4850
|
+
});
|
|
4851
|
+
};
|
|
4852
|
+
}
|
|
4853
|
+
function callFn(name, isAsync) {
|
|
4854
|
+
if (isAsync) {
|
|
4855
|
+
return function (...args) {
|
|
4856
|
+
const stateEl = this.stateElement;
|
|
4857
|
+
if (!stateEl)
|
|
4858
|
+
return;
|
|
4859
|
+
return stateEl.initializePromise.then(() => {
|
|
4860
|
+
return stateEl.createStateAsync("writable", async (state) => {
|
|
4861
|
+
await state[name](...args);
|
|
4862
|
+
});
|
|
4863
|
+
});
|
|
4864
|
+
};
|
|
4865
|
+
}
|
|
4866
|
+
return function (...args) {
|
|
4867
|
+
const stateEl = this.stateElement;
|
|
4868
|
+
if (!stateEl)
|
|
4869
|
+
return;
|
|
4870
|
+
stateEl.initializePromise.then(() => {
|
|
4871
|
+
stateEl.createState("writable", (state) => {
|
|
4872
|
+
state[name](...args);
|
|
4873
|
+
});
|
|
4874
|
+
});
|
|
4875
|
+
};
|
|
4876
|
+
}
|
|
4877
|
+
function isInternalProperty(name) {
|
|
4878
|
+
return name.startsWith("$");
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4881
|
+
function createWcBindable(tagName, bindables) {
|
|
4882
|
+
const properties = bindables.map((propName) => ({
|
|
4883
|
+
name: propName,
|
|
4884
|
+
event: `${tagName}:${propName}-changed`,
|
|
4885
|
+
}));
|
|
4886
|
+
return {
|
|
4887
|
+
protocol: "wc-bindable",
|
|
4888
|
+
version: 1,
|
|
4889
|
+
properties,
|
|
4890
|
+
};
|
|
4891
|
+
}
|
|
4892
|
+
function createBindableEventMap(tagName, bindables) {
|
|
4893
|
+
const map = {};
|
|
4894
|
+
for (const propName of bindables) {
|
|
4895
|
+
map[propName] = `${tagName}:${propName}-changed`;
|
|
4896
|
+
}
|
|
4897
|
+
return map;
|
|
4898
|
+
}
|
|
4899
|
+
|
|
4900
|
+
function defineDCC(hostElement, shadowRoot, state) {
|
|
4901
|
+
const tagName = hostElement.tagName.toLowerCase();
|
|
4902
|
+
// バリデーション
|
|
4903
|
+
if (!tagName.includes("-")) {
|
|
4904
|
+
raiseError(`DCC: "${tagName}" is not a valid custom element name (must contain a hyphen).`);
|
|
4905
|
+
}
|
|
4906
|
+
if (customElements.get(tagName)) {
|
|
4907
|
+
// 既に登録済みならスキップ
|
|
4908
|
+
return;
|
|
4909
|
+
}
|
|
4910
|
+
// ShadowRoot は cloneNode 不可のため、template 経由で内容をクローン
|
|
4911
|
+
const template = document.createElement("template");
|
|
4912
|
+
template.innerHTML = shadowRoot.innerHTML;
|
|
4913
|
+
const shadowRootMode = shadowRoot.mode;
|
|
4914
|
+
// $bindables から wcBindable + bindableEventMap を生成
|
|
4915
|
+
const bindables = Array.isArray(state[STATE_BINDABLES_NAME])
|
|
4916
|
+
? state[STATE_BINDABLES_NAME]
|
|
4917
|
+
: [];
|
|
4918
|
+
const wcBindable = bindables.length > 0
|
|
4919
|
+
? createWcBindable(tagName, bindables)
|
|
4920
|
+
: null;
|
|
4921
|
+
const bindableEventMap = bindables.length > 0
|
|
4922
|
+
? createBindableEventMap(tagName, bindables)
|
|
4923
|
+
: {};
|
|
4924
|
+
// DCC クラス生成
|
|
4925
|
+
const stateTagSelector = `${config.tagNames.state}:not([name])`;
|
|
4926
|
+
const DCCElement = class extends HTMLElement {
|
|
4927
|
+
static template = template;
|
|
4928
|
+
static shadowRootMode = shadowRootMode;
|
|
4929
|
+
static wcBindable = wcBindable;
|
|
4930
|
+
static bindableEventMap = bindableEventMap;
|
|
4931
|
+
_shadow = null;
|
|
4932
|
+
connectedCallback() {
|
|
4933
|
+
if (this.hasAttribute(DCC_DEFINITION_ATTRIBUTE))
|
|
4934
|
+
return;
|
|
4935
|
+
this._shadow = this.attachShadow({ mode: DCCElement.shadowRootMode });
|
|
4936
|
+
this._shadow.appendChild(DCCElement.template.content.cloneNode(true));
|
|
4937
|
+
// bindableEventMap の設定
|
|
4938
|
+
if (Object.keys(DCCElement.bindableEventMap).length > 0) {
|
|
4939
|
+
const stateEl = this._shadow.querySelector(stateTagSelector);
|
|
4940
|
+
if (stateEl) {
|
|
4941
|
+
stateEl.initializePromise.then(() => {
|
|
4942
|
+
stateEl.setBindableEventMap(DCCElement.bindableEventMap);
|
|
4943
|
+
});
|
|
4944
|
+
}
|
|
4945
|
+
}
|
|
4946
|
+
}
|
|
4947
|
+
get stateElement() {
|
|
4948
|
+
return this._shadow?.querySelector(stateTagSelector);
|
|
4949
|
+
}
|
|
4950
|
+
};
|
|
4951
|
+
// state プロパティを走査して DCC クラスのプロトタイプにgetter/setter/methodを定義
|
|
4952
|
+
const descriptors = Object.getOwnPropertyDescriptors(state);
|
|
4953
|
+
for (const [name, desc] of Object.entries(descriptors)) {
|
|
4954
|
+
if (isInternalProperty(name))
|
|
4955
|
+
continue;
|
|
4956
|
+
const newDesc = { configurable: true, enumerable: true };
|
|
4957
|
+
if (typeof desc.value === "function") {
|
|
4958
|
+
const isAsync = desc.value.constructor?.name === "AsyncFunction";
|
|
4959
|
+
newDesc.value = callFn(name, isAsync);
|
|
4960
|
+
}
|
|
4961
|
+
else {
|
|
4962
|
+
newDesc.get = getterFn(name);
|
|
4963
|
+
newDesc.set = setterFn(name);
|
|
4964
|
+
}
|
|
4965
|
+
Object.defineProperty(DCCElement.prototype, name, newDesc);
|
|
4966
|
+
}
|
|
4967
|
+
// カスタム要素登録
|
|
4968
|
+
customElements.define(tagName, DCCElement);
|
|
4969
|
+
}
|
|
4970
|
+
|
|
4822
4971
|
/**
|
|
4823
4972
|
* Cache for resolved path information.
|
|
4824
4973
|
* Uses Map to safely handle property names including reserved words like "constructor" and "toString".
|
|
@@ -5470,6 +5619,17 @@ function setByAddress(target, address, value, receiver, handler) {
|
|
|
5470
5619
|
dirty: false
|
|
5471
5620
|
});
|
|
5472
5621
|
}
|
|
5622
|
+
// DCC bindable イベントディスパッチ
|
|
5623
|
+
const eventName = stateElement.bindableEventMap[address.pathInfo.path];
|
|
5624
|
+
if (eventName) {
|
|
5625
|
+
const rootNode = stateElement.rootNode;
|
|
5626
|
+
if (rootNode instanceof ShadowRoot) {
|
|
5627
|
+
rootNode.host.dispatchEvent(new CustomEvent(eventName, {
|
|
5628
|
+
detail: value,
|
|
5629
|
+
bubbles: true,
|
|
5630
|
+
}));
|
|
5631
|
+
}
|
|
5632
|
+
}
|
|
5473
5633
|
}
|
|
5474
5634
|
}
|
|
5475
5635
|
|
|
@@ -6469,6 +6629,7 @@ class State extends HTMLElement {
|
|
|
6469
6629
|
_rootNode = null;
|
|
6470
6630
|
_boundComponent = null;
|
|
6471
6631
|
_boundComponentStateProp = null;
|
|
6632
|
+
_bindableEventMap = {};
|
|
6472
6633
|
constructor() {
|
|
6473
6634
|
super();
|
|
6474
6635
|
this._initializePromise = new Promise((resolve) => {
|
|
@@ -6627,6 +6788,37 @@ class State extends HTMLElement {
|
|
|
6627
6788
|
}
|
|
6628
6789
|
});
|
|
6629
6790
|
}
|
|
6791
|
+
async _initializeDCC(hostElement, shadowRoot) {
|
|
6792
|
+
let state;
|
|
6793
|
+
try {
|
|
6794
|
+
if (this.hasAttribute('src')) {
|
|
6795
|
+
const src = this.getAttribute('src');
|
|
6796
|
+
if (src.endsWith('.js')) {
|
|
6797
|
+
state = await loadFromScriptFile(src);
|
|
6798
|
+
}
|
|
6799
|
+
else {
|
|
6800
|
+
raiseError(`DCC: Unsupported src type: ${src}`);
|
|
6801
|
+
}
|
|
6802
|
+
}
|
|
6803
|
+
else {
|
|
6804
|
+
const script = this.querySelector('script[type="module"]');
|
|
6805
|
+
if (script) {
|
|
6806
|
+
state = await loadFromInnerScript(script, hostElement.tagName.toLowerCase());
|
|
6807
|
+
}
|
|
6808
|
+
else {
|
|
6809
|
+
raiseError(`DCC: No state source found for "${hostElement.tagName.toLowerCase()}".`);
|
|
6810
|
+
}
|
|
6811
|
+
}
|
|
6812
|
+
}
|
|
6813
|
+
catch (e) {
|
|
6814
|
+
raiseError(`DCC: Failed to load state: ${e}`);
|
|
6815
|
+
}
|
|
6816
|
+
defineDCC(hostElement, shadowRoot, state);
|
|
6817
|
+
this._initialized = true;
|
|
6818
|
+
this._rootNode = null; // disconnectedCallbackでのstate参照を防止
|
|
6819
|
+
this._resolveInitialize?.();
|
|
6820
|
+
this._resolveConnectedCallback?.();
|
|
6821
|
+
}
|
|
6630
6822
|
_callStateDisconnectedCallback() {
|
|
6631
6823
|
this.createState("writable", (state) => {
|
|
6632
6824
|
// stateに"$disconnectedCallback"があるか確認し、disconnectedCallbackAPIを呼び出す
|
|
@@ -6638,6 +6830,13 @@ class State extends HTMLElement {
|
|
|
6638
6830
|
async connectedCallback() {
|
|
6639
6831
|
this._rootNode = this.getRootNode();
|
|
6640
6832
|
if (!this._initialized) {
|
|
6833
|
+
// DCC 検出: ShadowRoot 内かつホストに data-wc-definition がある場合
|
|
6834
|
+
const parentNode = this.parentNode;
|
|
6835
|
+
if (parentNode instanceof ShadowRoot &&
|
|
6836
|
+
parentNode.host.hasAttribute(DCC_DEFINITION_ATTRIBUTE)) {
|
|
6837
|
+
await this._initializeDCC(parentNode.host, parentNode);
|
|
6838
|
+
return;
|
|
6839
|
+
}
|
|
6641
6840
|
await this._initializeBindWebComponent();
|
|
6642
6841
|
await this._initialize();
|
|
6643
6842
|
this._initialized = true;
|
|
@@ -6707,6 +6906,12 @@ class State extends HTMLElement {
|
|
|
6707
6906
|
get boundComponentStateProp() {
|
|
6708
6907
|
return this._boundComponentStateProp;
|
|
6709
6908
|
}
|
|
6909
|
+
get bindableEventMap() {
|
|
6910
|
+
return this._bindableEventMap;
|
|
6911
|
+
}
|
|
6912
|
+
setBindableEventMap(map) {
|
|
6913
|
+
this._bindableEventMap = map;
|
|
6914
|
+
}
|
|
6710
6915
|
_addDependency(map, sourcePath, targetPath) {
|
|
6711
6916
|
const deps = map.get(sourcePath);
|
|
6712
6917
|
if (deps === undefined) {
|