UNPKG

@joist/element

Version:

Intelligently apply styles to WebComponents

365 lines 20.8 kB
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); var _, done = false; for (var i = decorators.length - 1; i >= 0; i--) { var context = {}; for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; for (var p in contextIn.access) context.access[p] = contextIn.access[p]; context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); if (kind === "accessor") { if (result === void 0) continue; if (result === null || typeof result !== "object") throw new TypeError("Object expected"); if (_ = accept(result.get)) descriptor.get = _; if (_ = accept(result.set)) descriptor.set = _; if (_ = accept(result.init)) initializers.unshift(_); } else if (_ = accept(result)) { if (kind === "field") initializers.unshift(_); else descriptor[key] = _; } } if (target) Object.defineProperty(target, contextIn.name, descriptor); done = true; }; var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { var useValue = arguments.length > 2; for (var i = 0; i < initializers.length; i++) { value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } return useValue ? value : void 0; }; import { assert, expect } from "chai"; import { attr } from "./attr.js"; import { element } from "./element.js"; import { css, html } from "./tags.js"; it("should write default value to attribute", async () => { let MyElement = (() => { let _classDecorators = [element({ tagName: "element-1", })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; let _value1_decorators; let _value1_initializers = []; let _value1_extraInitializers = []; let _value2_decorators; let _value2_initializers = []; let _value2_extraInitializers = []; let _value3_decorators; let _value3_initializers = []; let _value3_extraInitializers = []; let _value4_decorators; let _value4_initializers = []; let _value4_extraInitializers = []; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _value1_decorators = [attr()]; _value2_decorators = [attr()]; _value3_decorators = [attr()]; _value4_decorators = [attr({ reflect: false })]; __esDecorate(this, null, _value1_decorators, { kind: "accessor", name: "value1", static: false, private: false, access: { has: obj => "value1" in obj, get: obj => obj.value1, set: (obj, value) => { obj.value1 = value; } }, metadata: _metadata }, _value1_initializers, _value1_extraInitializers); __esDecorate(this, null, _value2_decorators, { kind: "accessor", name: "value2", static: false, private: false, access: { has: obj => "value2" in obj, get: obj => obj.value2, set: (obj, value) => { obj.value2 = value; } }, metadata: _metadata }, _value2_initializers, _value2_extraInitializers); __esDecorate(this, null, _value3_decorators, { kind: "accessor", name: "value3", static: false, private: false, access: { has: obj => "value3" in obj, get: obj => obj.value3, set: (obj, value) => { obj.value3 = value; } }, metadata: _metadata }, _value3_initializers, _value3_extraInitializers); __esDecorate(this, null, _value4_decorators, { kind: "accessor", name: "value4", static: false, private: false, access: { has: obj => "value4" in obj, get: obj => obj.value4, set: (obj, value) => { obj.value4 = value; } }, metadata: _metadata }, _value4_initializers, _value4_extraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } #value1_accessor_storage = __runInitializers(this, _value1_initializers, "hello"); get value1() { return this.#value1_accessor_storage; } // no attribute set value1(value) { this.#value1_accessor_storage = value; } #value2_accessor_storage = (__runInitializers(this, _value1_extraInitializers), __runInitializers(this, _value2_initializers, 0)); get value2() { return this.#value2_accessor_storage; } // number set value2(value) { this.#value2_accessor_storage = value; } #value3_accessor_storage = (__runInitializers(this, _value2_extraInitializers), __runInitializers(this, _value3_initializers, true)); get value3() { return this.#value3_accessor_storage; } // boolean set value3(value) { this.#value3_accessor_storage = value; } #value4_accessor_storage = (__runInitializers(this, _value3_extraInitializers), __runInitializers(this, _value4_initializers, "foo")); get value4() { return this.#value4_accessor_storage; } set value4(value) { this.#value4_accessor_storage = value; } constructor() { super(...arguments); __runInitializers(this, _value4_extraInitializers); } }; return MyElement = _classThis; })(); const el = new MyElement(); document.body.append(el); expect(el.getAttribute("value1")).to.equal("hello"); expect(el.getAttribute("value2")).to.equal("0"); expect(el.getAttribute("value3")).to.equal(""); expect(el.getAttribute("value4")).to.equal(null); el.remove(); }); it("should register attributes", async () => { const observedAttrs = []; let MyElement = (() => { let _classDecorators = [element({ tagName: "element-2", })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; let _value1_decorators; let _value1_initializers = []; let _value1_extraInitializers = []; let _value2_decorators; let _value2_initializers = []; let _value2_extraInitializers = []; let _value3_decorators; let _value3_initializers = []; let _value3_extraInitializers = []; let _value4_decorators; let _value4_initializers = []; let _value4_extraInitializers = []; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _value1_decorators = [attr()]; _value2_decorators = [attr()]; _value3_decorators = [attr()]; _value4_decorators = [attr({ observed: false })]; __esDecorate(this, null, _value1_decorators, { kind: "accessor", name: "value1", static: false, private: false, access: { has: obj => "value1" in obj, get: obj => obj.value1, set: (obj, value) => { obj.value1 = value; } }, metadata: _metadata }, _value1_initializers, _value1_extraInitializers); __esDecorate(this, null, _value2_decorators, { kind: "accessor", name: "value2", static: false, private: false, access: { has: obj => "value2" in obj, get: obj => obj.value2, set: (obj, value) => { obj.value2 = value; } }, metadata: _metadata }, _value2_initializers, _value2_extraInitializers); __esDecorate(this, null, _value3_decorators, { kind: "accessor", name: "value3", static: false, private: false, access: { has: obj => "value3" in obj, get: obj => obj.value3, set: (obj, value) => { obj.value3 = value; } }, metadata: _metadata }, _value3_initializers, _value3_extraInitializers); __esDecorate(this, null, _value4_decorators, { kind: "accessor", name: "value4", static: false, private: false, access: { has: obj => "value4" in obj, get: obj => obj.value4, set: (obj, value) => { obj.value4 = value; } }, metadata: _metadata }, _value4_initializers, _value4_extraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } #value1_accessor_storage = __runInitializers(this, _value1_initializers, "hello"); get value1() { return this.#value1_accessor_storage; } set value1(value) { this.#value1_accessor_storage = value; } #value2_accessor_storage = (__runInitializers(this, _value1_extraInitializers), __runInitializers(this, _value2_initializers, 0)); get value2() { return this.#value2_accessor_storage; } set value2(value) { this.#value2_accessor_storage = value; } #value3_accessor_storage = (__runInitializers(this, _value2_extraInitializers), __runInitializers(this, _value3_initializers, true)); get value3() { return this.#value3_accessor_storage; } set value3(value) { this.#value3_accessor_storage = value; } #value4_accessor_storage = (__runInitializers(this, _value3_extraInitializers), __runInitializers(this, _value4_initializers, "hello world")); get value4() { return this.#value4_accessor_storage; } set value4(value) { this.#value4_accessor_storage = value; } attributeChangedCallback(name) { observedAttrs.push(name); } constructor() { super(...arguments); __runInitializers(this, _value4_extraInitializers); } }; return MyElement = _classThis; })(); const el = new MyElement(); el.setAttribute("value1", "foo"); el.setAttribute("value2", "1"); el.setAttribute("value3", "false"); el.setAttribute("value4", "bar"); expect(observedAttrs).to.deep.equal(["value1", "value2", "value3"]); }); it("should attach shadow root when the shadow property exists", async () => { let MyElement = (() => { let _classDecorators = [element({ tagName: "element-3", shadowDom: [], })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } }; return MyElement = _classThis; })(); const el = new MyElement(); expect(el.shadowRoot).to.be.instanceOf(ShadowRoot); }); it("should apply html and css", async () => { let MyElement = (() => { let _classDecorators = [element({ tagName: "element-4", shadowDom: [ css ` :host { display: contents; } `, html `<slot></slot>`, { apply(el) { const div = document.createElement("div"); div.innerHTML = "hello world"; el.append(div); }, }, ], })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } }; return MyElement = _classThis; })(); const el = new MyElement(); expect(el.shadowRoot?.adoptedStyleSheets.length).to.equal(1); expect(el.shadowRoot?.innerHTML).to.equal("<slot></slot>"); expect(el.innerHTML).to.equal("<div>hello world</div>"); }); it("should the correct shadow dom mode", async () => { let MyElement = (() => { let _classDecorators = [element({ tagName: "element-5", shadowDom: [], shadowDomOpts: { mode: "closed", }, })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } }; return MyElement = _classThis; })(); const el = new MyElement(); assert.equal(el.shadowRoot, null); }); it("should wait to register itself until all elements it depends on are also registered", async () => { let MyElement6 = (() => { let _classDecorators = [element({ tagName: "element-6", dependsOn: ["element-7", "element-8"], })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; var MyElement6 = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement6 = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } }; return MyElement6 = _classThis; })(); assert.isUndefined(customElements.get("element-6")); customElements.define("element-7", class extends HTMLElement { }); customElements.define("element-8", class extends HTMLElement { }); await Promise.all([ customElements.whenDefined("element-7"), customElements.whenDefined("element-8"), ]); assert.equal(customElements.get("element-6"), MyElement6); }); it("should wait to register itself until the custom dependsOn function runs", async () => { let resolver; let MyElement = (() => { let _classDecorators = [element({ tagName: "element-9", dependsOn() { return new Promise((resolve) => { resolver = resolve; }); }, })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } }; return MyElement = _classThis; })(); assert.isUndefined(customElements.get("element-9")); resolver(); await Promise.resolve(); assert.equal(customElements.get("element-9"), MyElement); }); it("should call disconnectedCallback when element is removed from DOM", async () => { let disconnectedCalled = false; let MyElement = (() => { let _classDecorators = [element({ tagName: "element-10", })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = HTMLElement; var MyElement = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyElement = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } disconnectedCallback() { disconnectedCalled = true; } }; return MyElement = _classThis; })(); const el = new MyElement(); document.body.append(el); // Verify element is connected expect(disconnectedCalled).to.be.false; // Remove element from DOM el.remove(); // Verify disconnectedCallback was called expect(disconnectedCalled).to.be.true; }); //# sourceMappingURL=element.test.js.map