改用lit-core二次开发

pull/1/head
yutent 2023-03-07 19:15:23 +08:00
parent 880e355396
commit dded36fb09
4 changed files with 1298 additions and 125 deletions

View File

@ -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;}
`

View File

@ -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() || '')

View File

@ -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
} }
return output
} }
function getTemplate(html) { const end =
let template = document.createElement('template') regex === tagEndRegex && strings[i + 1].startsWith('/>') ? ' ' : ''
template.innerHTML = html html2 +=
return template.content.cloneNode(true) 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)
}
} }
export function renderRoot(root, html) { export function render(value, container, options) {
root.appendChild(getTemplate(html)) var _a4, _b4
const renderId = 0
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
} }

View File

@ -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) {
switch (type) {
case Boolean:
value = value ? '' : null
break
case Object:
case Array:
value = value == null ? value : JSON.stringify(value)
break
}
return value
},
fromAttribute(value, type) {
let fromValue = value
switch (type) {
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
}
}
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 { export class Component extends HTMLElement {
// 声明要监听的属性
static get observedAttributes() {
this[finalize]()
let list = []
this.elemProps.forEach((it, prop) => {
list.push(prop)
})
return list
}
constructor() { constructor() {
super() super()
this.created && this.created()
this.__instanceProperties = new Map()
this.isUpdatePending = false
this.hasUpdated = false
this.__reflectingProperty = null
this._initialize()
} }
static addInitializer(initializer) {
/** var _a4
* 预处理rpops, styles等 this.finalize()
*/ ;((_a4 = this._initializers) !== null && _a4 !== void 0
static [finalize]() { ? _a4
if (this.finalized) { : (this._initializers = [])
return ).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)
this.finalized = true let key = Symbol(name)
let descriptor = this.getPropertyDescriptor(name, key, options)
this.elemProps = new Map() this.prototype[key] = options.default
Object.defineProperty(this.prototype, name, descriptor)
const t = Object.getPrototypeOf(this) }
static getPropertyDescriptor(name, key, options) {
console.log('>>>', t) return {
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() { get() {
return this[prop] || options.default return this[key]
}, },
set(val) { set(value) {
this[prop] = val const oldValue = this[name]
this[key] = value
this.requestUpdate(name, oldValue, options)
}, },
enumerable: false 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
} }
render() {
return ''
}
// 组件节点被插入文档时触发的回调
connectedCallback() { connectedCallback() {
Object.defineProperty(this, 'root', { var _a4
value: this.shadowRoot || this.attachShadow({ mode: 'open' }), if (this.root === void 0) {
enumerable: false 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)
adoptStyles(this.root, this.constructor.styles)
renderRoot(this.root, this.render())
this.mounted && this.mounted()
} }
enableUpdating(_requestedUpdate) {}
disconnectedCallback() { disconnectedCallback() {
console.log('>>>>') 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)
attributeChangedCallback(name, old, val) { this.__reflectingProperty = name
if (old === val) { 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 return
} }
}
adoptedCallback() { 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) {}
}