diff --git a/.gitignore b/.gitignore index 9ae6931..a13fb63 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ uploads client/dist client/dist/app.js.map client/dist/app.js +!/client/dist/ diff --git a/assets/templates/account.html b/assets/templates/account.html index c4c360a..ea1d0f7 100644 --- a/assets/templates/account.html +++ b/assets/templates/account.html @@ -10,6 +10,8 @@ facebook-id="{{a.facebook_id.as_deref().unwrap_or_default()}}" > {% when None %} - + {% endmatch %} {% endblock %} diff --git a/client/dist/app.js b/client/dist/app.js index 165bfce..9bffa3a 100644 --- a/client/dist/app.js +++ b/client/dist/app.js @@ -1,4 +1,4 @@ -const S = Symbol(); +Symbol(); const BUTTON_STYLE = ` input[type="button"], input[type="submit"] { padding: 12px 16px; @@ -101,23 +101,50 @@ label { } ${BUTTON_STYLE} `; -class PseudoForm extends HTMLElement { +class Component extends HTMLElement { + #a; + static get observedAttributes() { + return []; + } + constructor(a){ + super(), this.#a = this.attachShadow({ + mode: "open" + }), this.#a.innerHTML = a; + } + connectedCallback() {} + attributeChangedCallback(a, b, c) { + if (b === c) return; + let d = this.constructor.observedAttributes; + if (!Array.isArray(d) || !d.includes(a)) return; + let e = this.constructor.attr2Field(a); + e && (this[e] = c); + } + static attr2Field(a) { + if (!(this.constructor.attr2FieldBlacklist || []).includes(a)) return a.replace("-", "_"); + } + static get attr2FieldBlacklist() { + return []; + } +} +class PseudoForm extends Component { reportValidity() { - return this[S].querySelector("form").reportValidity(); + return this.shadowRoot.querySelector("form").reportValidity(); } checkValidity() { - return this[S].querySelector("form").checkValidity(); + return this.shadowRoot.querySelector("form").checkValidity(); } get elements() { - return this[S].querySelector("form").elements; + return this.shadowRoot.querySelector("form").elements; } } const fireFbReady = ()=>{ - for (let c of (!0, a))c(); + for (let c of (b = !0, a))c(); }; -let a = []; -customElements.define("form-navigation", class extends HTMLElement { - #a; +const runFbReady = (c)=>{ + b ? c() : a.push(c); +}; +let a = [], b = !1; +customElements.define("form-navigation", class extends Component { static get observedAttributes() { return [ "next", @@ -125,11 +152,7 @@ customElements.define("form-navigation", class extends HTMLElement { ]; } constructor(){ - super(); - let b = this.#a = this.attachShadow({ - mode: "closed" - }); - b.innerHTML = ` + super(` +

Skrypty Facebook są zablokowane przez rozszerzenie przeglądarki

+
+ + + + +
+ `), this.shadowRoot.querySelector("#fb-icon").addEventListener("click", (a)=>{ + if (a.stopPropagation(), a.preventDefault(), !this.#a) return console.info("Facebook SDK is not available"); + FB.login((a)=>{ + "connected" === a.status && FB.api("/me?fields=id,name,email", ({ id: a , name: b , email: c })=>{ + console.info({ + id: a, + name: b, + email: c + }), this.dispatchEvent(new CustomEvent("facebook:account", { + bubbles: !0, + composed: !0, + detail: { + id: a, + name: b, + email: c + } + })); + }); + }, { + scope: "public_profile,email", + return_scopes: !0 + }); + }); + } + connectedCallback() { + super.connectedCallback(), runFbReady(()=>{ + this.setAttribute("fb-sdk", "available"), this.dispatchEvent(new CustomEvent("facebook:available", { + bubbles: !0, + composed: !0 + })); + }); + } + get width() { + return this.getAttribute("width"); + } + set width(a) { + this.setAttribute("width", a), this.shadowRoot.querySelector("svg").setAttribute("width", a); + } + get height() { + return this.getAttribute("width"); + } + set height(a) { + this.setAttribute("height", a), this.shadowRoot.querySelector("svg").setAttribute("height", a); + } + get fb_sdk() { + return !!this.#a; + } + set fb_sdk(a) { + this.setAttribute("fb-sdk", a), this.#a = "available" === a; + } +}); +customElements.define("account-view", class extends Component { + static get observedAttributes() { + return [ + "facebook-id", + "id", + "name", + "email" + ]; + } + constructor(){ + super(` + +
+ +
+
+ + +
+
+ + +
+
+ +

Powiąż z kontem Facebook

+
+
+
+ + +
+ `), this.addEventListener("facebook:available", (a)=>{ + a.preventDefault(), a.stopPropagation(); + }); + } + get name() { + return this.getAttribute("name") || ""; + } + set name(a) { + this.setAttribute("name", a), this.shadowRoot.querySelector("#name").value = a; + } + get email() { + return this.getAttribute("email") || ""; + } + set email(a) { + this.setAttribute("email", a), this.shadowRoot.querySelector("#email").value = a; + } + get facebook_id() { + return this.getAttribute("facebook-id"); + } + set facebook_id(a) { + this.setAttribute("facebook-id", a), this.shadowRoot.querySelector("#facebook_id").value = a; + } +}); +customElements.define("ow-account", class extends Component { static get observedAttributes() { return [ "mode", @@ -386,11 +564,7 @@ customElements.define("ow-account", class extends HTMLElement { ]; } constructor(){ - super(); - let b = this.#a = this.attachShadow({ - mode: "closed" - }); - b.innerHTML = ` + super(` - `; + `); } connectedCallback() { this.selected = this.getAttribute("selected"); } attributeChangedCallback(a, b, c) { - if (b !== c) switch(a){ - case "selected": - return this.selected = c; - case "path": - return this.path = c; - } + super.attributeChangedCallback(a, b, c); } get selected() { return "selected" === this.getAttribute("selected"); @@ -610,7 +745,7 @@ customElements.define("ow-path", class extends HTMLElement { this.removeAttribute("path"); return; } - this.setAttribute("path", a), this.#a.querySelector("a").setAttribute("href", a); + this.setAttribute("path", a), this.shadowRoot.querySelector("a").setAttribute("href", a); } }); customElements.define("price-view", class extends HTMLElement { @@ -748,13 +883,8 @@ customElements.define("price-input", class extends HTMLElement { } }); customElements.define("register-basic-form", class extends PseudoForm { - #a; constructor(){ - super(); - let b = this.#a = this.attachShadow({ - mode: "closed" - }); - b.innerHTML = ` + super(` +
+
+ + +
+ + +
+
+ + + +
+
+
+
+ `; customElements.define("register-item-form-row", class extends PseudoForm { - #a; static get observedAttributes() { return [ "idx", @@ -792,9 +962,7 @@ customElements.define("register-item-form-row", class extends PseudoForm { ]; } constructor(){ - super(), this.#a = this.attachShadow({ - mode: "closed" - }), this.addEventListener("item:removed", ()=>{ + super(c()), this.addEventListener("item:removed", ()=>{ this.setAttribute("removed", "removed"); let a = this.parentElement; this.remove(), a.dispatchEvent(new CustomEvent("item:removed", { @@ -804,54 +972,13 @@ customElements.define("register-item-form-row", class extends PseudoForm { }); } connectedCallback() { - let b = this.idx; - this.#a.innerHTML = ` - -
-
- - -
- - -
-
- - - -
-
-
-
- `; - let c = this.#a.querySelector("image-input"); - this.addEventListener("image-input:uploaded", (a)=>{ - a.preventDefault(), a.stopPropagation(), this.picture_url = c.url; - }), this.#a.querySelector("form").addEventListener("submit", (a)=>{ + this.shadowRoot.innerHTML = c(this.idx); + let a = this.shadowRoot.querySelector("image-input"); + this.addEventListener("image-input:uploaded", (b)=>{ + b.preventDefault(), b.stopPropagation(), this.picture_url = a.url; + }), this.shadowRoot.querySelector("form").addEventListener("submit", (a)=>{ a.preventDefault(), a.stopPropagation(), this.reportValidity(); - }), this.#a.querySelector(".remove").addEventListener("click", (a)=>{ + }), this.shadowRoot.querySelector(".remove").addEventListener("click", (a)=>{ a.preventDefault(), a.stopPropagation(), this.dispatchEvent(new CustomEvent("item:removed", { bubbles: !0, composed: !1 @@ -868,13 +995,13 @@ customElements.define("register-item-form-row", class extends PseudoForm { } get inputs() { return [ - c(this.#a.querySelector(".item-name")), - c(this.#a.querySelector(".item-price")), + d(this.shadowRoot.querySelector(".item-name")), + d(this.shadowRoot.querySelector(".item-price")), ]; } updateNames() { let a = this.getAttribute("idx"); - for (let b of this.#a.querySelectorAll(".field")){ + for (let b of this.shadowRoot.querySelectorAll(".field")){ let c = b.id; b.querySelector("input, price-input").setAttribute("name", `items[${a}][${c}]`); } @@ -889,13 +1016,13 @@ customElements.define("register-item-form-row", class extends PseudoForm { return this.getAttribute("picture-url"); } set picture_url(a) { - this.setAttribute("picture-url", a), this.#a.querySelector("image-input").url = a, this.#a.querySelector("#picture_url").value = a; + this.setAttribute("picture-url", a), this.shadowRoot.querySelector("image-input").url = a, this.shadowRoot.querySelector("#picture_url").value = a; } reportValidity() { - return super.reportValidity() && this.#a.querySelector("price-input").reportValidity(); + return super.reportValidity() && this.shadowRoot.querySelector("price-input").reportValidity(); } }); -let c = ({ name: a , value: b })=>({ +let d = ({ name: a , value: b })=>({ name: a, value: b }); @@ -905,24 +1032,17 @@ let c1 = (a)=>{ return b; }; customElements.define("register-items-form", class extends PseudoForm { - #a; - static get observedAttributes() { - return []; - } constructor(){ - super(); - let b = this.#a = this.attachShadow({ - mode: "closed" - }); - b.innerHTML = ` + super(`
@@ -933,11 +1053,11 @@ customElements.define("register-items-form", class extends PseudoForm { - `, this.addEventListener("item:removed", (a)=>{ + `), this.addEventListener("item:removed", (a)=>{ a.stopPropagation(), c1(this); }), this.addEventListener("form:next", (a)=>{ for (let b of this.querySelectorAll("item-form-row"))b.reportValidity() || (a.stopPropagation(), a.preventDefault()); - }), b.querySelector("#add-item").addEventListener("click", (a)=>{ + }), this.shadowRoot.querySelector("#add-item").addEventListener("click", (a)=>{ a.stopPropagation(), a.preventDefault(), this.appendChild(document.createElement("register-item-form-row")), c1(this); }); } @@ -948,13 +1068,8 @@ customElements.define("register-items-form", class extends PseudoForm { } }); customElements.define("register-business-form", class extends PseudoForm { - #a; constructor(){ - super(); - let b = this.#a = this.attachShadow({ - mode: "closed" - }); - b.innerHTML = ` + super(` - `; + `); } }); if (!document.querySelector("#facebook-jssdk")) { @@ -1545,6 +1616,6 @@ if (!document.querySelector("#facebook-jssdk")) { version: "v14.0" }), FB.AppEvents.logPageView(), fireFbReady(); }; - let b = document.createElement("script"); - b.id = "facebook-jssdk", b.src = "https://connect.facebook.net/en_US/sdk.js", document.head.appendChild(b); + let b1 = document.createElement("script"); + b1.id = "facebook-jssdk", b1.src = "https://connect.facebook.net/en_US/sdk.js", document.head.appendChild(b1); } diff --git a/client/src/business-items.js b/client/src/business-items.js index 6b3786d..7db7885 100644 --- a/client/src/business-items.js +++ b/client/src/business-items.js @@ -1,18 +1,13 @@ import "./business-items/business-item"; +import { Component } from "./shared"; -customElements.define('business-items', class extends HTMLElement { - #form; - +customElements.define('business-items', class extends Component { constructor() { - super(); - - const shadow = this.#form = this.attachShadow({ mode: "closed" }); - - shadow.innerHTML = ` + super(` - `; + `); } }); diff --git a/client/src/business-items/business-item.js b/client/src/business-items/business-item.js index cfa2bb7..19ecec3 100644 --- a/client/src/business-items/business-item.js +++ b/client/src/business-items/business-item.js @@ -1,18 +1,13 @@ import "../shared/image-input"; +import { Component } from "../shared"; -customElements.define('business-item', class extends HTMLElement { - #form; - +customElements.define('business-item', class extends Component { static get observedAttributes() { return ['item-id', 'name', 'price', 'picture-url', 'item-order'] } constructor() { - super(); - - const shadow = this.#form = this.attachShadow({ mode: "closed" }); - - shadow.innerHTML = ` + super(` - `; + `); } connectedCallback() { @@ -38,13 +36,7 @@ customElements.define('ow-path', class extends HTMLElement { } attributeChangedCallback(name, oldV, newV) { - if (oldV === newV) return; - switch (name) { - case 'selected': - return this.selected = newV; - case 'path': - return this.path = newV; - } + super.attributeChangedCallback(name, oldV, newV); } get selected() { @@ -66,6 +58,6 @@ customElements.define('ow-path', class extends HTMLElement { return; } this.setAttribute('path', value); - this.#form.querySelector('a').setAttribute('href', value); + this.shadowRoot.querySelector('a').setAttribute('href', value); } }); diff --git a/client/src/ow-account.js b/client/src/ow-account.js index 3129f69..70636ba 100644 --- a/client/src/ow-account.js +++ b/client/src/ow-account.js @@ -1,16 +1,14 @@ -import { FORM_STYLE } from "./shared"; - -customElements.define('ow-account', class extends HTMLElement { - #form; +import { Component, FORM_STYLE } from "./shared"; +import './shared/facebook-button'; +import './ow-account/account-view'; +customElements.define('ow-account', class extends Component { static get observedAttributes() { return ['mode', "id", "name", 'email', "facebook-id"] } constructor() { - super(); - const shadow = this.#form = this.attachShadow({ mode: 'closed' }); - shadow.innerHTML = ` + super(` - -
-
- -
-
- - -
-
- - -
-
- - -
-
- `; - shadow.querySelector('#switch-login > a').addEventListener('click', ev => { + + `); + + this.shadowRoot.querySelector('#switch-login > a').addEventListener('click', ev => { ev.stopPropagation(); ev.preventDefault(); this.mode = 'login'; }); - shadow.querySelector('#switch-register > a').addEventListener('click', ev => { + this.shadowRoot.querySelector('#switch-register > a').addEventListener('click', ev => { ev.stopPropagation(); ev.preventDefault(); this.mode = 'register'; }); + this.addEventListener('facebook:account', ev => { + ev.stopPropagation(); + ev.preventDefault(); + this.mode = 'facebook'; + + const { id, name, email } = ev.details; + console.info({ id, name, email }) + // form.querySelector('#email').value = email; + // form.querySelector('#login').value = name; + // form.querySelector('#password').value = crypto.randomUUID(); + // form.querySelector('#facebook_id').value = id; + // form.submit(); + }); } connectedCallback() { if (this.mode === '') this.mode = 'login'; + this.name = this.name; + this.email = this.email; + this.facebook_id = this.facebook_id; } attributeChangedCallback(name, oldV, newV) { - if (oldV === newV) return; - switch (name) { - case 'mode': { - this.mode = newV; - break; - } - case 'id': { - this.id = newV; - break; - } - case 'name': { - this.name = newV; - break; - } - case 'email': { - this.email = newV; - break; - } - case 'facebook-id': { - this.facebook_id = newV; - break; - } - } + super.attributeChangedCallback(name, oldV, newV); } get mode() { @@ -129,7 +105,7 @@ customElements.define('ow-account', class extends HTMLElement { set name(v) { this.setAttribute('name', v); - this.#form.querySelector('#display #name').value = v; + this.shadowRoot.querySelector('account-view').name = v; } get email() { @@ -138,7 +114,7 @@ customElements.define('ow-account', class extends HTMLElement { set email(v) { this.setAttribute('email', v); - this.#form.querySelector('#display #email').value = v; + this.shadowRoot.querySelector('account-view').email = v; } get facebook_id() { @@ -147,6 +123,6 @@ customElements.define('ow-account', class extends HTMLElement { set facebook_id(v) { this.setAttribute('facebook-id', v); - this.#form.querySelector('#display #facebook_id').value = v; + this.shadowRoot.querySelector('account-view').facebook_id = v; } }); diff --git a/client/src/ow-account/account-view.js b/client/src/ow-account/account-view.js new file mode 100644 index 0000000..7b98385 --- /dev/null +++ b/client/src/ow-account/account-view.js @@ -0,0 +1,85 @@ +import { Component, FORM_STYLE } from "../shared"; + +customElements.define('account-view', class extends Component { + static get observedAttributes() { + return ['facebook-id', 'id', 'name', 'email'] + } + + constructor() { + super(` + +
+ +
+
+ + +
+
+ + +
+
+ +

Powiąż z kontem Facebook

+
+
+
+ + +
+ `); + this.addEventListener('facebook:available', ev => { + ev.preventDefault(); + ev.stopPropagation(); + }); + } + + get name() { + return this.getAttribute('name') || ''; + } + + set name(v) { + this.setAttribute('name', v); + this.shadowRoot.querySelector('#name').value = v; + } + + get email() { + return this.getAttribute('email') || ''; + } + + set email(v) { + this.setAttribute('email', v); + this.shadowRoot.querySelector('#email').value = v; + } + + get facebook_id() { + return this.getAttribute('facebook-id'); + } + + set facebook_id(v) { + this.setAttribute('facebook-id', v); + this.shadowRoot.querySelector('#facebook_id').value = v; + } +}); diff --git a/client/src/register-form.js b/client/src/register-form.js index 540d408..7dfe1e6 100644 --- a/client/src/register-form.js +++ b/client/src/register-form.js @@ -1,4 +1,4 @@ -import { S, FORM_STYLE } from "./shared"; +import { S, FORM_STYLE, Component } from "./shared"; import "./register-form/register-basic-form"; import "./register-form/register-item-form-row.js"; @@ -8,15 +8,13 @@ import "./register-form/register-submit-form"; import "./register-form/register-user-type"; import "./register-form/register-user-form"; -customElements.define('register-form', class extends HTMLElement { +customElements.define('register-form', class extends Component { static get observedAttributes() { return ['step'] } constructor() { - super(); - const shadow = this[S] = this.attachShadow({ mode: 'closed' }); - shadow.innerHTML = ` + super(`
@@ -24,12 +18,12 @@ customElements.define('register-business-form', class extends PseudoForm {
- `; + `); - shadow.querySelector('form').addEventListener('submit', ev => { + this.shadowRoot.querySelector('form').addEventListener('submit', ev => { ev.preventDefault(); ev.stopPropagation(); - shadow.querySelector('form-navigation').next(); + this.shadowRoot.querySelector('form-navigation').next(); }); } }) diff --git a/client/src/register-form/register-item-form-row.js b/client/src/register-form/register-item-form-row.js index 529543e..eaa9687 100644 --- a/client/src/register-form/register-item-form-row.js +++ b/client/src/register-form/register-item-form-row.js @@ -1,15 +1,56 @@ import { FORM_STYLE, PseudoForm } from "../shared"; -customElements.define('register-item-form-row', class extends PseudoForm { - #form; +const htmlContent = (idx) => { + return ` + +
+
+ + +
+ + +
+
+ + + +
+
+
+
+ `; +} +customElements.define('register-item-form-row', class extends PseudoForm { static get observedAttributes() { return ['idx', 'name'] } constructor() { - super(); - this.#form = this.attachShadow({ mode: 'closed' }); + super(htmlContent()); this.addEventListener('item:removed', () => { this.setAttribute('removed', 'removed'); @@ -20,62 +61,20 @@ customElements.define('register-item-form-row', class extends PseudoForm { } connectedCallback() { - const idx = this.idx; - - this.#form.innerHTML = ` - -
-
- - -
- - -
-
- - - -
-
-
-
- `; - const imageInput = this.#form.querySelector('image-input'); + this.shadowRoot.innerHTML = htmlContent(this.idx); + const imageInput = this.shadowRoot.querySelector('image-input'); this.addEventListener('image-input:uploaded', ev => { ev.preventDefault(); ev.stopPropagation(); this.picture_url = imageInput.url; }); - this.#form.querySelector('form').addEventListener('submit', ev => { + this.shadowRoot.querySelector('form').addEventListener('submit', ev => { ev.preventDefault(); ev.stopPropagation(); this.reportValidity(); }); - this.#form.querySelector('.remove').addEventListener('click', ev => { + this.shadowRoot.querySelector('.remove').addEventListener('click', ev => { ev.preventDefault(); ev.stopPropagation(); this.dispatchEvent(new CustomEvent('item:removed', { bubbles: true, composed: false })); @@ -85,21 +84,23 @@ customElements.define('register-item-form-row', class extends PseudoForm { attributeChangedCallback(name, oldV, newV) { if (oldV === newV) return; switch (name) { - case 'idx':return this.updateNames(); - case 'picture-url': return this.picture_url = newV; + case 'idx': + return this.updateNames(); + case 'picture-url': + return this.picture_url = newV; } } get inputs() { return [ - extract(this.#form.querySelector('.item-name')), - extract(this.#form.querySelector('.item-price')), + extract(this.shadowRoot.querySelector('.item-name')), + extract(this.shadowRoot.querySelector('.item-price')), ]; } updateNames() { const idx = this.getAttribute('idx'); - for (const el of this.#form.querySelectorAll('.field')) { + for (const el of this.shadowRoot.querySelectorAll('.field')) { const id = el.id; el.querySelector('input, price-input').setAttribute('name', `items[${ idx }][${ id }]`); } @@ -119,12 +120,12 @@ customElements.define('register-item-form-row', class extends PseudoForm { set picture_url(v) { this.setAttribute('picture-url', v); - this.#form.querySelector('image-input').url = v; - this.#form.querySelector('#picture_url').value = v; + this.shadowRoot.querySelector('image-input').url = v; + this.shadowRoot.querySelector('#picture_url').value = v; } reportValidity() { - return super.reportValidity() && this.#form.querySelector('price-input').reportValidity(); + return super.reportValidity() && this.shadowRoot.querySelector('price-input').reportValidity(); } }); diff --git a/client/src/register-form/register-items-form.js b/client/src/register-form/register-items-form.js index 976bc56..80434e4 100644 --- a/client/src/register-form/register-items-form.js +++ b/client/src/register-form/register-items-form.js @@ -11,24 +11,17 @@ const updateItems = (form) => { } customElements.define('register-items-form', class extends PseudoForm { - #form; - - static get observedAttributes() { - return [] - } - constructor() { - super(); - const shadow = this.#form = this.attachShadow({ mode: 'closed' }); - shadow.innerHTML = ` + super(`
@@ -39,7 +32,7 @@ customElements.define('register-items-form', class extends PseudoForm { - `; + `); this.addEventListener('item:removed', ev => { ev.stopPropagation(); updateItems(this) @@ -52,7 +45,7 @@ customElements.define('register-items-form', class extends PseudoForm { } } }); - shadow.querySelector('#add-item').addEventListener('click', ev => { + this.shadowRoot.querySelector('#add-item').addEventListener('click', ev => { ev.stopPropagation(); ev.preventDefault(); this.appendChild(document.createElement('register-item-form-row')); diff --git a/client/src/register-form/register-submit-form.js b/client/src/register-form/register-submit-form.js index adf96a5..7b75742 100644 --- a/client/src/register-form/register-submit-form.js +++ b/client/src/register-form/register-submit-form.js @@ -1,14 +1,8 @@ import { FORM_STYLE, PseudoForm } from "../shared"; customElements.define('register-submit-form', class extends PseudoForm { - #form; - constructor() { - super(); - - const shadow = this.#form = this.attachShadow({ mode: "closed" }); - - shadow.innerHTML = ` + super(` +

Skrypty Facebook są zablokowane przez rozszerzenie przeglądarki

+
+ + + + +
+ `); + + this.shadowRoot.querySelector('#fb-icon').addEventListener('click', ev => { + ev.stopPropagation(); + ev.preventDefault(); + if (!this.#fb_sdk) + return console.info("Facebook SDK is not available"); + FB.login((res) => { + if (res.status === 'connected') { + FB.api("/me?fields=id,name,email", ({ id, name, email }) => { + console.info({ id, name, email }); + this.dispatchEvent(new CustomEvent('facebook:account', { + bubbles: true, composed: true, detail: { + id, name, email + } + })); + }); + } + }, { scope: 'public_profile,email', return_scopes: true }); + }); + } + + connectedCallback() { + super.connectedCallback(); + runFbReady(() => { + this.setAttribute('fb-sdk', 'available'); + this.dispatchEvent(new CustomEvent('facebook:available', { bubbles: true, composed: true })); + }); + } + + get width() { + return this.getAttribute('width') + } + + set width(v) { + this.setAttribute('width', v); + this.shadowRoot.querySelector('svg').setAttribute('width', v); + } + + get height() { + return this.getAttribute('width') + } + + set height(v) { + this.setAttribute('height', v); + this.shadowRoot.querySelector('svg').setAttribute('height', v); + } + + get fb_sdk() { + return !!this.#fb_sdk; + } + + set fb_sdk(v) { + this.setAttribute('fb-sdk', v); + this.#fb_sdk = v === 'available'; + } +}); diff --git a/client/src/shared/image-input.js b/client/src/shared/image-input.js index a016d07..196c6b7 100644 --- a/client/src/shared/image-input.js +++ b/client/src/shared/image-input.js @@ -1,18 +1,12 @@ -import { BUTTON_STYLE, S } from "../shared.js"; - -customElements.define('image-input', class extends HTMLElement { - #form; +import { BUTTON_STYLE, Component, S } from "../shared.js"; +customElements.define('image-input', class extends Component { static get observedAttributes() { return ['width', 'height', "account-id", "url"] } constructor() { - super(); - - const shadow = this.#form = this.attachShadow({ mode: "closed" }); - - shadow.innerHTML = ` + super(`
@@ -45,9 +39,9 @@ customElements.define('image-input', class extends HTMLElement {
- `; + `); - shadow.querySelector('#save').addEventListener('click', ev => { + this.shadowRoot.querySelector('#save').addEventListener('click', ev => { ev.preventDefault(); ev.stopPropagation(); const c = document.createElement('canvas'); @@ -73,10 +67,10 @@ customElements.define('image-input', class extends HTMLElement { }); const f = new FileReader(); - const input = shadow.querySelector('#file'); - const view = shadow.querySelector('#view'); - const img = shadow.querySelector('img'); - const canvas = shadow.querySelector('canvas'); + const input = this.shadowRoot.querySelector('#file'); + const view = this.shadowRoot.querySelector('#view'); + const img = this.shadowRoot.querySelector('img'); + const canvas = this.shadowRoot.querySelector('canvas'); const ctx = canvas.getContext('2d'); img.addEventListener('load', () => { @@ -119,13 +113,7 @@ customElements.define('image-input', class extends HTMLElement { } attributeChangedCallback(name, oldV, newV) { - if (oldV === newV) return; - switch (name) { - case 'account-id': - return this.account_id = newV; - case 'url': - return this.url = newV; - } + super.attributeChangedCallback(name, oldV, newV); } get account_id() { @@ -141,17 +129,25 @@ customElements.define('image-input', class extends HTMLElement { return isNaN(v) ? 0 : v; } + set width(v) { + this.setAttribute('width', v); + } + get height() { const v = parseInt(this.getAttribute('height')); return isNaN(v) ? 0 : v; } + set height(v) { + this.setAttribute('height', v); + } + get url() { return this.getAttribute('url'); } set url(v) { this.setAttribute('url', v); - this.#form.querySelector('img').src = v; + this.shadowRoot.querySelector('img').src = v; } });