@marcoms/make-element
Advanced tools
Comparing version 4.1.1 to 4.1.2
@@ -89,3 +89,2 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
function identity(val) { | ||
// nothing special here | ||
return val; | ||
@@ -104,4 +103,2 @@ } | ||
const methods = def.methods || {}; | ||
// whether the connectedCallback has been run | ||
let hasConnected = false; | ||
let readyFn = noop; | ||
@@ -188,146 +185,146 @@ if (typeof def.ready === 'function') { | ||
const observedAttrs = Object.keys(registeredAttrs); | ||
const DefinableCustomElement = class extends HTMLElement { | ||
constructor() { | ||
super(); | ||
readyFn = readyFn.bind(this); | ||
for (const propName of Object.keys(registeredProps)) { | ||
// convenience aliases | ||
const internalProp = registeredProps[propName]; | ||
const hasLinkedAttr = typeof internalProp.attr === 'string'; | ||
const attrName = internalProp.attr; | ||
const internalAttr = registeredAttrs[attrName]; | ||
// bind property methods to element context | ||
internalProp.toAttr = internalProp.toAttr.bind(this); | ||
internalProp.fromAttr = internalProp.fromAttr.bind(this); | ||
internalProp.get = internalProp.get.bind(this); | ||
internalProp.set = internalProp.set.bind(this); | ||
internalProp.coerce = internalProp.coerce.bind(this); | ||
Object.defineProperty(this, propName, { | ||
set(val) { | ||
let propVal = val; | ||
propVal = internalProp.coerce(propVal); | ||
if (internalProp.settingInitialValue) { | ||
internalProp.settingInitialValue = false; | ||
} | ||
internalProp.val = propVal; | ||
internalProp.set(propVal); | ||
/* | ||
We only propagate from the property to the attribute if: | ||
- A linked attribute was defined | ||
- The property setter is not being triggered by attributeChangedCallback | ||
*/ | ||
const beingInitialized = (this.hasAttribute(attrName) | ||
&& !internalProp.hasSet); | ||
if (hasLinkedAttr && !beingInitialized) { | ||
const attrVal = internalProp.toAttr(propVal); | ||
// prevent the attribute from reflowing back to the | ||
// property in attributeChangedCallback | ||
internalAttr.needsPropagation = false; | ||
if (attrVal !== undefined) { | ||
// invoke attributeChangedCallback | ||
this.setAttribute(attrName, attrVal); | ||
const DefinableCustomElement = (_a = class extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this._hasConnected = false; | ||
this._readyFn = readyFn; | ||
this._props = registeredProps; | ||
this._attrs = registeredAttrs; | ||
for (const propName of Object.keys(this._props)) { | ||
// convenience aliases | ||
const internalProp = this._props[propName]; | ||
const hasLinkedAttr = typeof internalProp.attr === 'string'; | ||
const attrName = internalProp.attr; | ||
const internalAttr = this._attrs[attrName]; | ||
// bind property methods to element context | ||
internalProp.toAttr = internalProp.toAttr.bind(this); | ||
internalProp.fromAttr = internalProp.fromAttr.bind(this); | ||
internalProp.get = internalProp.get.bind(this); | ||
internalProp.set = internalProp.set.bind(this); | ||
internalProp.coerce = internalProp.coerce.bind(this); | ||
Object.defineProperty(this, propName, { | ||
set(val) { | ||
let propVal = val; | ||
propVal = internalProp.coerce(propVal); | ||
if (internalProp.settingInitialValue) { | ||
internalProp.settingInitialValue = false; | ||
} | ||
else { | ||
this.removeAttribute(attrName); | ||
internalProp.val = propVal; | ||
internalProp.set(propVal); | ||
/* | ||
We only propagate from the property to the attribute if: | ||
- A linked attribute was defined | ||
- The property setter is not being triggered by attributeChangedCallback | ||
*/ | ||
const beingInitialized = (this.hasAttribute(attrName) | ||
&& !internalProp.hasSet); | ||
if (hasLinkedAttr && !beingInitialized) { | ||
const attrVal = internalProp.toAttr(propVal); | ||
// prevent the attribute from reflowing back to the | ||
// property in attributeChangedCallback | ||
internalAttr.needsPropagation = false; | ||
if (attrVal !== undefined) { | ||
// invoke attributeChangedCallback | ||
this.setAttribute(attrName, attrVal); | ||
} | ||
else { | ||
this.removeAttribute(attrName); | ||
} | ||
} | ||
} | ||
internalProp.hasSet = true; | ||
}, | ||
get() { | ||
const propVal = internalProp.get(internalProp.val); | ||
return propVal; | ||
}, | ||
}); | ||
} | ||
// insert element template | ||
const hasLocalTemplate = typeof def.template === 'string'; | ||
const hasRemoteTemplate = typeof def.templateUrl === 'string'; | ||
if (def.shadowDom) { | ||
this.attachShadow({ mode: 'open' }); | ||
} | ||
if (hasLocalTemplate) { | ||
internalProp.hasSet = true; | ||
}, | ||
get() { | ||
const propVal = internalProp.get(internalProp.val); | ||
return propVal; | ||
}, | ||
}); | ||
} | ||
// insert element template | ||
const hasLocalTemplate = typeof def.template === 'string'; | ||
const hasRemoteTemplate = typeof def.templateUrl === 'string'; | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = def.template; | ||
this.attachShadow({ mode: 'open' }); | ||
} | ||
else { | ||
this.innerHTML = def.template; | ||
} | ||
} | ||
else if (hasRemoteTemplate) { | ||
fetch(def.templateUrl).then((resp) => { | ||
if (resp.ok) { | ||
// 200 OK | ||
return resp.text(); | ||
if (hasLocalTemplate) { | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = def.template; | ||
} | ||
else { | ||
// 404 et al | ||
throw new Error(`Couldn't fetch template at ${def.templateUrl}. ` + | ||
`Got HTTP status code ${status}`); | ||
this.innerHTML = def.template; | ||
} | ||
}).then((template) => { | ||
} | ||
else if (hasRemoteTemplate) { | ||
fetch(def.templateUrl).then((resp) => { | ||
if (resp.ok) { | ||
// 200 OK | ||
return resp.text(); | ||
} | ||
else { | ||
// 404 et al | ||
throw new Error(`Couldn't fetch template at ${def.templateUrl}. ` + | ||
`Got HTTP status code ${status}`); | ||
} | ||
}).then((template) => { | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = template; | ||
} | ||
else { | ||
this.innerHTML = template; | ||
} | ||
}); | ||
} | ||
// id caching enabled by default | ||
if (def.cacheIds !== false) { | ||
this.$ = {}; | ||
let elsWithIds; | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = template; | ||
elsWithIds = this.shadowRoot.querySelectorAll('[id]'); | ||
} | ||
else { | ||
this.innerHTML = template; | ||
elsWithIds = this.querySelectorAll('[id]'); | ||
} | ||
}); | ||
for (const el of elsWithIds) { | ||
const castEl = el; | ||
this.$[castEl.id] = castEl; | ||
} | ||
} | ||
} | ||
// id caching enabled by default | ||
if (def.cacheIds !== false) { | ||
this.$ = {}; | ||
let elsWithIds; | ||
if (def.shadowDom) { | ||
elsWithIds = this.shadowRoot.querySelectorAll('[id]'); | ||
connectedCallback() { | ||
if (this._hasConnected) { | ||
return; | ||
} | ||
else { | ||
elsWithIds = this.querySelectorAll('[id]'); | ||
// only run once | ||
for (const propName of Object.keys(this._props)) { | ||
const internalProp = this._props[propName]; | ||
// if there is a value but the setter has not run | ||
if (internalProp.val !== undefined | ||
&& internalProp.val !== null | ||
&& !internalProp.hasSet) { | ||
internalProp.settingInitialValue = true; | ||
// kick off property setter | ||
this[propName] = internalProp.val; | ||
} | ||
} | ||
for (const el of elsWithIds) { | ||
const castEl = el; | ||
this.$[castEl.id] = castEl; | ||
} | ||
this._readyFn(); | ||
this._hasConnected = true; | ||
} | ||
} | ||
connectedCallback() { | ||
if (hasConnected) { | ||
return; | ||
} | ||
// only run once | ||
for (const propName of Object.keys(props)) { | ||
const internalProp = registeredProps[propName]; | ||
// if there is a value but the setter has not run | ||
if (internalProp.val !== undefined | ||
&& internalProp.val !== null | ||
&& !internalProp.hasSet) { | ||
internalProp.settingInitialValue = true; | ||
// kick off property setter | ||
this[propName] = internalProp.val; | ||
attributeChangedCallback(attrName, oldVal, val) { | ||
// only do work if the new value differs | ||
if (val !== oldVal) { | ||
// convenience aliases | ||
const internalAttr = this._attrs[attrName]; | ||
internalAttr.val = val; | ||
if (internalAttr.needsPropagation) { | ||
// propagation should only occur once | ||
internalAttr.needsPropagation = false; | ||
const propName = internalAttr.propName; | ||
const internalProp = this._props[propName]; | ||
const propVal = internalProp.fromAttr(val); | ||
this[propName] = propVal; | ||
} | ||
} | ||
} | ||
// invoke ready function with element context | ||
readyFn.call(this); | ||
hasConnected = true; | ||
} | ||
attributeChangedCallback(attrName, oldVal, val) { | ||
// only do work if the new value differs | ||
if (val !== oldVal) { | ||
// convenience aliases | ||
const internalAttr = registeredAttrs[attrName]; | ||
internalAttr.val = val; | ||
if (internalAttr.needsPropagation) { | ||
// propagation should only occur once | ||
internalAttr.needsPropagation = false; | ||
const propName = internalAttr.propName; | ||
const internalProp = registeredProps[propName]; | ||
const propVal = internalProp.fromAttr(val); | ||
this[propName] = propVal; | ||
} | ||
} | ||
} | ||
static get observedAttributes() { | ||
// required for attributeChangedCallback to be called | ||
return observedAttrs; | ||
} | ||
}; | ||
}, | ||
_a.observedAttributes = observedAttrs, | ||
_a); | ||
for (const fnName of Object.keys(methods)) { | ||
@@ -341,2 +338,3 @@ const fn = methods[fnName]; | ||
return DefinableCustomElement; | ||
var _a; | ||
} | ||
@@ -343,0 +341,0 @@ /* harmony default export */ __webpack_exports__["default"] = (makeElement); |
@@ -161,10 +161,15 @@ /******/ (function(modules) { // webpackBootstrap | ||
function identity(val) { | ||
// nothing special here | ||
return val; | ||
} | ||
function convertToBoolAttr(val) { | ||
if (Boolean(val)) { | ||
return ''; | ||
} | ||
else { | ||
return undefined; | ||
} | ||
} | ||
function makeElement(def = {}) { | ||
const props = def.props || {}; | ||
const methods = def.methods || {}; | ||
// whether the connectedCallback has been run | ||
let hasConnected = false; | ||
let readyFn = noop; | ||
@@ -201,5 +206,11 @@ if (typeof def.ready === 'function') { | ||
} | ||
let boolAttr = false; | ||
if (typeof propDef.boolAttr === 'boolean') { | ||
boolAttr = propDef.boolAttr; | ||
} | ||
let toAttr = identity; | ||
if (typeof propDef.toAttr === 'function') { | ||
// this === element instance | ||
if (boolAttr) { | ||
toAttr = convertToBoolAttr; | ||
} | ||
else if (typeof propDef.toAttr === 'function') { | ||
toAttr = propDef.toAttr; | ||
@@ -228,2 +239,3 @@ } | ||
attr: attrName, | ||
boolAttr, | ||
// function used to produce an attribute value from a | ||
@@ -246,141 +258,146 @@ // property value | ||
const observedAttrs = Object.keys(registeredAttrs); | ||
const DefinableCustomElement = class extends HTMLElement { | ||
constructor() { | ||
super(); | ||
readyFn = readyFn.bind(this); | ||
for (const propName of Object.keys(registeredProps)) { | ||
// convenience aliases | ||
const internalProp = registeredProps[propName]; | ||
const hasLinkedAttr = typeof internalProp.attr === 'string'; | ||
const attrName = internalProp.attr; | ||
const internalAttr = registeredAttrs[attrName]; | ||
// bind property methods to element context | ||
internalProp.toAttr = internalProp.toAttr.bind(this); | ||
internalProp.fromAttr = internalProp.fromAttr.bind(this); | ||
internalProp.get = internalProp.get.bind(this); | ||
internalProp.set = internalProp.set.bind(this); | ||
internalProp.coerce = internalProp.coerce.bind(this); | ||
Object.defineProperty(this, propName, { | ||
set(val) { | ||
let propVal = val; | ||
propVal = internalProp.coerce(propVal); | ||
if (internalProp.settingInitialValue) { | ||
internalProp.settingInitialValue = false; | ||
} | ||
internalProp.val = propVal; | ||
internalProp.set(propVal); | ||
/* | ||
We only propagate from the property to the attribute if: | ||
- A linked attribute was defined | ||
- The property setter is not being triggered by attributeChangedCallback | ||
*/ | ||
const beingInitialized = (this.hasAttribute(attrName) | ||
&& !internalProp.hasSet); | ||
if (hasLinkedAttr && !beingInitialized) { | ||
const attrVal = internalProp.toAttr(propVal); | ||
// prevent the attribute from reflowing back to the | ||
// property in attributeChangedCallback | ||
internalAttr.needsPropagation = false; | ||
// invoke attributeChangedCallback | ||
this.setAttribute(attrName, attrVal); | ||
} | ||
internalProp.hasSet = true; | ||
}, | ||
get() { | ||
const propVal = internalProp.get(internalProp.val); | ||
return propVal; | ||
}, | ||
}); | ||
} | ||
// insert element template | ||
const hasLocalTemplate = typeof def.template === 'string'; | ||
const hasRemoteTemplate = typeof def.templateUrl === 'string'; | ||
if (def.shadowDom) { | ||
this.attachShadow({ mode: 'open' }); | ||
} | ||
if (hasLocalTemplate) { | ||
const DefinableCustomElement = (_a = class extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this._hasConnected = false; | ||
this._readyFn = readyFn; | ||
this._props = registeredProps; | ||
this._attrs = registeredAttrs; | ||
for (const propName of Object.keys(this._props)) { | ||
// convenience aliases | ||
const internalProp = this._props[propName]; | ||
const hasLinkedAttr = typeof internalProp.attr === 'string'; | ||
const attrName = internalProp.attr; | ||
const internalAttr = this._attrs[attrName]; | ||
// bind property methods to element context | ||
internalProp.toAttr = internalProp.toAttr.bind(this); | ||
internalProp.fromAttr = internalProp.fromAttr.bind(this); | ||
internalProp.get = internalProp.get.bind(this); | ||
internalProp.set = internalProp.set.bind(this); | ||
internalProp.coerce = internalProp.coerce.bind(this); | ||
Object.defineProperty(this, propName, { | ||
set(val) { | ||
let propVal = val; | ||
propVal = internalProp.coerce(propVal); | ||
if (internalProp.settingInitialValue) { | ||
internalProp.settingInitialValue = false; | ||
} | ||
internalProp.val = propVal; | ||
internalProp.set(propVal); | ||
/* | ||
We only propagate from the property to the attribute if: | ||
- A linked attribute was defined | ||
- The property setter is not being triggered by attributeChangedCallback | ||
*/ | ||
const beingInitialized = (this.hasAttribute(attrName) | ||
&& !internalProp.hasSet); | ||
if (hasLinkedAttr && !beingInitialized) { | ||
const attrVal = internalProp.toAttr(propVal); | ||
// prevent the attribute from reflowing back to the | ||
// property in attributeChangedCallback | ||
internalAttr.needsPropagation = false; | ||
if (attrVal !== undefined) { | ||
// invoke attributeChangedCallback | ||
this.setAttribute(attrName, attrVal); | ||
} | ||
else { | ||
this.removeAttribute(attrName); | ||
} | ||
} | ||
internalProp.hasSet = true; | ||
}, | ||
get() { | ||
const propVal = internalProp.get(internalProp.val); | ||
return propVal; | ||
}, | ||
}); | ||
} | ||
// insert element template | ||
const hasLocalTemplate = typeof def.template === 'string'; | ||
const hasRemoteTemplate = typeof def.templateUrl === 'string'; | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = def.template; | ||
this.attachShadow({ mode: 'open' }); | ||
} | ||
else { | ||
this.innerHTML = def.template; | ||
} | ||
} | ||
else if (hasRemoteTemplate) { | ||
fetch(def.templateUrl).then((resp) => { | ||
if (resp.ok) { | ||
// 200 OK | ||
return resp.text(); | ||
if (hasLocalTemplate) { | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = def.template; | ||
} | ||
else { | ||
// 404 et al | ||
throw new Error(`Couldn't fetch template at ${def.templateUrl}. ` + | ||
`Got HTTP status code ${status}`); | ||
this.innerHTML = def.template; | ||
} | ||
}).then((template) => { | ||
} | ||
else if (hasRemoteTemplate) { | ||
fetch(def.templateUrl).then((resp) => { | ||
if (resp.ok) { | ||
// 200 OK | ||
return resp.text(); | ||
} | ||
else { | ||
// 404 et al | ||
throw new Error(`Couldn't fetch template at ${def.templateUrl}. ` + | ||
`Got HTTP status code ${status}`); | ||
} | ||
}).then((template) => { | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = template; | ||
} | ||
else { | ||
this.innerHTML = template; | ||
} | ||
}); | ||
} | ||
// id caching enabled by default | ||
if (def.cacheIds !== false) { | ||
this.$ = {}; | ||
let elsWithIds; | ||
if (def.shadowDom) { | ||
this.shadowRoot.innerHTML = template; | ||
elsWithIds = this.shadowRoot.querySelectorAll('[id]'); | ||
} | ||
else { | ||
this.innerHTML = template; | ||
elsWithIds = this.querySelectorAll('[id]'); | ||
} | ||
}); | ||
for (const el of elsWithIds) { | ||
const castEl = el; | ||
this.$[castEl.id] = castEl; | ||
} | ||
} | ||
} | ||
// id caching enabled by default | ||
if (def.cacheIds !== false) { | ||
this.$ = {}; | ||
let elsWithIds; | ||
if (def.shadowDom) { | ||
elsWithIds = this.shadowRoot.querySelectorAll('[id]'); | ||
connectedCallback() { | ||
if (this._hasConnected) { | ||
return; | ||
} | ||
else { | ||
elsWithIds = this.querySelectorAll('[id]'); | ||
// only run once | ||
for (const propName of Object.keys(this._props)) { | ||
const internalProp = this._props[propName]; | ||
// if there is a value but the setter has not run | ||
if (internalProp.val !== undefined | ||
&& internalProp.val !== null | ||
&& !internalProp.hasSet) { | ||
internalProp.settingInitialValue = true; | ||
// kick off property setter | ||
this[propName] = internalProp.val; | ||
} | ||
} | ||
for (const el of elsWithIds) { | ||
const castEl = el; | ||
this.$[castEl.id] = castEl; | ||
} | ||
this._readyFn(); | ||
this._hasConnected = true; | ||
} | ||
} | ||
connectedCallback() { | ||
if (hasConnected) { | ||
return; | ||
} | ||
// only run once | ||
for (const propName of Object.keys(props)) { | ||
const internalProp = registeredProps[propName]; | ||
// if there is a value but the setter has not run | ||
if (internalProp.val !== undefined | ||
&& internalProp.val !== null | ||
&& !internalProp.hasSet) { | ||
internalProp.settingInitialValue = true; | ||
// kick off property setter | ||
this[propName] = internalProp.val; | ||
attributeChangedCallback(attrName, oldVal, val) { | ||
// only do work if the new value differs | ||
if (val !== oldVal) { | ||
// convenience aliases | ||
const internalAttr = this._attrs[attrName]; | ||
internalAttr.val = val; | ||
if (internalAttr.needsPropagation) { | ||
// propagation should only occur once | ||
internalAttr.needsPropagation = false; | ||
const propName = internalAttr.propName; | ||
const internalProp = this._props[propName]; | ||
const propVal = internalProp.fromAttr(val); | ||
this[propName] = propVal; | ||
} | ||
} | ||
} | ||
// invoke ready function with element context | ||
readyFn.call(this); | ||
hasConnected = true; | ||
} | ||
attributeChangedCallback(attrName, oldVal, val) { | ||
// only do work if the new value differs | ||
if (val !== oldVal) { | ||
// convenience aliases | ||
const internalAttr = registeredAttrs[attrName]; | ||
internalAttr.val = val; | ||
if (internalAttr.needsPropagation) { | ||
// propagation should only occur once | ||
internalAttr.needsPropagation = false; | ||
const propName = internalAttr.propName; | ||
const internalProp = registeredProps[propName]; | ||
const propVal = internalProp.fromAttr(val); | ||
this[propName] = propVal; | ||
} | ||
} | ||
} | ||
static get observedAttributes() { | ||
// required for attributeChangedCallback to be called | ||
return observedAttrs; | ||
} | ||
}; | ||
}, | ||
_a.observedAttributes = observedAttrs, | ||
_a); | ||
for (const fnName of Object.keys(methods)) { | ||
@@ -394,2 +411,3 @@ const fn = methods[fnName]; | ||
return DefinableCustomElement; | ||
var _a; | ||
} | ||
@@ -396,0 +414,0 @@ /* harmony default export */ __webpack_exports__["default"] = (makeElement); |
{ | ||
"name": "@marcoms/make-element", | ||
"version": "4.1.1", | ||
"version": "4.1.2", | ||
"description": "Create custom elements without boilerplate", | ||
@@ -21,3 +21,12 @@ "main": "build/make-element.js", | ||
"devDependencies": { | ||
"@types/chai": "^4.0.1", | ||
"@types/mocha": "^2.2.41", | ||
"chai": "^4.1.0", | ||
"eslint": "^3.15.0", | ||
"karma": "^1.7.0", | ||
"karma-chrome-launcher": "^2.2.0", | ||
"karma-mocha": "^1.3.0", | ||
"karma-mocha-reporter": "^2.2.3", | ||
"karma-typescript": "^3.0.4", | ||
"mocha": "^3.4.2", | ||
"ts-loader": "^2.2.2", | ||
@@ -24,0 +33,0 @@ "typescript": "^2.4.1" |
@@ -0,1 +1,10 @@ | ||
export interface ArbitraryFn { (...args: any[]): any; } | ||
export interface GetFn { (val: any): void; } | ||
export interface SetFn { (val: any): any; } | ||
export interface CoerceFn { (val: any): any; } | ||
export interface FromAttrFn { (val: string): any; } | ||
export interface ToAttrFn { (val: any): string; } | ||
type ReadyFn = ArbitraryFn; | ||
export interface ElementDef { | ||
@@ -8,3 +17,3 @@ props?: PropDefs; | ||
methods?: MethodsDef; | ||
ready?: ArbitraryFn; | ||
ready?: ReadyFn; | ||
} | ||
@@ -27,9 +36,2 @@ | ||
export interface ArbitraryFn { (...args: any[]): any; } | ||
export interface GetFn { (val: any): void; } | ||
export interface SetFn { (val: any): any; } | ||
export interface CoerceFn { (val: any): any; } | ||
export interface FromAttrFn { (val: string): any; } | ||
export interface ToAttrFn { (val: any): string; } | ||
export interface MethodsDef { | ||
@@ -49,2 +51,3 @@ [index: string]: ArbitraryFn; | ||
$: IdMap; | ||
[index: string]: any; | ||
} | ||
@@ -90,8 +93,7 @@ | ||
function consume(val: any) {} | ||
function identity(val: any) { | ||
// nothing special here | ||
function identity<T>(val: T): T { | ||
return val; | ||
} | ||
function convertToBoolAttr(val) { | ||
function convertToBoolAttr(val: any): string | undefined { | ||
if (Boolean(val)) { | ||
@@ -108,5 +110,2 @@ return ''; | ||
// whether the connectedCallback has been run | ||
let hasConnected = false; | ||
let readyFn = noop; | ||
@@ -159,3 +158,3 @@ if (typeof def.ready === 'function') { | ||
let toAttr = identity; | ||
let toAttr: ToAttrFn = identity; | ||
if (boolAttr) { | ||
@@ -167,3 +166,3 @@ toAttr = convertToBoolAttr; | ||
let fromAttr = identity; | ||
let fromAttr: FromAttrFn = identity; | ||
if (typeof propDef.fromAttr === 'function') { | ||
@@ -173,3 +172,3 @@ fromAttr = propDef.fromAttr; | ||
let get = identity; | ||
let get: GetFn = identity; | ||
if (typeof propDef.get === 'function') { | ||
@@ -179,3 +178,3 @@ get = propDef.get; | ||
let set = consume; | ||
let set: SetFn = consume; | ||
if (typeof propDef.set === 'function') { | ||
@@ -185,3 +184,3 @@ set = propDef.set; | ||
let coerce = identity; | ||
let coerce: CoerceFn = identity; | ||
if (typeof propDef.coerce === 'function') { | ||
@@ -225,15 +224,20 @@ coerce = propDef.coerce; | ||
const DefinableCustomElement: CustomElementClass = class extends HTMLElement { | ||
static observedAttributes = observedAttrs; | ||
$: IdMap; | ||
private _hasConnected: boolean = false; | ||
private _readyFn: ReadyFn = readyFn; | ||
private _props: RegisteredProps = registeredProps; | ||
private _attrs: RegisteredAttrs = registeredAttrs; | ||
constructor() { | ||
super(); | ||
readyFn = readyFn.bind(this); | ||
for (const propName of Object.keys(registeredProps)) { | ||
for (const propName of Object.keys(this._props)) { | ||
// convenience aliases | ||
const internalProp = registeredProps[propName] as InternalProp; | ||
const internalProp = this._props[propName] as InternalProp; | ||
const hasLinkedAttr = typeof internalProp.attr === 'string'; | ||
const attrName = internalProp.attr; | ||
const internalAttr = registeredAttrs[attrName] as InternalAttr; | ||
const internalAttr = this._attrs[attrName] as InternalAttr; | ||
@@ -351,3 +355,3 @@ // bind property methods to element context | ||
connectedCallback() { | ||
if (hasConnected) { | ||
if (this._hasConnected) { | ||
return; | ||
@@ -358,4 +362,4 @@ } | ||
for (const propName of Object.keys(props)) { | ||
const internalProp = registeredProps[propName] as InternalProp; | ||
for (const propName of Object.keys(this._props)) { | ||
const internalProp = this._props[propName] as InternalProp; | ||
@@ -376,6 +380,4 @@ // if there is a value but the setter has not run | ||
// invoke ready function with element context | ||
readyFn.call(this); | ||
hasConnected = true; | ||
this._readyFn(); | ||
this._hasConnected = true; | ||
} | ||
@@ -387,3 +389,3 @@ | ||
// convenience aliases | ||
const internalAttr = registeredAttrs[attrName] as InternalAttr; | ||
const internalAttr = this._attrs[attrName] as InternalAttr; | ||
internalAttr.val = val; | ||
@@ -396,3 +398,3 @@ | ||
const propName = internalAttr.propName; | ||
const internalProp = registeredProps[propName] as InternalProp; | ||
const internalProp = this._props[propName] as InternalProp; | ||
@@ -404,7 +406,2 @@ const propVal = internalProp.fromAttr(val); | ||
} | ||
static get observedAttributes() { | ||
// required for attributeChangedCallback to be called | ||
return observedAttrs; | ||
} | ||
}; | ||
@@ -411,0 +408,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
207145
18
1270
12