改用lit-core二次开发
parent
880e355396
commit
dded36fb09
|
@ -5,3 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const finalize = Symbol('finalize')
|
export const finalize = Symbol('finalize')
|
||||||
|
|
||||||
|
export const RESET_CSS_STYLE = `
|
||||||
|
* {box-sizing: border-box;margin: 0;padding: 0;}
|
||||||
|
::before,::after {box-sizing: border-box;}
|
||||||
|
`
|
||||||
|
|
16
src/css.js
16
src/css.js
|
@ -4,22 +4,10 @@
|
||||||
* @date 2023/03/06 16:27:49
|
* @date 2023/03/06 16:27:49
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const RESET_CSS_STYLE = css`
|
import { RESET_CSS_STYLE } from './constants.js'
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
::before,
|
|
||||||
::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export function css(strs, ...args) {
|
export function css(strs, ...args) {
|
||||||
let output = `
|
let output = ''
|
||||||
|
|
||||||
`
|
|
||||||
let tmp = Array.from(strs)
|
let tmp = Array.from(strs)
|
||||||
while (tmp.length) {
|
while (tmp.length) {
|
||||||
output += tmp.shift() + (args.shift() || '')
|
output += tmp.shift() + (args.shift() || '')
|
||||||
|
|
939
src/html.js
939
src/html.js
|
@ -1,32 +1,925 @@
|
||||||
export function html(strs, ...args) {
|
var ENABLE_EXTRA_SECURITY_HOOKS = true
|
||||||
let output = ''
|
var global3 = window
|
||||||
let tmp = Array.from(strs)
|
var debugLogEvent2 = void 0
|
||||||
// console.log(tmp, args)
|
var debugLogRenderId = 0
|
||||||
|
var issueWarning2
|
||||||
|
|
||||||
while (tmp.length) {
|
var wrap = node => node
|
||||||
let _ = args.shift()
|
|
||||||
switch (typeof _) {
|
var identityFunction = value => value
|
||||||
case 'function':
|
var noopSanitizer = (_node, _name, _type) => identityFunction
|
||||||
console.log([_], _.name)
|
var setSanitizer = newSanitizer => {
|
||||||
_ = _.name
|
if (!ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
break
|
return
|
||||||
case 'object':
|
|
||||||
if (Array.isArray(_)) {
|
|
||||||
_ = _.join('')
|
|
||||||
}
|
}
|
||||||
|
if (sanitizerFactoryInternal !== noopSanitizer) {
|
||||||
|
throw new Error(
|
||||||
|
`Attempted to overwrite existing lit-html security policy. setSanitizeDOMValueFactory should be called at most once.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sanitizerFactoryInternal = newSanitizer
|
||||||
|
}
|
||||||
|
var _testOnlyClearSanitizerFactoryDoNotCallOrElse = () => {
|
||||||
|
sanitizerFactoryInternal = noopSanitizer
|
||||||
|
}
|
||||||
|
var createSanitizer = (node, name, type) => {
|
||||||
|
return sanitizerFactoryInternal(node, name, type)
|
||||||
|
}
|
||||||
|
var boundAttributeSuffix = '$wc$'
|
||||||
|
var marker = `wc$${String(Math.random()).slice(9)}$`
|
||||||
|
var markerMatch = '?' + marker
|
||||||
|
var nodeMarker = `<${markerMatch}>`
|
||||||
|
var d = document
|
||||||
|
var createMarker = (v = '') => d.createComment(v)
|
||||||
|
var isPrimitive = value =>
|
||||||
|
value === null || (typeof value != 'object' && typeof value != 'function')
|
||||||
|
var isArray = Array.isArray
|
||||||
|
var isIterable = value =>
|
||||||
|
isArray(value) ||
|
||||||
|
typeof (value === null || value === void 0
|
||||||
|
? void 0
|
||||||
|
: value[Symbol.iterator]) === 'function'
|
||||||
|
var SPACE_CHAR = `[
|
||||||
|
\f\r]`
|
||||||
|
var ATTR_VALUE_CHAR = `[^
|
||||||
|
\f\r"'\`<>=]`
|
||||||
|
var NAME_CHAR = `[^\\s"'>=/]`
|
||||||
|
var textEndRegex = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g
|
||||||
|
var COMMENT_START = 1
|
||||||
|
var TAG_NAME = 2
|
||||||
|
var DYNAMIC_TAG_NAME = 3
|
||||||
|
var commentEndRegex = /-->/g
|
||||||
|
var comment2EndRegex = />/g
|
||||||
|
var tagEndRegex = new RegExp(
|
||||||
|
`>|${SPACE_CHAR}(?:(${NAME_CHAR}+)(${SPACE_CHAR}*=${SPACE_CHAR}*(?:${ATTR_VALUE_CHAR}|("|')|))|$)`,
|
||||||
|
'g'
|
||||||
|
)
|
||||||
|
var ENTIRE_MATCH = 0
|
||||||
|
var ATTRIBUTE_NAME = 1
|
||||||
|
var SPACES_AND_EQUALS = 2
|
||||||
|
var QUOTE_CHAR = 3
|
||||||
|
var singleQuoteAttrEndRegex = /'/g
|
||||||
|
var doubleQuoteAttrEndRegex = /"/g
|
||||||
|
var rawTextElement = /^(?:script|style|textarea|title)$/i
|
||||||
|
var HTML_RESULT = 1
|
||||||
|
var SVG_RESULT = 2
|
||||||
|
var ATTRIBUTE_PART = 1
|
||||||
|
var CHILD_PART = 2
|
||||||
|
var PROPERTY_PART = 3
|
||||||
|
var BOOLEAN_ATTRIBUTE_PART = 4
|
||||||
|
var EVENT_PART = 5
|
||||||
|
var ELEMENT_PART = 6
|
||||||
|
var COMMENT_PART = 7
|
||||||
|
var tag =
|
||||||
|
type =>
|
||||||
|
(strings, ...values) => {
|
||||||
|
return {
|
||||||
|
__dom_type__: type,
|
||||||
|
strings,
|
||||||
|
values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const html = tag(HTML_RESULT)
|
||||||
|
export const svg = tag(SVG_RESULT)
|
||||||
|
var noChange = Symbol.for('wc-noChange')
|
||||||
|
var nothing = Symbol.for('wc-nothing')
|
||||||
|
var templateCache = /* @__PURE__ */ new WeakMap()
|
||||||
|
var walker = d.createTreeWalker(d, 129, null, false)
|
||||||
|
var sanitizerFactoryInternal = noopSanitizer
|
||||||
|
var getTemplateHtml = (strings, type) => {
|
||||||
|
const l = strings.length - 1
|
||||||
|
const attrNames = []
|
||||||
|
let html2 = type === SVG_RESULT ? '<svg>' : ''
|
||||||
|
let rawTextEndRegex
|
||||||
|
let regex = textEndRegex
|
||||||
|
for (let i = 0; i < l; i++) {
|
||||||
|
const s = strings[i]
|
||||||
|
let attrNameEndIndex = -1
|
||||||
|
let attrName
|
||||||
|
let lastIndex = 0
|
||||||
|
let match
|
||||||
|
while (lastIndex < s.length) {
|
||||||
|
regex.lastIndex = lastIndex
|
||||||
|
match = regex.exec(s)
|
||||||
|
if (match === null) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
output += tmp.shift() + (_ === void 0 ? '' : _)
|
lastIndex = regex.lastIndex
|
||||||
|
if (regex === textEndRegex) {
|
||||||
|
if (match[COMMENT_START] === '!--') {
|
||||||
|
regex = commentEndRegex
|
||||||
|
} else if (match[COMMENT_START] !== void 0) {
|
||||||
|
regex = comment2EndRegex
|
||||||
|
} else if (match[TAG_NAME] !== void 0) {
|
||||||
|
if (rawTextElement.test(match[TAG_NAME])) {
|
||||||
|
rawTextEndRegex = new RegExp(`</${match[TAG_NAME]}`, 'g')
|
||||||
|
}
|
||||||
|
regex = tagEndRegex
|
||||||
|
} else if (match[DYNAMIC_TAG_NAME] !== void 0) {
|
||||||
|
regex = tagEndRegex
|
||||||
|
}
|
||||||
|
} else if (regex === tagEndRegex) {
|
||||||
|
if (match[ENTIRE_MATCH] === '>') {
|
||||||
|
regex =
|
||||||
|
rawTextEndRegex !== null && rawTextEndRegex !== void 0
|
||||||
|
? rawTextEndRegex
|
||||||
|
: textEndRegex
|
||||||
|
attrNameEndIndex = -1
|
||||||
|
} else if (match[ATTRIBUTE_NAME] === void 0) {
|
||||||
|
attrNameEndIndex = -2
|
||||||
|
} else {
|
||||||
|
attrNameEndIndex = regex.lastIndex - match[SPACES_AND_EQUALS].length
|
||||||
|
attrName = match[ATTRIBUTE_NAME]
|
||||||
|
regex =
|
||||||
|
match[QUOTE_CHAR] === void 0
|
||||||
|
? tagEndRegex
|
||||||
|
: match[QUOTE_CHAR] === '"'
|
||||||
|
? doubleQuoteAttrEndRegex
|
||||||
|
: singleQuoteAttrEndRegex
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
regex === doubleQuoteAttrEndRegex ||
|
||||||
|
regex === singleQuoteAttrEndRegex
|
||||||
|
) {
|
||||||
|
regex = tagEndRegex
|
||||||
|
} else if (regex === commentEndRegex || regex === comment2EndRegex) {
|
||||||
|
regex = textEndRegex
|
||||||
|
} else {
|
||||||
|
regex = tagEndRegex
|
||||||
|
rawTextEndRegex = void 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const end =
|
||||||
|
regex === tagEndRegex && strings[i + 1].startsWith('/>') ? ' ' : ''
|
||||||
|
html2 +=
|
||||||
|
regex === textEndRegex
|
||||||
|
? s + nodeMarker
|
||||||
|
: attrNameEndIndex >= 0
|
||||||
|
? (attrNames.push(attrName),
|
||||||
|
s.slice(0, attrNameEndIndex) +
|
||||||
|
boundAttributeSuffix +
|
||||||
|
s.slice(attrNameEndIndex)) +
|
||||||
|
marker +
|
||||||
|
end
|
||||||
|
: s +
|
||||||
|
marker +
|
||||||
|
(attrNameEndIndex === -2 ? (attrNames.push(void 0), i) : end)
|
||||||
|
}
|
||||||
|
const htmlResult =
|
||||||
|
html2 + (strings[l] || '<?>') + (type === SVG_RESULT ? '</svg>' : '')
|
||||||
|
if (!Array.isArray(strings) || !strings.hasOwnProperty('raw')) {
|
||||||
|
let message = 'invalid template strings array'
|
||||||
|
|
||||||
|
throw new Error(message)
|
||||||
|
}
|
||||||
|
return [htmlResult, attrNames]
|
||||||
|
}
|
||||||
|
class Template {
|
||||||
|
constructor({ strings, ['__dom_type__']: type }, options) {
|
||||||
|
this.parts = []
|
||||||
|
let node
|
||||||
|
let nodeIndex = 0
|
||||||
|
let attrNameIndex = 0
|
||||||
|
const partCount = strings.length - 1
|
||||||
|
const parts = this.parts
|
||||||
|
const [html2, attrNames] = getTemplateHtml(strings, type)
|
||||||
|
this.el = Template.createElement(html2, options)
|
||||||
|
walker.currentNode = this.el.content
|
||||||
|
if (type === SVG_RESULT) {
|
||||||
|
const content = this.el.content
|
||||||
|
const svgElement = content.firstChild
|
||||||
|
svgElement.remove()
|
||||||
|
content.append(...svgElement.childNodes)
|
||||||
|
}
|
||||||
|
while ((node = walker.nextNode()) !== null && parts.length < partCount) {
|
||||||
|
if (node.nodeType === 1) {
|
||||||
|
if (node.hasAttributes()) {
|
||||||
|
const attrsToRemove = []
|
||||||
|
for (const name of node.getAttributeNames()) {
|
||||||
|
if (
|
||||||
|
name.endsWith(boundAttributeSuffix) ||
|
||||||
|
name.startsWith(marker)
|
||||||
|
) {
|
||||||
|
const realName = attrNames[attrNameIndex++]
|
||||||
|
attrsToRemove.push(name)
|
||||||
|
if (realName !== void 0) {
|
||||||
|
const value = node.getAttribute(
|
||||||
|
realName.toLowerCase() + boundAttributeSuffix
|
||||||
|
)
|
||||||
|
const statics = value.split(marker)
|
||||||
|
const m = /([.?@])?(.*)/.exec(realName)
|
||||||
|
parts.push({
|
||||||
|
type: ATTRIBUTE_PART,
|
||||||
|
index: nodeIndex,
|
||||||
|
name: m[2],
|
||||||
|
strings: statics,
|
||||||
|
ctor:
|
||||||
|
m[1] === '.'
|
||||||
|
? PropertyPart
|
||||||
|
: m[1] === '?'
|
||||||
|
? BooleanAttributePart
|
||||||
|
: m[1] === '@'
|
||||||
|
? EventPart
|
||||||
|
: AttributePart
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
parts.push({
|
||||||
|
type: ELEMENT_PART,
|
||||||
|
index: nodeIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const name of attrsToRemove) {
|
||||||
|
node.removeAttribute(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rawTextElement.test(node.tagName)) {
|
||||||
|
const strings2 = node.textContent.split(marker)
|
||||||
|
const lastIndex = strings2.length - 1
|
||||||
|
if (lastIndex > 0) {
|
||||||
|
node.textContent = ''
|
||||||
|
for (let i = 0; i < lastIndex; i++) {
|
||||||
|
node.append(strings2[i], createMarker())
|
||||||
|
walker.nextNode()
|
||||||
|
parts.push({ type: CHILD_PART, index: ++nodeIndex })
|
||||||
|
}
|
||||||
|
node.append(strings2[lastIndex], createMarker())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (node.nodeType === 8) {
|
||||||
|
const data = node.data
|
||||||
|
if (data === markerMatch) {
|
||||||
|
parts.push({ type: CHILD_PART, index: nodeIndex })
|
||||||
|
} else {
|
||||||
|
let i = -1
|
||||||
|
while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
|
||||||
|
parts.push({ type: COMMENT_PART, index: nodeIndex })
|
||||||
|
i += marker.length - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodeIndex++
|
||||||
|
}
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'template prep',
|
||||||
|
template: this,
|
||||||
|
clonableTemplate: this.el,
|
||||||
|
parts: this.parts,
|
||||||
|
strings
|
||||||
|
})
|
||||||
|
}
|
||||||
|
static createElement(html2, _options) {
|
||||||
|
const el = d.createElement('template')
|
||||||
|
el.innerHTML = html2
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function resolveDirective(part, value, parent = part, attributeIndex) {
|
||||||
|
var _a4, _b4, _c4
|
||||||
|
var _d3
|
||||||
|
if (value === noChange) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
let currentDirective =
|
||||||
|
attributeIndex !== void 0
|
||||||
|
? (_a4 = parent.__directives) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4[attributeIndex]
|
||||||
|
: parent.__directive
|
||||||
|
const nextDirectiveConstructor = isPrimitive(value)
|
||||||
|
? void 0
|
||||||
|
: value['_$litDirective$']
|
||||||
|
if (
|
||||||
|
(currentDirective === null || currentDirective === void 0
|
||||||
|
? void 0
|
||||||
|
: currentDirective.constructor) !== nextDirectiveConstructor
|
||||||
|
) {
|
||||||
|
;(_b4 =
|
||||||
|
currentDirective === null || currentDirective === void 0
|
||||||
|
? void 0
|
||||||
|
: currentDirective['_$notifyDirectiveConnectionChanged']) === null ||
|
||||||
|
_b4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _b4.call(currentDirective, false)
|
||||||
|
if (nextDirectiveConstructor === void 0) {
|
||||||
|
currentDirective = void 0
|
||||||
|
} else {
|
||||||
|
currentDirective = new nextDirectiveConstructor(part)
|
||||||
|
currentDirective._$initialize(part, parent, attributeIndex)
|
||||||
|
}
|
||||||
|
if (attributeIndex !== void 0) {
|
||||||
|
;((_c4 = (_d3 = parent).__directives) !== null && _c4 !== void 0
|
||||||
|
? _c4
|
||||||
|
: (_d3.__directives = []))[attributeIndex] = currentDirective
|
||||||
|
} else {
|
||||||
|
parent.__directive = currentDirective
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDirective !== void 0) {
|
||||||
|
value = resolveDirective(
|
||||||
|
part,
|
||||||
|
currentDirective._$resolve(part, value.values),
|
||||||
|
currentDirective,
|
||||||
|
attributeIndex
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
class TemplateInstance {
|
||||||
|
constructor(template, parent) {
|
||||||
|
this._parts = []
|
||||||
|
this._$disconnectableChildren = void 0
|
||||||
|
this._$template = template
|
||||||
|
this._$parent = parent
|
||||||
|
}
|
||||||
|
get parentNode() {
|
||||||
|
return this._$parent.parentNode
|
||||||
|
}
|
||||||
|
get _$isConnected() {
|
||||||
|
return this._$parent._$isConnected
|
||||||
|
}
|
||||||
|
_clone(options) {
|
||||||
|
var _a4
|
||||||
|
const {
|
||||||
|
el: { content },
|
||||||
|
parts
|
||||||
|
} = this._$template
|
||||||
|
const fragment = (
|
||||||
|
(_a4 =
|
||||||
|
options === null || options === void 0
|
||||||
|
? void 0
|
||||||
|
: options.creationScope) !== null && _a4 !== void 0
|
||||||
|
? _a4
|
||||||
|
: d
|
||||||
|
).importNode(content, true)
|
||||||
|
walker.currentNode = fragment
|
||||||
|
let node = walker.nextNode()
|
||||||
|
let nodeIndex = 0
|
||||||
|
let partIndex = 0
|
||||||
|
let templatePart = parts[0]
|
||||||
|
while (templatePart !== void 0) {
|
||||||
|
if (nodeIndex === templatePart.index) {
|
||||||
|
let part
|
||||||
|
if (templatePart.type === CHILD_PART) {
|
||||||
|
part = new ChildPart(node, node.nextSibling, this, options)
|
||||||
|
} else if (templatePart.type === ATTRIBUTE_PART) {
|
||||||
|
part = new templatePart.ctor(
|
||||||
|
node,
|
||||||
|
templatePart.name,
|
||||||
|
templatePart.strings,
|
||||||
|
this,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
} else if (templatePart.type === ELEMENT_PART) {
|
||||||
|
part = new ElementPart(node, this, options)
|
||||||
|
}
|
||||||
|
this._parts.push(part)
|
||||||
|
templatePart = parts[++partIndex]
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
nodeIndex !==
|
||||||
|
(templatePart === null || templatePart === void 0
|
||||||
|
? void 0
|
||||||
|
: templatePart.index)
|
||||||
|
) {
|
||||||
|
node = walker.nextNode()
|
||||||
|
nodeIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fragment
|
||||||
|
}
|
||||||
|
_update(values) {
|
||||||
|
let i = 0
|
||||||
|
for (const part of this._parts) {
|
||||||
|
if (part !== void 0) {
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'set part',
|
||||||
|
part,
|
||||||
|
value: values[i],
|
||||||
|
valueIndex: i,
|
||||||
|
values,
|
||||||
|
templateInstance: this
|
||||||
|
})
|
||||||
|
if (part.strings !== void 0) {
|
||||||
|
part._$setValue(values, part, i)
|
||||||
|
i += part.strings.length - 2
|
||||||
|
} else {
|
||||||
|
part._$setValue(values[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ChildPart {
|
||||||
|
constructor(startNode, endNode, parent, options) {
|
||||||
|
var _a4
|
||||||
|
this.type = CHILD_PART
|
||||||
|
this._$committedValue = nothing
|
||||||
|
this._$disconnectableChildren = void 0
|
||||||
|
this._$startNode = startNode
|
||||||
|
this._$endNode = endNode
|
||||||
|
this._$parent = parent
|
||||||
|
this.options = options
|
||||||
|
this.__isConnected =
|
||||||
|
(_a4 =
|
||||||
|
options === null || options === void 0
|
||||||
|
? void 0
|
||||||
|
: options.isConnected) !== null && _a4 !== void 0
|
||||||
|
? _a4
|
||||||
|
: true
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
this._textSanitizer = void 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get _$isConnected() {
|
||||||
|
var _a4, _b4
|
||||||
|
return (_b4 =
|
||||||
|
(_a4 = this._$parent) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4._$isConnected) !== null && _b4 !== void 0
|
||||||
|
? _b4
|
||||||
|
: this.__isConnected
|
||||||
|
}
|
||||||
|
get parentNode() {
|
||||||
|
let parentNode = wrap(this._$startNode).parentNode
|
||||||
|
const parent = this._$parent
|
||||||
|
if (parent !== void 0 && parentNode.nodeType === 11) {
|
||||||
|
parentNode = parent.parentNode
|
||||||
|
}
|
||||||
|
return parentNode
|
||||||
|
}
|
||||||
|
get startNode() {
|
||||||
|
return this._$startNode
|
||||||
|
}
|
||||||
|
get endNode() {
|
||||||
|
return this._$endNode
|
||||||
|
}
|
||||||
|
_$setValue(value, directiveParent = this) {
|
||||||
|
var _a4
|
||||||
|
|
||||||
|
value = resolveDirective(this, value, directiveParent)
|
||||||
|
if (isPrimitive(value)) {
|
||||||
|
if (value === nothing || value == null || value === '') {
|
||||||
|
if (this._$committedValue !== nothing) {
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit nothing to child',
|
||||||
|
start: this._$startNode,
|
||||||
|
end: this._$endNode,
|
||||||
|
parent: this._$parent,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
this._$clear()
|
||||||
|
}
|
||||||
|
this._$committedValue = nothing
|
||||||
|
} else if (value !== this._$committedValue && value !== noChange) {
|
||||||
|
this._commitText(value)
|
||||||
|
}
|
||||||
|
} else if (value['__dom_type__'] !== void 0) {
|
||||||
|
this._commitTemplateResult(value)
|
||||||
|
} else if (value.nodeType !== void 0) {
|
||||||
|
this._commitNode(value)
|
||||||
|
} else if (isIterable(value)) {
|
||||||
|
this._commitIterable(value)
|
||||||
|
} else {
|
||||||
|
this._commitText(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_insert(node, ref = this._$endNode) {
|
||||||
|
return wrap(wrap(this._$startNode).parentNode).insertBefore(node, ref)
|
||||||
|
}
|
||||||
|
_commitNode(value) {
|
||||||
|
var _a4
|
||||||
|
if (this._$committedValue !== value) {
|
||||||
|
this._$clear()
|
||||||
|
if (
|
||||||
|
ENABLE_EXTRA_SECURITY_HOOKS &&
|
||||||
|
sanitizerFactoryInternal !== noopSanitizer
|
||||||
|
) {
|
||||||
|
const parentNodeName =
|
||||||
|
(_a4 = this._$startNode.parentNode) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.nodeName
|
||||||
|
if (parentNodeName === 'STYLE' || parentNodeName === 'SCRIPT') {
|
||||||
|
let message = 'Forbidden'
|
||||||
|
|
||||||
|
throw new Error(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit node',
|
||||||
|
start: this._$startNode,
|
||||||
|
parent: this._$parent,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
this._$committedValue = this._insert(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_commitText(value) {
|
||||||
|
if (
|
||||||
|
this._$committedValue !== nothing &&
|
||||||
|
isPrimitive(this._$committedValue)
|
||||||
|
) {
|
||||||
|
const node = wrap(this._$startNode).nextSibling
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
if (this._textSanitizer === void 0) {
|
||||||
|
this._textSanitizer = createSanitizer(node, 'data', 'property')
|
||||||
|
}
|
||||||
|
value = this._textSanitizer(value)
|
||||||
|
}
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit text',
|
||||||
|
node,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
node.data = value
|
||||||
|
} else {
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
const textNode = document.createTextNode('')
|
||||||
|
this._commitNode(textNode)
|
||||||
|
if (this._textSanitizer === void 0) {
|
||||||
|
this._textSanitizer = createSanitizer(textNode, 'data', 'property')
|
||||||
|
}
|
||||||
|
value = this._textSanitizer(value)
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit text',
|
||||||
|
node: textNode,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
textNode.data = value
|
||||||
|
} else {
|
||||||
|
this._commitNode(d.createTextNode(value))
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit text',
|
||||||
|
node: wrap(this._$startNode).nextSibling,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._$committedValue = value
|
||||||
|
}
|
||||||
|
_commitTemplateResult(result) {
|
||||||
|
var _a4
|
||||||
|
const { values, ['__dom_type__']: type } = result
|
||||||
|
const template =
|
||||||
|
typeof type === 'number'
|
||||||
|
? this._$getTemplate(result)
|
||||||
|
: (type.el === void 0 &&
|
||||||
|
(type.el = Template.createElement(type.h, this.options)),
|
||||||
|
type)
|
||||||
|
if (
|
||||||
|
((_a4 = this._$committedValue) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4._$template) === template
|
||||||
|
) {
|
||||||
|
this._$committedValue._update(values)
|
||||||
|
} else {
|
||||||
|
const instance = new TemplateInstance(template, this)
|
||||||
|
const fragment = instance._clone(this.options)
|
||||||
|
|
||||||
|
instance._update(values)
|
||||||
|
|
||||||
|
this._commitNode(fragment)
|
||||||
|
this._$committedValue = instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_$getTemplate(result) {
|
||||||
|
let template = templateCache.get(result.strings)
|
||||||
|
if (template === void 0) {
|
||||||
|
templateCache.set(result.strings, (template = new Template(result)))
|
||||||
|
}
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
_commitIterable(value) {
|
||||||
|
if (!isArray(this._$committedValue)) {
|
||||||
|
this._$committedValue = []
|
||||||
|
this._$clear()
|
||||||
|
}
|
||||||
|
const itemParts = this._$committedValue
|
||||||
|
let partIndex = 0
|
||||||
|
let itemPart
|
||||||
|
for (const item of value) {
|
||||||
|
if (partIndex === itemParts.length) {
|
||||||
|
itemParts.push(
|
||||||
|
(itemPart = new ChildPart(
|
||||||
|
this._insert(createMarker()),
|
||||||
|
this._insert(createMarker()),
|
||||||
|
this,
|
||||||
|
this.options
|
||||||
|
))
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
itemPart = itemParts[partIndex]
|
||||||
|
}
|
||||||
|
itemPart._$setValue(item)
|
||||||
|
partIndex++
|
||||||
|
}
|
||||||
|
if (partIndex < itemParts.length) {
|
||||||
|
this._$clear(itemPart && wrap(itemPart._$endNode).nextSibling, partIndex)
|
||||||
|
itemParts.length = partIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_$clear(start = wrap(this._$startNode).nextSibling, from) {
|
||||||
|
var _a4
|
||||||
|
;(_a4 = this._$notifyConnectionChanged) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.call(this, false, true, from)
|
||||||
|
while (start && start !== this._$endNode) {
|
||||||
|
const n = wrap(start).nextSibling
|
||||||
|
wrap(start).remove()
|
||||||
|
start = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setConnected(isConnected) {
|
||||||
|
var _a4
|
||||||
|
if (this._$parent === void 0) {
|
||||||
|
this.__isConnected = isConnected
|
||||||
|
;(_a4 = this._$notifyConnectionChanged) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.call(this, isConnected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class AttributePart {
|
||||||
|
constructor(element, name, strings, parent, options) {
|
||||||
|
this.type = ATTRIBUTE_PART
|
||||||
|
this._$committedValue = nothing
|
||||||
|
this._$disconnectableChildren = void 0
|
||||||
|
this.element = element
|
||||||
|
this.name = name
|
||||||
|
this._$parent = parent
|
||||||
|
this.options = options
|
||||||
|
if (strings.length > 2 || strings[0] !== '' || strings[1] !== '') {
|
||||||
|
this._$committedValue = new Array(strings.length - 1).fill(new String())
|
||||||
|
this.strings = strings
|
||||||
|
} else {
|
||||||
|
this._$committedValue = nothing
|
||||||
|
}
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
this._sanitizer = void 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get tagName() {
|
||||||
|
return this.element.tagName
|
||||||
|
}
|
||||||
|
get _$isConnected() {
|
||||||
|
return this._$parent._$isConnected
|
||||||
|
}
|
||||||
|
_$setValue(value, directiveParent = this, valueIndex, noCommit) {
|
||||||
|
const strings = this.strings
|
||||||
|
let change = false
|
||||||
|
if (strings === void 0) {
|
||||||
|
value = resolveDirective(this, value, directiveParent, 0)
|
||||||
|
change =
|
||||||
|
!isPrimitive(value) ||
|
||||||
|
(value !== this._$committedValue && value !== noChange)
|
||||||
|
if (change) {
|
||||||
|
this._$committedValue = value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const values = value
|
||||||
|
value = strings[0]
|
||||||
|
let i, v
|
||||||
|
for (i = 0; i < strings.length - 1; i++) {
|
||||||
|
v = resolveDirective(this, values[valueIndex + i], directiveParent, i)
|
||||||
|
if (v === noChange) {
|
||||||
|
v = this._$committedValue[i]
|
||||||
|
}
|
||||||
|
change || (change = !isPrimitive(v) || v !== this._$committedValue[i])
|
||||||
|
if (v === nothing) {
|
||||||
|
value = nothing
|
||||||
|
} else if (value !== nothing) {
|
||||||
|
value += (v !== null && v !== void 0 ? v : '') + strings[i + 1]
|
||||||
|
}
|
||||||
|
this._$committedValue[i] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (change && !noCommit) {
|
||||||
|
this._commitValue(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_commitValue(value) {
|
||||||
|
if (value === nothing) {
|
||||||
|
wrap(this.element).removeAttribute(this.name)
|
||||||
|
} else {
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
if (this._sanitizer === void 0) {
|
||||||
|
this._sanitizer = sanitizerFactoryInternal(
|
||||||
|
this.element,
|
||||||
|
this.name,
|
||||||
|
'attribute'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
value = this._sanitizer(value !== null && value !== void 0 ? value : '')
|
||||||
|
}
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit attribute',
|
||||||
|
element: this.element,
|
||||||
|
name: this.name,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
wrap(this.element).setAttribute(
|
||||||
|
this.name,
|
||||||
|
value !== null && value !== void 0 ? value : ''
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class PropertyPart extends AttributePart {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments)
|
||||||
|
this.type = PROPERTY_PART
|
||||||
|
}
|
||||||
|
_commitValue(value) {
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
if (this._sanitizer === void 0) {
|
||||||
|
this._sanitizer = sanitizerFactoryInternal(
|
||||||
|
this.element,
|
||||||
|
this.name,
|
||||||
|
'property'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
value = this._sanitizer(value)
|
||||||
|
}
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit property',
|
||||||
|
element: this.element,
|
||||||
|
name: this.name,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
this.element[this.name] = value === nothing ? void 0 : value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var emptyStringForBooleanAttribute2 = ''
|
||||||
|
class BooleanAttributePart extends AttributePart {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments)
|
||||||
|
this.type = BOOLEAN_ATTRIBUTE_PART
|
||||||
|
}
|
||||||
|
_commitValue(value) {
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit boolean attribute',
|
||||||
|
element: this.element,
|
||||||
|
name: this.name,
|
||||||
|
value: !!(value && value !== nothing),
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
if (value && value !== nothing) {
|
||||||
|
wrap(this.element).setAttribute(
|
||||||
|
this.name,
|
||||||
|
emptyStringForBooleanAttribute2
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
wrap(this.element).removeAttribute(this.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class EventPart extends AttributePart {
|
||||||
|
constructor(element, name, strings, parent, options) {
|
||||||
|
super(element, name, strings, parent, options)
|
||||||
|
this.type = EVENT_PART
|
||||||
|
}
|
||||||
|
_$setValue(newListener, directiveParent = this) {
|
||||||
|
var _a4
|
||||||
|
newListener =
|
||||||
|
(_a4 = resolveDirective(this, newListener, directiveParent, 0)) !==
|
||||||
|
null && _a4 !== void 0
|
||||||
|
? _a4
|
||||||
|
: nothing
|
||||||
|
if (newListener === noChange) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const oldListener = this._$committedValue
|
||||||
|
const shouldRemoveListener =
|
||||||
|
(newListener === nothing && oldListener !== nothing) ||
|
||||||
|
newListener.capture !== oldListener.capture ||
|
||||||
|
newListener.once !== oldListener.once ||
|
||||||
|
newListener.passive !== oldListener.passive
|
||||||
|
const shouldAddListener =
|
||||||
|
newListener !== nothing &&
|
||||||
|
(oldListener === nothing || shouldRemoveListener)
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit event listener',
|
||||||
|
element: this.element,
|
||||||
|
name: this.name,
|
||||||
|
value: newListener,
|
||||||
|
options: this.options,
|
||||||
|
removeListener: shouldRemoveListener,
|
||||||
|
addListener: shouldAddListener,
|
||||||
|
oldListener
|
||||||
|
})
|
||||||
|
if (shouldRemoveListener) {
|
||||||
|
this.element.removeEventListener(this.name, this, oldListener)
|
||||||
|
}
|
||||||
|
if (shouldAddListener) {
|
||||||
|
this.element.addEventListener(this.name, this, newListener)
|
||||||
|
}
|
||||||
|
this._$committedValue = newListener
|
||||||
|
}
|
||||||
|
handleEvent(event) {
|
||||||
|
var _a4, _b4
|
||||||
|
if (typeof this._$committedValue === 'function') {
|
||||||
|
this._$committedValue.call(
|
||||||
|
(_b4 =
|
||||||
|
(_a4 = this.options) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.host) !== null && _b4 !== void 0
|
||||||
|
? _b4
|
||||||
|
: this.element,
|
||||||
|
event
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this._$committedValue.handleEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ElementPart {
|
||||||
|
constructor(element, parent, options) {
|
||||||
|
this.element = element
|
||||||
|
this.type = ELEMENT_PART
|
||||||
|
this._$disconnectableChildren = void 0
|
||||||
|
this._$parent = parent
|
||||||
|
this.options = options
|
||||||
|
}
|
||||||
|
get _$isConnected() {
|
||||||
|
return this._$parent._$isConnected
|
||||||
|
}
|
||||||
|
_$setValue(value) {
|
||||||
|
debugLogEvent2 === null || debugLogEvent2 === void 0
|
||||||
|
? void 0
|
||||||
|
: debugLogEvent2({
|
||||||
|
kind: 'commit to element binding',
|
||||||
|
element: this.element,
|
||||||
|
value,
|
||||||
|
options: this.options
|
||||||
|
})
|
||||||
|
resolveDirective(this, value)
|
||||||
}
|
}
|
||||||
return output
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTemplate(html) {
|
export function render(value, container, options) {
|
||||||
let template = document.createElement('template')
|
var _a4, _b4
|
||||||
template.innerHTML = html
|
|
||||||
return template.content.cloneNode(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function renderRoot(root, html) {
|
const renderId = 0
|
||||||
root.appendChild(getTemplate(html))
|
const partOwnerNode =
|
||||||
|
(_a4 =
|
||||||
|
options === null || options === void 0
|
||||||
|
? void 0
|
||||||
|
: options.renderBefore) !== null && _a4 !== void 0
|
||||||
|
? _a4
|
||||||
|
: container
|
||||||
|
let part = partOwnerNode['_$litPart$']
|
||||||
|
|
||||||
|
if (part === void 0) {
|
||||||
|
const endNode =
|
||||||
|
(_b4 =
|
||||||
|
options === null || options === void 0
|
||||||
|
? void 0
|
||||||
|
: options.renderBefore) !== null && _b4 !== void 0
|
||||||
|
? _b4
|
||||||
|
: null
|
||||||
|
partOwnerNode['_$litPart$'] = part = new ChildPart(
|
||||||
|
container.insertBefore(createMarker(), endNode),
|
||||||
|
endNode,
|
||||||
|
void 0,
|
||||||
|
options !== null && options !== void 0 ? options : {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
part._$setValue(value)
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
if (ENABLE_EXTRA_SECURITY_HOOKS) {
|
||||||
|
render.setSanitizer = setSanitizer
|
||||||
|
render.createSanitizer = createSanitizer
|
||||||
}
|
}
|
||||||
|
|
453
src/index.js
453
src/index.js
|
@ -1,94 +1,381 @@
|
||||||
/**
|
/**
|
||||||
* {全新的组件核心库}
|
* {wcui的核心库, 基于lit-core二次开发}
|
||||||
* @author yutent<yutent.io@gmail.com>
|
* @author yutent<yutent.io@gmail.com>
|
||||||
* @date 2023/03/03 11:21:44
|
* @date 2023/03/07 18:10:43
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { finalize } from './constants.js'
|
|
||||||
import { css, adoptStyles } from './css.js'
|
import { css, adoptStyles } from './css.js'
|
||||||
import { html, renderRoot } from './html.js'
|
import { render, html, svg } from './html.js'
|
||||||
|
export { html, css, svg }
|
||||||
|
|
||||||
export { css, html }
|
var defaultConverter = {
|
||||||
|
toAttribute(value, type) {
|
||||||
export class Component extends HTMLElement {
|
switch (type) {
|
||||||
// 声明要监听的属性
|
case Boolean:
|
||||||
static get observedAttributes() {
|
value = value ? '' : null
|
||||||
this[finalize]()
|
break
|
||||||
|
case Object:
|
||||||
let list = []
|
case Array:
|
||||||
this.elemProps.forEach((it, prop) => {
|
value = value == null ? value : JSON.stringify(value)
|
||||||
list.push(prop)
|
break
|
||||||
})
|
|
||||||
return list
|
|
||||||
}
|
}
|
||||||
|
return value
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.created && this.created()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预处理rpops, styles等
|
|
||||||
*/
|
|
||||||
static [finalize]() {
|
|
||||||
if (this.finalized) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.finalized = true
|
|
||||||
|
|
||||||
this.elemProps = new Map()
|
|
||||||
|
|
||||||
const t = Object.getPrototypeOf(this)
|
|
||||||
|
|
||||||
console.log('>>>', t)
|
|
||||||
console.log('>>>', this)
|
|
||||||
|
|
||||||
for (let k in this.props) {
|
|
||||||
let prop = Symbol(k)
|
|
||||||
let options = this.props[k]
|
|
||||||
this.elemProps.set(k, prop)
|
|
||||||
Object.defineProperty(this.prototype, k, {
|
|
||||||
get() {
|
|
||||||
return this[prop] || options.default
|
|
||||||
},
|
},
|
||||||
set(val) {
|
fromAttribute(value, type) {
|
||||||
this[prop] = val
|
let fromValue = value
|
||||||
},
|
switch (type) {
|
||||||
enumerable: false
|
case Boolean:
|
||||||
})
|
fromValue = value !== null
|
||||||
|
break
|
||||||
|
case Number:
|
||||||
|
fromValue = value === null ? null : Number(value)
|
||||||
|
break
|
||||||
|
case Object:
|
||||||
|
case Array:
|
||||||
|
try {
|
||||||
|
fromValue = JSON.parse(value)
|
||||||
|
} catch (e) {
|
||||||
|
fromValue = null
|
||||||
}
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
return fromValue
|
||||||
render() {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// 组件节点被插入文档时触发的回调
|
|
||||||
connectedCallback() {
|
|
||||||
Object.defineProperty(this, 'root', {
|
|
||||||
value: this.shadowRoot || this.attachShadow({ mode: 'open' }),
|
|
||||||
enumerable: false
|
|
||||||
})
|
|
||||||
|
|
||||||
adoptStyles(this.root, this.constructor.styles)
|
|
||||||
|
|
||||||
renderRoot(this.root, this.render())
|
|
||||||
|
|
||||||
this.mounted && this.mounted()
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
console.log('>>>>')
|
|
||||||
}
|
|
||||||
|
|
||||||
attributeChangedCallback(name, old, val) {
|
|
||||||
if (old === val) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adoptedCallback() {
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var notEqual = (value, old) => {
|
||||||
|
return old !== value && (old === old || value === value)
|
||||||
|
}
|
||||||
|
var defaultPropertyDeclaration = {
|
||||||
|
attribute: true,
|
||||||
|
type: String,
|
||||||
|
converter: defaultConverter,
|
||||||
|
reflect: false,
|
||||||
|
hasChanged: notEqual
|
||||||
|
}
|
||||||
|
var finalized = 'finalized'
|
||||||
|
|
||||||
|
export class Component extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.__instanceProperties = new Map()
|
||||||
|
this.isUpdatePending = false
|
||||||
|
this.hasUpdated = false
|
||||||
|
this.__reflectingProperty = null
|
||||||
|
this._initialize()
|
||||||
|
}
|
||||||
|
static addInitializer(initializer) {
|
||||||
|
var _a4
|
||||||
|
this.finalize()
|
||||||
|
;((_a4 = this._initializers) !== null && _a4 !== void 0
|
||||||
|
? _a4
|
||||||
|
: (this._initializers = [])
|
||||||
|
).push(initializer)
|
||||||
|
}
|
||||||
|
static get observedAttributes() {
|
||||||
|
this.finalize()
|
||||||
|
const attributes = []
|
||||||
|
this.elementProperties.forEach((v, p) => {
|
||||||
|
const attr = this.__attributeNameForProperty(p, v)
|
||||||
|
if (attr !== void 0) {
|
||||||
|
this.__attributeToPropertyMap.set(attr, p)
|
||||||
|
attributes.push(attr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return attributes
|
||||||
|
}
|
||||||
|
static createProperty(name, options = defaultPropertyDeclaration) {
|
||||||
|
if (options.state) {
|
||||||
|
options.attribute = false
|
||||||
|
}
|
||||||
|
this.finalize()
|
||||||
|
this.elementProperties.set(name, options)
|
||||||
|
|
||||||
|
let key = Symbol(name)
|
||||||
|
let descriptor = this.getPropertyDescriptor(name, key, options)
|
||||||
|
|
||||||
|
this.prototype[key] = options.default
|
||||||
|
Object.defineProperty(this.prototype, name, descriptor)
|
||||||
|
}
|
||||||
|
static getPropertyDescriptor(name, key, options) {
|
||||||
|
return {
|
||||||
|
get() {
|
||||||
|
return this[key]
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
const oldValue = this[name]
|
||||||
|
this[key] = value
|
||||||
|
this.requestUpdate(name, oldValue, options)
|
||||||
|
},
|
||||||
|
configurable: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static getPropertyOptions(name) {
|
||||||
|
return this.elementProperties.get(name) || defaultPropertyDeclaration
|
||||||
|
}
|
||||||
|
static finalize() {
|
||||||
|
if (this.hasOwnProperty(finalized)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this[finalized] = true
|
||||||
|
|
||||||
|
this.elementProperties = new Map()
|
||||||
|
this.__attributeToPropertyMap = new Map()
|
||||||
|
if (this.hasOwnProperty('props')) {
|
||||||
|
for (let k in this.props) {
|
||||||
|
this.createProperty(k, this.props[k])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
static __attributeNameForProperty(name, options) {
|
||||||
|
const attribute = options.attribute
|
||||||
|
return attribute === false
|
||||||
|
? void 0
|
||||||
|
: typeof attribute === 'string'
|
||||||
|
? attribute
|
||||||
|
: typeof name === 'string'
|
||||||
|
? name.toLowerCase()
|
||||||
|
: void 0
|
||||||
|
}
|
||||||
|
_initialize() {
|
||||||
|
var _a4
|
||||||
|
this.__updatePromise = new Promise(res => (this.enableUpdating = res))
|
||||||
|
this._$changedProperties = new Map()
|
||||||
|
this.__saveInstanceProperties()
|
||||||
|
this.requestUpdate()
|
||||||
|
;(_a4 = this.constructor._initializers) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.forEach(i => i(this))
|
||||||
|
}
|
||||||
|
addController(controller) {
|
||||||
|
var _a4, _b4
|
||||||
|
;((_a4 = this.__controllers) !== null && _a4 !== void 0
|
||||||
|
? _a4
|
||||||
|
: (this.__controllers = [])
|
||||||
|
).push(controller)
|
||||||
|
if (this.root !== void 0 && this.isConnected) {
|
||||||
|
;(_b4 = controller.hostConnected) === null || _b4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _b4.call(controller)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeController(controller) {
|
||||||
|
var _a4
|
||||||
|
;(_a4 = this.__controllers) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.splice(this.__controllers.indexOf(controller) >>> 0, 1)
|
||||||
|
}
|
||||||
|
__saveInstanceProperties() {
|
||||||
|
this.constructor.elementProperties.forEach((_v, p) => {
|
||||||
|
if (this.hasOwnProperty(p)) {
|
||||||
|
this.__instanceProperties.set(p, this[p])
|
||||||
|
delete this[p]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
createRenderRoot() {
|
||||||
|
let root = this.shadowRoot || this.attachShadow({ mode: 'open' })
|
||||||
|
adoptStyles(root, this.constructor.styles)
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
var _a4
|
||||||
|
if (this.root === void 0) {
|
||||||
|
this.root = this.createRenderRoot()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.enableUpdating(true)
|
||||||
|
;(_a4 = this.__controllers) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.forEach(c => {
|
||||||
|
var _a5
|
||||||
|
return (_a5 = c.hostConnected) === null || _a5 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a5.call(c)
|
||||||
|
})
|
||||||
|
this.__childPart && this.__childPart.setConnected(true)
|
||||||
|
}
|
||||||
|
enableUpdating(_requestedUpdate) {}
|
||||||
|
disconnectedCallback() {
|
||||||
|
var _a4
|
||||||
|
;(_a4 = this.__controllers) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.forEach(c => {
|
||||||
|
var _a5
|
||||||
|
return (_a5 = c.hostDisconnected) === null || _a5 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a5.call(c)
|
||||||
|
})
|
||||||
|
this.__childPart && this.__childPart.setConnected(false)
|
||||||
|
}
|
||||||
|
attributeChangedCallback(name, _old, value) {
|
||||||
|
this._$attributeToProperty(name, value)
|
||||||
|
}
|
||||||
|
__propertyToAttribute(name, value, options = defaultPropertyDeclaration) {
|
||||||
|
var _a4
|
||||||
|
const attr = this.constructor.__attributeNameForProperty(name, options)
|
||||||
|
if (attr !== void 0 && options.reflect === true) {
|
||||||
|
const converter =
|
||||||
|
((_a4 = options.converter) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.toAttribute) !== void 0
|
||||||
|
? options.converter
|
||||||
|
: defaultConverter
|
||||||
|
const attrValue = converter.toAttribute(value, options.type)
|
||||||
|
|
||||||
|
this.__reflectingProperty = name
|
||||||
|
if (attrValue == null) {
|
||||||
|
this.removeAttribute(attr)
|
||||||
|
} else {
|
||||||
|
this.setAttribute(attr, attrValue)
|
||||||
|
}
|
||||||
|
this.__reflectingProperty = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_$attributeToProperty(name, value) {
|
||||||
|
var _a4
|
||||||
|
const ctor = this.constructor
|
||||||
|
const propName = ctor.__attributeToPropertyMap.get(name)
|
||||||
|
if (propName !== void 0 && this.__reflectingProperty !== propName) {
|
||||||
|
const options = ctor.getPropertyOptions(propName)
|
||||||
|
const converter =
|
||||||
|
typeof options.converter === 'function'
|
||||||
|
? { fromAttribute: options.converter }
|
||||||
|
: ((_a4 = options.converter) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.fromAttribute) !== void 0
|
||||||
|
? options.converter
|
||||||
|
: defaultConverter
|
||||||
|
this.__reflectingProperty = propName
|
||||||
|
this[propName] = converter.fromAttribute(value, options.type)
|
||||||
|
this.__reflectingProperty = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestUpdate(name, oldValue, options) {
|
||||||
|
let shouldRequestUpdate = true
|
||||||
|
if (name !== void 0) {
|
||||||
|
options = options || this.constructor.getPropertyOptions(name)
|
||||||
|
const hasChanged = options.hasChanged || notEqual
|
||||||
|
if (hasChanged(this[name], oldValue)) {
|
||||||
|
if (!this._$changedProperties.has(name)) {
|
||||||
|
this._$changedProperties.set(name, oldValue)
|
||||||
|
}
|
||||||
|
if (options.reflect === true && this.__reflectingProperty !== name) {
|
||||||
|
if (this.__reflectingProperties === void 0) {
|
||||||
|
this.__reflectingProperties = new Map()
|
||||||
|
}
|
||||||
|
this.__reflectingProperties.set(name, options)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shouldRequestUpdate = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.isUpdatePending && shouldRequestUpdate) {
|
||||||
|
this.__updatePromise = this.__enqueueUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async __enqueueUpdate() {
|
||||||
|
this.isUpdatePending = true
|
||||||
|
try {
|
||||||
|
await this.__updatePromise
|
||||||
|
} catch (e) {
|
||||||
|
Promise.reject(e)
|
||||||
|
}
|
||||||
|
const result = this.scheduleUpdate()
|
||||||
|
if (result != null) {
|
||||||
|
await result
|
||||||
|
}
|
||||||
|
return !this.isUpdatePending
|
||||||
|
}
|
||||||
|
scheduleUpdate() {
|
||||||
|
return this.performUpdate()
|
||||||
|
}
|
||||||
|
performUpdate() {
|
||||||
|
var _a4, _b4
|
||||||
|
if (!this.isUpdatePending) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.__instanceProperties) {
|
||||||
|
this.__instanceProperties.forEach((v, p) => (this[p] = v))
|
||||||
|
this.__instanceProperties = void 0
|
||||||
|
}
|
||||||
|
let shouldUpdate = false
|
||||||
|
const changedProperties = this._$changedProperties
|
||||||
|
try {
|
||||||
|
shouldUpdate = this.shouldUpdate(changedProperties)
|
||||||
|
if (shouldUpdate) {
|
||||||
|
this.willUpdate(changedProperties)
|
||||||
|
;(_b4 = this.__controllers) === null || _b4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _b4.forEach(c => {
|
||||||
|
var _a5
|
||||||
|
return (_a5 = c.hostUpdate) === null || _a5 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a5.call(c)
|
||||||
|
})
|
||||||
|
this.update(changedProperties)
|
||||||
|
} else {
|
||||||
|
this.__markUpdated()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
shouldUpdate = false
|
||||||
|
this.__markUpdated()
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
if (shouldUpdate) {
|
||||||
|
this._$didUpdate(changedProperties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
willUpdate(_changedProperties) {}
|
||||||
|
_$didUpdate(changedProperties) {
|
||||||
|
var _a4
|
||||||
|
;(_a4 = this.__controllers) === null || _a4 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a4.forEach(c => {
|
||||||
|
var _a5
|
||||||
|
return (_a5 = c.hostUpdated) === null || _a5 === void 0
|
||||||
|
? void 0
|
||||||
|
: _a5.call(c)
|
||||||
|
})
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
this.hasUpdated = true
|
||||||
|
this.firstUpdated(changedProperties)
|
||||||
|
}
|
||||||
|
this.updated(changedProperties)
|
||||||
|
}
|
||||||
|
__markUpdated() {
|
||||||
|
this._$changedProperties = new Map()
|
||||||
|
this.isUpdatePending = false
|
||||||
|
}
|
||||||
|
get updateComplete() {
|
||||||
|
return this.getUpdateComplete()
|
||||||
|
}
|
||||||
|
getUpdateComplete() {
|
||||||
|
return this.__updatePromise
|
||||||
|
}
|
||||||
|
shouldUpdate(_changedProperties) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
update(_changedProperties) {
|
||||||
|
const value = this.render()
|
||||||
|
|
||||||
|
/* */
|
||||||
|
if (this.__reflectingProperties !== void 0) {
|
||||||
|
this.__reflectingProperties.forEach((v, k) =>
|
||||||
|
this.__propertyToAttribute(k, this[k], v)
|
||||||
|
)
|
||||||
|
this.__reflectingProperties = void 0
|
||||||
|
}
|
||||||
|
this.__markUpdated()
|
||||||
|
|
||||||
|
this.__childPart = render(value, this.root, {
|
||||||
|
host: this,
|
||||||
|
isConnected: !this.hasUpdated && this.isConnected
|
||||||
|
})
|
||||||
|
}
|
||||||
|
updated(_changedProperties) {}
|
||||||
|
firstUpdated(_changedProperties) {}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue