@wcstack/upload 4.8.0 → 4.9.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 +29 -1
- package/README.md +29 -1
- package/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.esm.js +90 -1
- package/dist/index.esm.js.map +1 -1
- package/package.json +2 -1
package/README.ja.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
- 入力 / コマンドサーフェス: `files`, `trigger`
|
|
13
13
|
- 設定サーフェス: `url`, `method`, `field-name`, `accept`, `max-size`, `manual`, `multiple`
|
|
14
|
+
- リクエストヘッダ: 子要素の `<wcs-upload-header>`(4.9 から。[`<wcs-upload-header>`](#wcs-upload-header) を参照)
|
|
14
15
|
- 出力ステートサーフェス: `value`, `loading`, `progress`, `error`, `status`
|
|
15
16
|
|
|
16
17
|
つまり、ファイルアップロードを場当たり的な `XMLHttpRequest` のグルーコードではなく、状態遷移と DOM バインディングとして扱えます。
|
|
@@ -234,6 +235,32 @@ npm install @wcstack/upload
|
|
|
234
235
|
|
|
235
236
|
現在のリクエストを中断します。loading の解除はリクエストの abort 経路を通じて行われます(`@wcstack/fetch` と一貫)。
|
|
236
237
|
|
|
238
|
+
### `<wcs-upload-header>`
|
|
239
|
+
|
|
240
|
+
4.9 から、アップロードのリクエストヘッダを定義します。`<wcs-fetch>` の中の `<wcs-fetch-header>` と同じく、`<wcs-upload>` の子要素として置きます。アップロードを始めるときに読まれます。(それまでの `<wcs-upload>` はヘッダを送れません。4.8 では `UploadCore` に `headers` を渡してください — [Headless API](#headless-api) を参照。)
|
|
241
|
+
|
|
242
|
+
| 属性 / プロパティ | 型 | 説明 |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `name` | `string` | ヘッダ名 |
|
|
245
|
+
| `value` | `string` | ヘッダ値。`value` 属性が無ければヘッダは送らない(空の `value=""` は送る) |
|
|
246
|
+
|
|
247
|
+
`name` と `value` はプロパティでもあり、属性へ反映します(`null` は属性を外し、`undefined` はマークアップの値に戻す)。だからヘッダを state から渡せます — 毎回ベアラートークンを求める API:
|
|
248
|
+
|
|
249
|
+
```html
|
|
250
|
+
<wcs-upload id="receipt-upload" url="/api/receipts" manual data-wcs="value: receipt">
|
|
251
|
+
<wcs-upload-header name="Authorization" data-wcs="value: authHeader"></wcs-upload-header>
|
|
252
|
+
</wcs-upload>
|
|
253
|
+
<!-- get authHeader() { return this.token ? `Bearer ${this.token}` : null; } -->
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
`authHeader` が `null` の間、アップロードは `Authorization` ヘッダ無しで出ます。ヘッダは要素の接続時ではなく、アップロードを始めるとき — 自動送信での `files` の代入、`trigger`、`upload()` — に読むので、後から届いたトークンも次のアップロードで送られます。
|
|
257
|
+
|
|
258
|
+
`Content-Type` のヘッダは付けないでください。アップロードは `multipart/form-data` で送り、手で付けた `Content-Type` はブラウザが付ける境界(boundary)を落とすので、サーバーは各パートを読めません。`<wcs-upload>` は書かれたとおりに送り、警告します。
|
|
259
|
+
|
|
260
|
+
`<wcs-upload-header>` は `wcBindable` を宣言しません。`<wcs-upload>` のマークアップの一部で、それ自体は I/O ノードではありません(`value:` の束縛はそのプロパティを書きます)。
|
|
261
|
+
|
|
262
|
+
**タグを自分で定義するとき。** `@wcstack/upload/auto` は 2 つのタグをどちらも定義します。タグを自分で定義するページ — autoloader の包みのモジュールや、スコープ付きのレジストリ — は `<wcs-upload-header>` も定義する必要があります。パッケージはそのクラス `WcsUploadHeader` を `WcsUpload` と並べて出します。定義されていない `<wcs-upload-header>` は素の要素で、そのヘッダは送られません。そのとき `<wcs-upload>` が 1 回警告します(`[wcs/upload-helper-undefined]`)。autoloader では、`/auto` を読み込む包みが 2 つのタグをまとめて定義します([autoloader の README](../autoloader/README.ja.md#wcstack-自身のタグを読み込む))。
|
|
263
|
+
|
|
237
264
|
## イベント
|
|
238
265
|
|
|
239
266
|
| イベント | `detail` | 説明 |
|
|
@@ -423,10 +450,11 @@ bootstrapUpload({
|
|
|
423
450
|
triggerAttribute: "data-uploadtarget",
|
|
424
451
|
tagNames: {
|
|
425
452
|
upload: "wcs-upload",
|
|
453
|
+
uploadHeader: "wcs-upload-header",
|
|
426
454
|
},
|
|
427
455
|
});
|
|
428
456
|
```
|
|
429
457
|
|
|
430
|
-
`@wcstack/upload/auto`
|
|
458
|
+
`@wcstack/upload/auto` に頼らず、タグ名やトリガー属性名をカスタマイズしたい場合に使います。`tagNames.uploadHeader` は `<wcs-upload-header>` のタグ名です(4.9 から。4.8 はこのキーを拒みます)。
|
|
431
459
|
|
|
432
460
|
`bootstrapUpload()` は、持っていないオプション、既定値と型の違う値(`null` や、オブジェクトの所の配列を含む)、定義していない `tagNames` のキー、文字列でないタグ名で例外を投げます。当てる前にすべてのオプションを確かめるので、投げたときは何も当てません。値が `undefined` のオプションは飛ばします。
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ With `@wcstack/state`, `<wcs-upload>` exposes a small async state surface:
|
|
|
11
11
|
|
|
12
12
|
- input / command surface: `files`, `trigger`
|
|
13
13
|
- configuration surface: `url`, `method`, `field-name`, `accept`, `max-size`, `manual`, `multiple`
|
|
14
|
+
- request headers: `<wcs-upload-header>` children (since 4.9; see [`<wcs-upload-header>`](#wcs-upload-header))
|
|
14
15
|
- output state surface: `value`, `loading`, `progress`, `error`, `status`
|
|
15
16
|
|
|
16
17
|
This means file upload can be expressed as state transitions and DOM bindings instead of ad-hoc `XMLHttpRequest` glue code.
|
|
@@ -234,6 +235,32 @@ Because `null` is also a valid resolved value, do not use the resolved value to
|
|
|
234
235
|
|
|
235
236
|
Aborts the current request. Loading is cleared through the request's abort path (consistent with `@wcstack/fetch`).
|
|
236
237
|
|
|
238
|
+
### `<wcs-upload-header>`
|
|
239
|
+
|
|
240
|
+
Since 4.9, a request header of the upload: place it as a child of `<wcs-upload>`, as `<wcs-fetch-header>` sits in `<wcs-fetch>`. It is read when an upload starts. (Before, `<wcs-upload>` sent no header; on 4.8, call `UploadCore` with `headers` — see [Headless API](#headless-api).)
|
|
241
|
+
|
|
242
|
+
| Attribute / property | Type | Description |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `name` | `string` | Header name |
|
|
245
|
+
| `value` | `string` | Header value. Without a `value` attribute the header is not sent (an empty `value=""` is) |
|
|
246
|
+
|
|
247
|
+
`name` and `value` are also properties, reflected to the attributes (`null` removes the attribute, `undefined` restores the one in the markup), so a header can come from state — an API that wants a bearer token on every request:
|
|
248
|
+
|
|
249
|
+
```html
|
|
250
|
+
<wcs-upload id="receipt-upload" url="/api/receipts" manual data-wcs="value: receipt">
|
|
251
|
+
<wcs-upload-header name="Authorization" data-wcs="value: authHeader"></wcs-upload-header>
|
|
252
|
+
</wcs-upload>
|
|
253
|
+
<!-- get authHeader() { return this.token ? `Bearer ${this.token}` : null; } -->
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
While `authHeader` is `null` an upload goes out with no `Authorization` header at all. The headers are read when the upload starts — a `files` assignment in automatic mode, `trigger`, `upload()` — not when the element connects, so a token that arrives later goes out with the next upload.
|
|
257
|
+
|
|
258
|
+
Do not add a `Content-Type` header: an upload is sent as `multipart/form-data`, and a manual `Content-Type` drops the boundary the browser adds, so the server cannot read the parts. `<wcs-upload>` sends it as written and warns.
|
|
259
|
+
|
|
260
|
+
`<wcs-upload-header>` declares no `wcBindable`: it is part of `<wcs-upload>`'s markup, not an I/O node of its own (a `value:` binding writes its property).
|
|
261
|
+
|
|
262
|
+
**Defining the tags yourself.** `@wcstack/upload/auto` defines both tags. A page that defines them itself — an autoloader's wrapper module, a scoped registry — has to define `<wcs-upload-header>` too: the package exports its class, `WcsUploadHeader`, beside `WcsUpload`. An undefined `<wcs-upload-header>` is a plain element, and its header is not sent; `<wcs-upload>` then warns once (`[wcs/upload-helper-undefined]`). For the autoloader, a wrapper that imports `/auto` defines both tags at once ([autoloader README](../autoloader/README.md#loading-wcstacks-own-tags)).
|
|
263
|
+
|
|
237
264
|
## Events
|
|
238
265
|
|
|
239
266
|
| Event | `detail` | Description |
|
|
@@ -425,10 +452,11 @@ bootstrapUpload({
|
|
|
425
452
|
triggerAttribute: "data-uploadtarget",
|
|
426
453
|
tagNames: {
|
|
427
454
|
upload: "wcs-upload",
|
|
455
|
+
uploadHeader: "wcs-upload-header",
|
|
428
456
|
},
|
|
429
457
|
});
|
|
430
458
|
```
|
|
431
459
|
|
|
432
|
-
Use this when you want to customize the tag name or trigger attribute instead of relying on `@wcstack/upload/auto`.
|
|
460
|
+
Use this when you want to customize the tag name or trigger attribute instead of relying on `@wcstack/upload/auto`. `tagNames.uploadHeader` names `<wcs-upload-header>` (since 4.9; 4.8 refuses the key).
|
|
433
461
|
|
|
434
462
|
`bootstrapUpload()` throws on an option it does not have, on a value whose type differs from the option's default (`null`, or an array where an object is expected, included), and on a `tagNames` key it does not define or a tag name that is not a string. It checks every option before applying any, so nothing is applied when it throws. An option whose value is `undefined` is skipped.
|
package/dist/auto.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const t={triggerAttribute:"data-uploadtarget",tagNames:{upload:"wcs-upload"}};class e{laneKey;policy;_ownerGeneration=0;_latestEpoch=0;_nextOperationId=1;_activeOperationId=void 0;_activeOperationIds=new Set;_queue=[];_inFlightCount=0;_terminal=new Map;_claimedOutcome=new Map;_controllers=new Map;_attempts=new Map;_withSignal;_trace;constructor(t,e,i={}){this.laneKey=t,this.policy=e,this._withSignal=i.withSignal??!1,this._trace=i.trace}get ownerGeneration(){return this._ownerGeneration}get inFlightCount(){return this._inFlightCount}get latestEpoch(){return this._latestEpoch}get activeOperationId(){return this._activeOperationId}begin(){let t;switch(this.policy){case"latest":t=++this._latestEpoch,void 0!==this._activeOperationId&&this._abortController(this._activeOperationId);break;case"exhaust":if(void 0!==this._activeOperationId)return null}const e=this._nextOperationId++,i={operationId:e,ownerGeneration:this._ownerGeneration,laneKey:this.laneKey,policy:this.policy,supersedeEpoch:t};switch(this.policy){case"latest":case"exhaust":this._activeOperationId=e;break;case"queue":this._queue.push(i),void 0===this._activeOperationId&&(this._activeOperationId=e);break;case"overlap":this._activeOperationIds.add(e)}this._inFlightCount+=1,this._attempts.set(e,1);const s=this._makeAttempt(e,1);return void 0!==this._trace&&this._trace({type:"io:operation-started",operationId:e,laneKey:this.laneKey,policy:this.policy}),{ticket:i,attempt:s}}retry(t){if(t.ownerGeneration!==this._ownerGeneration)return null;if(this._terminal.has(t.operationId))return null;const e=this._attempts.get(t.operationId);if(void 0===e)return null;const i=e+1;this._attempts.set(t.operationId,i),this._releaseController(t.operationId);const s=this._makeAttempt(t.operationId,i);return void 0!==this._trace&&this._trace({type:"io:operation-retried",operationId:t.operationId,laneKey:this.laneKey,attempt:i}),s}canCommit(t){if(t.ownerGeneration!==this._ownerGeneration)return!1;const e=this._terminal.get(t.operationId);return(void 0===e||"committing"===e)&&this._isEligible(t)}claimTerminal(t,e){return t.ownerGeneration===this._ownerGeneration&&(!this._terminal.has(t.operationId)&&(!!this._isEligible(t)&&(this._terminal.set(t.operationId,"committing"),this._claimedOutcome.set(t.operationId,e),!0)))}claimedOutcome(t){return this._claimedOutcome.get(t.operationId)}finalize(t){const e=t.operationId,i=this._terminal.get(e);if(void 0!==i&&"committing"!==i)return;let s;s="committing"===i?this._claimedOutcome.get(e)??"stale":"stale",this._terminal.set(e,s),this._claimedOutcome.delete(e),this._releaseController(e),this._attempts.delete(e),this._inFlightCount>0&&(this._inFlightCount-=1),this._advanceBookkeeping(e),void 0!==this._trace&&("stale"===s?this._trace({type:"io:stale-dropped",operationId:e,laneKey:this.laneKey}):this._trace({type:"io:operation-settled",operationId:e,laneKey:this.laneKey,outcome:s}))}signalOf(t){return this._controllers.get(t.operationId)?.signal}abort(t){this._abortController(t.operationId)}abortActive(){void 0!==this._activeOperationId&&this._abortController(this._activeOperationId);for(const t of this._activeOperationIds)this._abortController(t)}disposeOwner(){this._ownerGeneration+=1;for(const t of Array.from(this._controllers.keys()))this._abortController(t),this._releaseController(t);for(const t of Array.from(this._attempts.keys()))this._terminal.has(t)||this._terminal.set(t,"stale"),this._claimedOutcome.delete(t),this._attempts.delete(t),void 0!==this._trace&&this._trace({type:"io:stale-dropped",operationId:t,laneKey:this.laneKey});this._activeOperationId=void 0,this._activeOperationIds.clear(),this._queue.length=0,this._inFlightCount=0}_makeAttempt(t,e){let i;if(this._withSignal&&"function"==typeof AbortController){const e=new AbortController;this._controllers.set(t,e),i=e.signal}return{operationId:t,attempt:e,signal:i}}_isEligible(t){switch(this.policy){case"latest":return t.supersedeEpoch===this._latestEpoch;case"queue":case"exhaust":return this._activeOperationId===t.operationId;case"overlap":return this._activeOperationIds.has(t.operationId)}}_advanceBookkeeping(t){switch(this.policy){case"latest":case"exhaust":this._activeOperationId===t&&(this._activeOperationId=void 0);break;case"queue":{const e=this._queue.filter(e=>e.operationId!==t);this._queue.length=0,this._queue.push(...e),this._activeOperationId=this._queue.length>0?this._queue[0].operationId:void 0;break}case"overlap":this._activeOperationIds.delete(t)}}_abortController(t){const e=this._controllers.get(t);void 0===e||e.signal.aborted||e.abort()}_releaseController(t){this._controllers.delete(t)}}function i(t,e){const i=new Map,s=e=>{const i=t.get(e);return void 0===i?"unknown":i.probe()?"available":"missing"};let r=!0;for(const t of e.required){const e=s(t);i.set(t,e),"available"!==e&&(r=!1)}let n=!0;for(const t of e.optional??[]){const e=s(t);i.set(t,e),"available"!==e&&(n=!1)}const a=r?n?"ready":"degraded":"idle",o=[...e.required,...e.optional??[]],l=o.some(e=>!0===t.get(e)?.requiresSecureContext),c=o.some(e=>!0===t.get(e)?.requiresUserActivation),h=l?!0===globalThis.isSecureContext?"satisfied":"required":"not-applicable",u=c?"required":"not-applicable";return{availability:i,permission:e.permission??"not-applicable",readiness:a,activity:e.activity??"inactive",preconditions:{secureContext:h,userActivation:u},epoch:e.epoch??0,lastError:e.lastError}}function s(t,e){return e.every(e=>"available"===t.availability.get(e))}const r="capability-missing",n="invalid-argument",a="network",o="http-error",l=new Map([["web.xhr",{probe:()=>"function"==typeof globalThis.XMLHttpRequest,compatKey:"api.XMLHttpRequest"}]]);class c extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"value",event:"wcs-upload:response",semantics:"state",getter:t=>t.detail.value},{name:"loading",event:"wcs-upload:loading-changed",semantics:"state"},{name:"progress",event:"wcs-upload:progress",semantics:"state"},{name:"error",event:"wcs-upload:error",semantics:"state"},{name:"status",event:"wcs-upload:response",semantics:"state",getter:t=>t.detail.status},{name:"errorInfo",event:"wcs-upload:error-info-changed",semantics:"state"}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"}],commands:[{name:"upload",async:!0},{name:"abort"}]};static REQUIRED_CAPABILITIES=["web.xhr"];_target;_value=null;_loading=!1;_progress=0;_error=null;_status=0;_errorInfo=null;_xhr=null;_promise=Promise.resolve(null);_lane=new e("upload","latest",{withSignal:!1});_ready=Promise.resolve();constructor(t){super(),this._target=t??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._lane.disposeOwner(),this.abort(),this._loading&&this._setLoading(!1)}get value(){return this._value}get loading(){return this._loading}get progress(){return this._progress}get error(){return this._error}get status(){return this._status}get promise(){return this._promise}get errorInfo(){return this._errorInfo}get supported(){return s(this.platformAssessment,c.REQUIRED_CAPABILITIES)}get platformAssessment(){return i(l,{required:c.REQUIRED_CAPABILITIES,activity:this._loading?"active":"inactive",lastError:this._errorInfo??void 0})}_commitStep(t,e){this._lane.canCommit(t)&&e()}_setLoading(t){this._loading=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:loading-changed",{detail:t,bubbles:!0}))}_setProgress(t){this._progress=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:progress",{detail:t,bubbles:!0}))}_setError(t){this._error!==t&&(this._error=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:error",{detail:t,bubbles:!0})))}setError(t){this._setError(t)}_setResponse(t,e){this._value=t,this._status=e,this._target.dispatchEvent(new CustomEvent("wcs-upload:response",{detail:{value:t,status:e},bubbles:!0}))}_setErrorInfo(t,e,i,s,r){this._commitErrorInfo({code:t,phase:e,recoverable:i,message:s,...void 0===r?{}:{capabilityId:r}})}_commitErrorInfo(t){this._errorInfo!==t&&(this._errorInfo=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:error-info-changed",{detail:t,bubbles:!0})))}abort(){this._xhr&&(this._xhr.abort(),this._xhr=null)}async upload(t,e,i={}){if(!t)return this._setErrorInfo(n,"start",!1,"url is required."),this._setError({message:"url is required."}),null;if(!e||0===e.length)return this._setErrorInfo(n,"start",!1,"files are required."),this._setError({message:"files are required."}),null;const s=this._doUpload(t,e,i);return this._promise=s,s}_doUpload(t,e,i){const n=this.platformAssessment;if(!s(n,c.REQUIRED_CAPABILITIES)){const t=c.REQUIRED_CAPABILITIES.find(t=>"available"!==n.availability.get(t)),e=`Required capability "${t}" is unavailable.`;return this._setErrorInfo(r,"start",!1,e,t),this._setError({message:e}),Promise.resolve(null)}this.abort();const l=this._lane.begin(),{ticket:h}=l;this._commitStep(h,()=>this._setLoading(!0)),this._commitStep(h,()=>{this._setProgress(0),this._commitErrorInfo(null),this._setError(null)});const{method:u="POST",headers:d={},fieldName:p="file"}=i,_=new FormData;for(let t=0;t<e.length;t++)_.append(p,e[t]);return new Promise(e=>{const i=new XMLHttpRequest;this._xhr=i,i.upload.addEventListener("progress",t=>{this._commitStep(h,()=>{t.lengthComputable&&this._setProgress(Math.round(t.loaded/t.total*100))})}),i.addEventListener("load",()=>{if(this._xhr=null,i.status>=200&&i.status<300){if(!this._lane.claimTerminal(h,"success"))return e(null),void this._lane.finalize(h);let t=i.responseText;if((i.getResponseHeader("Content-Type")||"").includes("application/json"))try{t=JSON.parse(i.responseText)}catch{}this._commitStep(h,()=>this._setProgress(100)),this._commitStep(h,()=>this._setResponse(t,i.status)),this._commitStep(h,()=>this._setLoading(!1)),this._lane.finalize(h),e(t)}else{if(!this._lane.claimTerminal(h,"error"))return e(null),void this._lane.finalize(h);const t={status:i.status,statusText:i.statusText,body:i.responseText};this._commitStep(h,()=>{this._status=i.status,this._setErrorInfo(o,"execute",!0,`HTTP ${i.status} ${i.statusText}`),this._setError(t)}),this._commitStep(h,()=>this._setLoading(!1)),this._lane.finalize(h),e(null)}}),i.addEventListener("error",()=>{if(this._xhr=null,!this._lane.claimTerminal(h,"error"))return e(null),void this._lane.finalize(h);const t="Network error";this._commitStep(h,()=>{this._setErrorInfo(a,"execute",!0,t),this._setError({message:t})}),this._commitStep(h,()=>this._setLoading(!1)),this._lane.finalize(h),e(null)}),i.addEventListener("abort",()=>{this._xhr=null,this._lane.claimTerminal(h,"aborted")&&this._commitStep(h,()=>this._setLoading(!1)),this._lane.finalize(h),e(null)}),i.open(u,t);for(const[t,e]of Object.entries(d))i.setRequestHeader(t,e);i.send(_)})}}let h=!1;function u(e){const i=e.target;if(!(i instanceof Element))return;const s=i.closest(`[${t.triggerAttribute}]`);if(!s)return;const r=s.getAttribute(t.triggerAttribute);if(!r)return;const n=customElements.get(t.tagNames.upload),a=document.getElementById(r);if(!(n&&a instanceof n))return;const o=a;o.files&&o.files.length>0&&o.url&&e.preventDefault(),o.upload()}function d(t,e){let i=Object.getPrototypeOf(t);for(;null!==i;){const t=Object.getOwnPropertyDescriptor(i,e);if(void 0!==t)return"function"==typeof t.get||"function"==typeof t.set;i=Object.getPrototypeOf(i)}return!1}const p=new WeakSet;function _(t,e,i){if(p.has(t))return;p.add(t);const s=t.localName??"element";console.warn(`[wcs/input-as-attribute] <${s}> has the attribute ${e}="${i}": an object was written as an attribute, so the element did not receive it. A framework does that when the property is set before the element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, or assign the property through a ref (Vue: .prop). (Said once per element.)`,t)}const m=new WeakMap;function g(t,e){let i=m.get(t);return void 0===i&&(i=new Map,m.set(t,i)),i.has(e)||i.set(e,t.getAttribute(e)),i.get(e)}function f(t,e,i){null===i?t.removeAttribute(e):t.setAttribute(e,i)}function b(t,e,i){const s=g(t,e);f(t,e,void 0===i?s:null===i?null:String(i))}function v(t,e,i){const s=g(t,e);f(t,e,void 0===i?s:i?"":null)}class w extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...c.wcBindable,properties:[...c.wcBindable.properties,{name:"trigger",event:"wcs-upload:trigger-changed",semantics:"state"},{name:"files",event:"wcs-upload:files-changed",semantics:"state"}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"},{name:"multiple"},{name:"maxSize"},{name:"accept"},{name:"manual"},{name:"files"},{name:"trigger"}]};static get observedAttributes(){return["url"]}_core;_files=null;_trigger=!1;_told=null;_waitingForUrl=!1;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new c(this),this._internals=this._initInternals(),this._wireStates({"wcs-upload:loading-changed":t=>({loading:!0===t}),"wcs-upload:error":t=>({error:null!=t})})}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const t=this.attachInternals();return t.states.add("wcs-probe"),t.states.delete("wcs-probe"),t}catch{return null}}_wireStates(t){if(null===this._internals)return;const e=this._internals.states;for(const[i,s]of Object.entries(t))this.addEventListener(i,t=>{const i=this.hasAttribute("debug-states");for(const[r,n]of Object.entries(s(t.detail))){try{n?e.add(r):e.delete(r)}catch{}i&&this.toggleAttribute(`data-wcs-state-${r}`,n)}})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get url(){return this.getAttribute("url")||""}set url(t){b(this,"url",t)}get method(){return(this.getAttribute("method")||"POST").toUpperCase()}set method(t){b(this,"method",t)}get fieldName(){return this.getAttribute("field-name")||"file"}set fieldName(t){b(this,"field-name",t)}get multiple(){return this.hasAttribute("multiple")}set multiple(t){v(this,"multiple",t)}get maxSize(){const t=this.getAttribute("max-size");if(null===t)return 1/0;const e=parseInt(t,10);return Number.isFinite(e)&&e>=0?e:1/0}set maxSize(t){b(this,"max-size",t)}get accept(){return this.getAttribute("accept")||""}set accept(t){b(this,"accept",t)}get manual(){return this.hasAttribute("manual")}set manual(t){v(this,"manual",t)}get value(){return this._core.value}get loading(){return this._core.loading}get progress(){return this._core.progress}get error(){return this._core.error}get status(){return this._core.status}get errorInfo(){return this._core.errorInfo}get promise(){return this._core.promise}get trigger(){return this._trigger}set trigger(t){!!t&&(this._trigger=!0,this.upload().finally(()=>{this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-upload:trigger-changed",{detail:!1,bubbles:!0}))}))}get files(){return this._files}set files(t){const e=t??null;this._files=e,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:e,bubbles:!0})),this._waitingForUrl=!this.manual&&!!e&&e.length>0&&!this.url,!this.manual&&e&&e.length>0&&this.url&&this.upload()}_validate(t){const e=this.maxSize;if(e!==1/0)for(let i=0;i<t.length;i++)if(t[i].size>e)return{message:`File "${t[i].name}" exceeds maximum size of ${e} bytes.`};const i=this.accept;if(i){const e=i.split(",").map(t=>t.trim().toLowerCase());for(let s=0;s<t.length;s++){const r=t[s],n=r.type.toLowerCase(),a=r.name.toLowerCase();if(!e.some(t=>t.startsWith(".")?a.endsWith(t):t.endsWith("/*")?""!==n&&n.startsWith(t.slice(0,-1)):""!==n&&n===t))return{message:`File "${r.name}" does not match accepted types: ${i}`}}}return null}abort(){this._core.abort()}async upload(){const t=this._files;if(!t||0===t.length||!this.url)return this._warnNotReady(this.url?"there are no files":"there is no url"),null;const e=this._validate(t);if(e)return this._core.setError(e),null;this._told=null;const i=await this._core.upload(this.url,t,{method:this.method,fieldName:this.fieldName});return this._files===t&&(this._files=null,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:null,bubbles:!0}))),i}_warnNotReady(t){this._told?.has(t)||((this._told??=new Set).add(t),console.warn(`[@wcstack/upload] [wcs/command-not-ready] The upload was refused: ${t}, so nothing is sent. Write url and files before trigger (data-wcs bindings and a framework's props are applied in the order written), and assign files again for each retry: an upload uses them up. (Said once per reason until an upload is sent again.)`,this))}attributeChangedCallback(t,e,i){this._waitingForUrl&&i&&!this.manual&&(this._waitingForUrl=!1,this.upload())}connectedCallback(){!function(t){const e=t.constructor?.wcBindable,i=e?.inputs;if(void 0===i)return;const s=t.getAttribute;for(const e of i){const i=e.name,r="function"==typeof s?s.call(t,i.toLowerCase()):null;if(null!==r&&r.startsWith("[object ")&&_(t,i,r),!Object.prototype.hasOwnProperty.call(t,i))continue;if(!d(t,i))continue;const n=t,a=n[i];delete n[i],n[i]=a}}(this),this.style.display="none",h||(h=!0,document.addEventListener("click",u)),this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}var I;!function(e=customElements){e.get(t.tagNames.upload)||e.define(t.tagNames.upload,w)}(I);
|
|
1
|
+
const t={triggerAttribute:"data-uploadtarget",tagNames:{upload:"wcs-upload",uploadHeader:"wcs-upload-header"}};class e{laneKey;policy;_ownerGeneration=0;_latestEpoch=0;_nextOperationId=1;_activeOperationId=void 0;_activeOperationIds=new Set;_queue=[];_inFlightCount=0;_terminal=new Map;_claimedOutcome=new Map;_controllers=new Map;_attempts=new Map;_withSignal;_trace;constructor(t,e,s={}){this.laneKey=t,this.policy=e,this._withSignal=s.withSignal??!1,this._trace=s.trace}get ownerGeneration(){return this._ownerGeneration}get inFlightCount(){return this._inFlightCount}get latestEpoch(){return this._latestEpoch}get activeOperationId(){return this._activeOperationId}begin(){let t;switch(this.policy){case"latest":t=++this._latestEpoch,void 0!==this._activeOperationId&&this._abortController(this._activeOperationId);break;case"exhaust":if(void 0!==this._activeOperationId)return null}const e=this._nextOperationId++,s={operationId:e,ownerGeneration:this._ownerGeneration,laneKey:this.laneKey,policy:this.policy,supersedeEpoch:t};switch(this.policy){case"latest":case"exhaust":this._activeOperationId=e;break;case"queue":this._queue.push(s),void 0===this._activeOperationId&&(this._activeOperationId=e);break;case"overlap":this._activeOperationIds.add(e)}this._inFlightCount+=1,this._attempts.set(e,1);const i=this._makeAttempt(e,1);return void 0!==this._trace&&this._trace({type:"io:operation-started",operationId:e,laneKey:this.laneKey,policy:this.policy}),{ticket:s,attempt:i}}retry(t){if(t.ownerGeneration!==this._ownerGeneration)return null;if(this._terminal.has(t.operationId))return null;const e=this._attempts.get(t.operationId);if(void 0===e)return null;const s=e+1;this._attempts.set(t.operationId,s),this._releaseController(t.operationId);const i=this._makeAttempt(t.operationId,s);return void 0!==this._trace&&this._trace({type:"io:operation-retried",operationId:t.operationId,laneKey:this.laneKey,attempt:s}),i}canCommit(t){if(t.ownerGeneration!==this._ownerGeneration)return!1;const e=this._terminal.get(t.operationId);return(void 0===e||"committing"===e)&&this._isEligible(t)}claimTerminal(t,e){return t.ownerGeneration===this._ownerGeneration&&(!this._terminal.has(t.operationId)&&(!!this._isEligible(t)&&(this._terminal.set(t.operationId,"committing"),this._claimedOutcome.set(t.operationId,e),!0)))}claimedOutcome(t){return this._claimedOutcome.get(t.operationId)}finalize(t){const e=t.operationId,s=this._terminal.get(e);if(void 0!==s&&"committing"!==s)return;let i;i="committing"===s?this._claimedOutcome.get(e)??"stale":"stale",this._terminal.set(e,i),this._claimedOutcome.delete(e),this._releaseController(e),this._attempts.delete(e),this._inFlightCount>0&&(this._inFlightCount-=1),this._advanceBookkeeping(e),void 0!==this._trace&&("stale"===i?this._trace({type:"io:stale-dropped",operationId:e,laneKey:this.laneKey}):this._trace({type:"io:operation-settled",operationId:e,laneKey:this.laneKey,outcome:i}))}signalOf(t){return this._controllers.get(t.operationId)?.signal}abort(t){this._abortController(t.operationId)}abortActive(){void 0!==this._activeOperationId&&this._abortController(this._activeOperationId);for(const t of this._activeOperationIds)this._abortController(t)}disposeOwner(){this._ownerGeneration+=1;for(const t of Array.from(this._controllers.keys()))this._abortController(t),this._releaseController(t);for(const t of Array.from(this._attempts.keys()))this._terminal.has(t)||this._terminal.set(t,"stale"),this._claimedOutcome.delete(t),this._attempts.delete(t),void 0!==this._trace&&this._trace({type:"io:stale-dropped",operationId:t,laneKey:this.laneKey});this._activeOperationId=void 0,this._activeOperationIds.clear(),this._queue.length=0,this._inFlightCount=0}_makeAttempt(t,e){let s;if(this._withSignal&&"function"==typeof AbortController){const e=new AbortController;this._controllers.set(t,e),s=e.signal}return{operationId:t,attempt:e,signal:s}}_isEligible(t){switch(this.policy){case"latest":return t.supersedeEpoch===this._latestEpoch;case"queue":case"exhaust":return this._activeOperationId===t.operationId;case"overlap":return this._activeOperationIds.has(t.operationId)}}_advanceBookkeeping(t){switch(this.policy){case"latest":case"exhaust":this._activeOperationId===t&&(this._activeOperationId=void 0);break;case"queue":{const e=this._queue.filter(e=>e.operationId!==t);this._queue.length=0,this._queue.push(...e),this._activeOperationId=this._queue.length>0?this._queue[0].operationId:void 0;break}case"overlap":this._activeOperationIds.delete(t)}}_abortController(t){const e=this._controllers.get(t);void 0===e||e.signal.aborted||e.abort()}_releaseController(t){this._controllers.delete(t)}}function s(t,e){const s=new Map,i=e=>{const s=t.get(e);return void 0===s?"unknown":s.probe()?"available":"missing"};let r=!0;for(const t of e.required){const e=i(t);s.set(t,e),"available"!==e&&(r=!1)}let a=!0;for(const t of e.optional??[]){const e=i(t);s.set(t,e),"available"!==e&&(a=!1)}const n=r?a?"ready":"degraded":"idle",o=[...e.required,...e.optional??[]],l=o.some(e=>!0===t.get(e)?.requiresSecureContext),h=o.some(e=>!0===t.get(e)?.requiresUserActivation),c=l?!0===globalThis.isSecureContext?"satisfied":"required":"not-applicable",u=h?"required":"not-applicable";return{availability:s,permission:e.permission??"not-applicable",readiness:n,activity:e.activity??"inactive",preconditions:{secureContext:c,userActivation:u},epoch:e.epoch??0,lastError:e.lastError}}function i(t,e){return e.every(e=>"available"===t.availability.get(e))}const r="capability-missing",a="invalid-argument",n="network",o="http-error",l=new Map([["web.xhr",{probe:()=>"function"==typeof globalThis.XMLHttpRequest,compatKey:"api.XMLHttpRequest"}]]);class h extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"value",event:"wcs-upload:response",semantics:"state",getter:t=>t.detail.value},{name:"loading",event:"wcs-upload:loading-changed",semantics:"state"},{name:"progress",event:"wcs-upload:progress",semantics:"state"},{name:"error",event:"wcs-upload:error",semantics:"state"},{name:"status",event:"wcs-upload:response",semantics:"state",getter:t=>t.detail.status},{name:"errorInfo",event:"wcs-upload:error-info-changed",semantics:"state"}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"}],commands:[{name:"upload",async:!0},{name:"abort"}]};static REQUIRED_CAPABILITIES=["web.xhr"];_target;_value=null;_loading=!1;_progress=0;_error=null;_status=0;_errorInfo=null;_xhr=null;_promise=Promise.resolve(null);_lane=new e("upload","latest",{withSignal:!1});_ready=Promise.resolve();constructor(t){super(),this._target=t??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._lane.disposeOwner(),this.abort(),this._loading&&this._setLoading(!1)}get value(){return this._value}get loading(){return this._loading}get progress(){return this._progress}get error(){return this._error}get status(){return this._status}get promise(){return this._promise}get errorInfo(){return this._errorInfo}get supported(){return i(this.platformAssessment,h.REQUIRED_CAPABILITIES)}get platformAssessment(){return s(l,{required:h.REQUIRED_CAPABILITIES,activity:this._loading?"active":"inactive",lastError:this._errorInfo??void 0})}_commitStep(t,e){this._lane.canCommit(t)&&e()}_setLoading(t){this._loading=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:loading-changed",{detail:t,bubbles:!0}))}_setProgress(t){this._progress=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:progress",{detail:t,bubbles:!0}))}_setError(t){this._error!==t&&(this._error=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:error",{detail:t,bubbles:!0})))}setError(t){this._setError(t)}_setResponse(t,e){this._value=t,this._status=e,this._target.dispatchEvent(new CustomEvent("wcs-upload:response",{detail:{value:t,status:e},bubbles:!0}))}_setErrorInfo(t,e,s,i,r){this._commitErrorInfo({code:t,phase:e,recoverable:s,message:i,...void 0===r?{}:{capabilityId:r}})}_commitErrorInfo(t){this._errorInfo!==t&&(this._errorInfo=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:error-info-changed",{detail:t,bubbles:!0})))}abort(){this._xhr&&(this._xhr.abort(),this._xhr=null)}async upload(t,e,s={}){if(!t)return this._setErrorInfo(a,"start",!1,"url is required."),this._setError({message:"url is required."}),null;if(!e||0===e.length)return this._setErrorInfo(a,"start",!1,"files are required."),this._setError({message:"files are required."}),null;const i=this._doUpload(t,e,s);return this._promise=i,i}_doUpload(t,e,s){const a=this.platformAssessment;if(!i(a,h.REQUIRED_CAPABILITIES)){const t=h.REQUIRED_CAPABILITIES.find(t=>"available"!==a.availability.get(t)),e=`Required capability "${t}" is unavailable.`;return this._setErrorInfo(r,"start",!1,e,t),this._setError({message:e}),Promise.resolve(null)}this.abort();const l=this._lane.begin(),{ticket:c}=l;this._commitStep(c,()=>this._setLoading(!0)),this._commitStep(c,()=>{this._setProgress(0),this._commitErrorInfo(null),this._setError(null)});const{method:u="POST",headers:d={},fieldName:p="file"}=s,_=new FormData;for(let t=0;t<e.length;t++)_.append(p,e[t]);return new Promise(e=>{const s=new XMLHttpRequest;this._xhr=s,s.upload.addEventListener("progress",t=>{this._commitStep(c,()=>{t.lengthComputable&&this._setProgress(Math.round(t.loaded/t.total*100))})}),s.addEventListener("load",()=>{if(this._xhr=null,s.status>=200&&s.status<300){if(!this._lane.claimTerminal(c,"success"))return e(null),void this._lane.finalize(c);let t=s.responseText;if((s.getResponseHeader("Content-Type")||"").includes("application/json"))try{t=JSON.parse(s.responseText)}catch{}this._commitStep(c,()=>this._setProgress(100)),this._commitStep(c,()=>this._setResponse(t,s.status)),this._commitStep(c,()=>this._setLoading(!1)),this._lane.finalize(c),e(t)}else{if(!this._lane.claimTerminal(c,"error"))return e(null),void this._lane.finalize(c);const t={status:s.status,statusText:s.statusText,body:s.responseText};this._commitStep(c,()=>{this._status=s.status,this._setErrorInfo(o,"execute",!0,`HTTP ${s.status} ${s.statusText}`),this._setError(t)}),this._commitStep(c,()=>this._setLoading(!1)),this._lane.finalize(c),e(null)}}),s.addEventListener("error",()=>{if(this._xhr=null,!this._lane.claimTerminal(c,"error"))return e(null),void this._lane.finalize(c);const t="Network error";this._commitStep(c,()=>{this._setErrorInfo(n,"execute",!0,t),this._setError({message:t})}),this._commitStep(c,()=>this._setLoading(!1)),this._lane.finalize(c),e(null)}),s.addEventListener("abort",()=>{this._xhr=null,this._lane.claimTerminal(c,"aborted")&&this._commitStep(c,()=>this._setLoading(!1)),this._lane.finalize(c),e(null)}),s.open(u,t);for(const[t,e]of Object.entries(d))s.setRequestHeader(t,e);s.send(_)})}}let c=!1;function u(e){const s=e.target;if(!(s instanceof Element))return;const i=s.closest(`[${t.triggerAttribute}]`);if(!i)return;const r=i.getAttribute(t.triggerAttribute);if(!r)return;const a=customElements.get(t.tagNames.upload),n=document.getElementById(r);if(!(a&&n instanceof a))return;const o=n;o.files&&o.files.length>0&&o.url&&e.preventDefault(),o.upload()}function d(t,e){let s=Object.getPrototypeOf(t);for(;null!==s;){const t=Object.getOwnPropertyDescriptor(s,e);if(void 0!==t)return"function"==typeof t.get||"function"==typeof t.set;s=Object.getPrototypeOf(s)}return!1}const p=new WeakSet;function _(t,e,s){if(p.has(t))return;p.add(t);const i=t.localName??"element";console.warn(`[wcs/input-as-attribute] <${i}> has the attribute ${e}="${s}": an object was written as an attribute, so the element did not receive it. A framework does that when the property is set before the element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, or assign the property through a ref (Vue: .prop). (Said once per element.)`,t)}const m=new WeakMap;function g(t,e){let s=m.get(t);return void 0===s&&(s=new Map,m.set(t,s)),s.has(e)||s.set(e,t.getAttribute(e)),s.get(e)}function f(t,e,s){null===s?t.removeAttribute(e):t.setAttribute(e,s)}function b(t,e,s){const i=g(t,e);f(t,e,void 0===s?i:null===s?null:String(s))}function v(t,e,s){const i=g(t,e);f(t,e,void 0===s?i:s?"":null)}class w extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...h.wcBindable,properties:[...h.wcBindable.properties,{name:"trigger",event:"wcs-upload:trigger-changed",semantics:"state"},{name:"files",event:"wcs-upload:files-changed",semantics:"state"}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"},{name:"multiple"},{name:"maxSize"},{name:"accept"},{name:"manual"},{name:"files"},{name:"trigger"}]};static get observedAttributes(){return["url"]}_core;_files=null;_trigger=!1;_told=null;_toldUndefinedHelper=!1;_waitingForUrl=!1;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new h(this),this._internals=this._initInternals(),this._wireStates({"wcs-upload:loading-changed":t=>({loading:!0===t}),"wcs-upload:error":t=>({error:null!=t})})}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const t=this.attachInternals();return t.states.add("wcs-probe"),t.states.delete("wcs-probe"),t}catch{return null}}_wireStates(t){if(null===this._internals)return;const e=this._internals.states;for(const[s,i]of Object.entries(t))this.addEventListener(s,t=>{const s=this.hasAttribute("debug-states");for(const[r,a]of Object.entries(i(t.detail))){try{a?e.add(r):e.delete(r)}catch{}s&&this.toggleAttribute(`data-wcs-state-${r}`,a)}})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get url(){return this.getAttribute("url")||""}set url(t){b(this,"url",t)}get method(){return(this.getAttribute("method")||"POST").toUpperCase()}set method(t){b(this,"method",t)}get fieldName(){return this.getAttribute("field-name")||"file"}set fieldName(t){b(this,"field-name",t)}get multiple(){return this.hasAttribute("multiple")}set multiple(t){v(this,"multiple",t)}get maxSize(){const t=this.getAttribute("max-size");if(null===t)return 1/0;const e=parseInt(t,10);return Number.isFinite(e)&&e>=0?e:1/0}set maxSize(t){b(this,"max-size",t)}get accept(){return this.getAttribute("accept")||""}set accept(t){b(this,"accept",t)}get manual(){return this.hasAttribute("manual")}set manual(t){v(this,"manual",t)}get value(){return this._core.value}get loading(){return this._core.loading}get progress(){return this._core.progress}get error(){return this._core.error}get status(){return this._core.status}get errorInfo(){return this._core.errorInfo}get promise(){return this._core.promise}get trigger(){return this._trigger}set trigger(t){!!t&&(this._trigger=!0,this.upload().finally(()=>{this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-upload:trigger-changed",{detail:!1,bubbles:!0}))}))}get files(){return this._files}set files(t){const e=t??null;this._files=e,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:e,bubbles:!0})),this._waitingForUrl=!this.manual&&!!e&&e.length>0&&!this.url,!this.manual&&e&&e.length>0&&this.url&&this.upload()}_validate(t){const e=this.maxSize;if(e!==1/0)for(let s=0;s<t.length;s++)if(t[s].size>e)return{message:`File "${t[s].name}" exceeds maximum size of ${e} bytes.`};const s=this.accept;if(s){const e=s.split(",").map(t=>t.trim().toLowerCase());for(let i=0;i<t.length;i++){const r=t[i],a=r.type.toLowerCase(),n=r.name.toLowerCase();if(!e.some(t=>t.startsWith(".")?n.endsWith(t):t.endsWith("/*")?""!==a&&a.startsWith(t.slice(0,-1)):""!==a&&a===t))return{message:`File "${r.name}" does not match accepted types: ${s}`}}}return null}abort(){this._core.abort()}async upload(){const e=this._files;if(!e||0===e.length||!this.url)return this._warnNotReady(this.url?"there are no files":"there is no url"),null;const s=this._validate(e);if(s)return this._core.setError(s),null;this._told=null;const i=this._collectHeaders();Object.keys(i).some(t=>"content-type"===t.toLowerCase())&&console.warn(`[@wcstack/upload] A Content-Type header was set on an upload. An upload is sent as multipart/form-data, and a manual Content-Type drops the boundary the browser adds; remove the Content-Type <${t.tagNames.uploadHeader}>.`,this);const r=await this._core.upload(this.url,e,{method:this.method,fieldName:this.fieldName,headers:i});return this._files===e&&(this._files=null,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:null,bubbles:!0}))),r}_collectHeaders(){const e={},s=this.querySelectorAll(t.tagNames.uploadHeader);for(const i of s)"boolean"==typeof i.hasHeader?i.hasHeader&&(e[i.name]=i.value):this._warnUndefinedHelper(t.tagNames.uploadHeader);return e}_warnUndefinedHelper(e){this._toldUndefinedHelper||(this._toldUndefinedHelper=!0,console.warn(`[@wcstack/upload] [wcs/upload-helper-undefined] <${e}> inside this <${t.tagNames.upload}> is not defined, so its header is not sent. Load @wcstack/upload/auto, or define WcsUploadHeader with WcsUpload when the page defines the tags itself. (Said once per element.)`,this))}_warnNotReady(t){this._told?.has(t)||((this._told??=new Set).add(t),console.warn(`[@wcstack/upload] [wcs/command-not-ready] The upload was refused: ${t}, so nothing is sent. Write url and files before trigger (data-wcs bindings and a framework's props are applied in the order written), and assign files again for each retry: an upload uses them up. (Said once per reason until an upload is sent again.)`,this))}attributeChangedCallback(t,e,s){this._waitingForUrl&&s&&!this.manual&&(this._waitingForUrl=!1,this.upload())}connectedCallback(){!function(t){const e=t.constructor?.wcBindable,s=e?.inputs;if(void 0===s)return;const i=t.getAttribute;for(const e of s){const s=e.name,r="function"==typeof i?i.call(t,s.toLowerCase()):null;if(null!==r&&r.startsWith("[object ")&&_(t,s,r),!Object.prototype.hasOwnProperty.call(t,s))continue;if(!d(t,s))continue;const a=t,n=a[s];delete a[s],a[s]=n}}(this),this.style.display="none",c||(c=!0,document.addEventListener("click",u)),this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}class y extends HTMLElement{connectedCallback(){for(const t of["name","value"])if(Object.prototype.hasOwnProperty.call(this,t)){const e=this[t];delete this[t],this[t]=e}this.style.display="none"}get name(){return this.getAttribute("name")??""}set name(t){b(this,"name",t)}get value(){return this.getAttribute("value")??""}set value(t){b(this,"value",t)}get hasHeader(){return""!==this.name&&this.hasAttribute("value")}}var I;!function(e=customElements){e.get(t.tagNames.upload)||e.define(t.tagNames.upload,w),e.get(t.tagNames.uploadHeader)||e.define(t.tagNames.uploadHeader,y)}(I);
|
|
2
2
|
//# sourceMappingURL=auto.min.js.map
|