一大波精简

pull/1/head
yutent 2023-03-08 11:11:05 +08:00
parent e53a60d7a4
commit 65753a6e02
4 changed files with 120 additions and 280 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@ninejs/core", "name": "@ninejs/core",
"version": "0.1.0", "version": "0.2.0",
"type": "module", "type": "module",
"description": "9号UI组件库的核心", "description": "9号UI组件库的核心",
"main": "dist/index.js", "main": "dist/index.js",

View File

@ -4,9 +4,57 @@
* @date 2023/03/06 12:08:35 * @date 2023/03/06 12:08:35
*/ */
export const finalize = Symbol('finalize') export const FINALIZED = Symbol('finalized')
export const UPDATE = Symbol('update')
export const RESET_CSS_STYLE = ` export const RESET_CSS_STYLE = `
* {box-sizing: border-box;margin: 0;padding: 0;} * {box-sizing: border-box;margin: 0;padding: 0;}
::before,::after {box-sizing: border-box;} ::before,::after {box-sizing: border-box;}
` `
export const DEFAULT_CONVERTER = {
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
}
}
export function notEqual(value, old) {
return old !== value && (old === old || value === value)
}
export const DEFAULT_PROPERTY_DECLARATION = {
attribute: true,
type: String,
converter: DEFAULT_CONVERTER,
reflect: false,
hasChanged: notEqual
}

View File

@ -1,11 +1,8 @@
var ENABLE_EXTRA_SECURITY_HOOKS = true var ENABLE_EXTRA_SECURITY_HOOKS = true
var global3 = window var global3 = window
var debugLogEvent2 = void 0
var debugLogRenderId = 0 var debugLogRenderId = 0
var issueWarning2 var issueWarning2
var wrap = node => node
var identityFunction = value => value var identityFunction = value => value
var noopSanitizer = (_node, _name, _type) => identityFunction var noopSanitizer = (_node, _name, _type) => identityFunction
var setSanitizer = newSanitizer => { var setSanitizer = newSanitizer => {
@ -262,15 +259,6 @@ class Template {
} }
nodeIndex++ 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) { static createElement(html2, _options) {
const el = d.createElement('template') const el = d.createElement('template')
@ -396,16 +384,6 @@ class TemplateInstance {
let i = 0 let i = 0
for (const part of this._parts) { for (const part of this._parts) {
if (part !== void 0) { 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) { if (part.strings !== void 0) {
part._$setValue(values, part, i) part._$setValue(values, part, i)
i += part.strings.length - 2 i += part.strings.length - 2
@ -448,7 +426,7 @@ class ChildPart {
: this.__isConnected : this.__isConnected
} }
get parentNode() { get parentNode() {
let parentNode = wrap(this._$startNode).parentNode let parentNode = this._$startNode.parentNode
const parent = this._$parent const parent = this._$parent
if (parent !== void 0 && parentNode.nodeType === 11) { if (parent !== void 0 && parentNode.nodeType === 11) {
parentNode = parent.parentNode parentNode = parent.parentNode
@ -468,15 +446,6 @@ class ChildPart {
if (isPrimitive(value)) { if (isPrimitive(value)) {
if (value === nothing || value == null || value === '') { if (value === nothing || value == null || value === '') {
if (this._$committedValue !== nothing) { 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._$clear()
} }
this._$committedValue = nothing this._$committedValue = nothing
@ -494,7 +463,7 @@ class ChildPart {
} }
} }
_insert(node, ref = this._$endNode) { _insert(node, ref = this._$endNode) {
return wrap(wrap(this._$startNode).parentNode).insertBefore(node, ref) return this._$startNode.parentNode.insertBefore(node, ref)
} }
_commitNode(value) { _commitNode(value) {
var _a4 var _a4
@ -514,15 +483,7 @@ class ChildPart {
throw new Error(message) 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) this._$committedValue = this._insert(value)
} }
} }
@ -531,21 +492,14 @@ class ChildPart {
this._$committedValue !== nothing && this._$committedValue !== nothing &&
isPrimitive(this._$committedValue) isPrimitive(this._$committedValue)
) { ) {
const node = wrap(this._$startNode).nextSibling const node = this._$startNode.nextSibling
if (ENABLE_EXTRA_SECURITY_HOOKS) { if (ENABLE_EXTRA_SECURITY_HOOKS) {
if (this._textSanitizer === void 0) { if (this._textSanitizer === void 0) {
this._textSanitizer = createSanitizer(node, 'data', 'property') this._textSanitizer = createSanitizer(node, 'data', 'property')
} }
value = this._textSanitizer(value) value = this._textSanitizer(value)
} }
debugLogEvent2 === null || debugLogEvent2 === void 0
? void 0
: debugLogEvent2({
kind: 'commit text',
node,
value,
options: this.options
})
node.data = value node.data = value
} else { } else {
if (ENABLE_EXTRA_SECURITY_HOOKS) { if (ENABLE_EXTRA_SECURITY_HOOKS) {
@ -555,25 +509,10 @@ class ChildPart {
this._textSanitizer = createSanitizer(textNode, 'data', 'property') this._textSanitizer = createSanitizer(textNode, 'data', 'property')
} }
value = this._textSanitizer(value) value = this._textSanitizer(value)
debugLogEvent2 === null || debugLogEvent2 === void 0
? void 0
: debugLogEvent2({
kind: 'commit text',
node: textNode,
value,
options: this.options
})
textNode.data = value textNode.data = value
} else { } else {
this._commitNode(d.createTextNode(value)) 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 this._$committedValue = value
@ -635,18 +574,18 @@ class ChildPart {
partIndex++ partIndex++
} }
if (partIndex < itemParts.length) { if (partIndex < itemParts.length) {
this._$clear(itemPart && wrap(itemPart._$endNode).nextSibling, partIndex) this._$clear(itemPart && itemPart._$endNode.nextSibling, partIndex)
itemParts.length = partIndex itemParts.length = partIndex
} }
} }
_$clear(start = wrap(this._$startNode).nextSibling, from) { _$clear(start = this._$startNode.nextSibling, from) {
var _a4 var _a4
;(_a4 = this._$notifyConnectionChanged) === null || _a4 === void 0 ;(_a4 = this._$notifyConnectionChanged) === null || _a4 === void 0
? void 0 ? void 0
: _a4.call(this, false, true, from) : _a4.call(this, false, true, from)
while (start && start !== this._$endNode) { while (start && start !== this._$endNode) {
const n = wrap(start).nextSibling const n = start.nextSibling
wrap(start).remove() start.remove()
start = n start = n
} }
} }
@ -720,7 +659,7 @@ class AttributePart {
} }
_commitValue(value) { _commitValue(value) {
if (value === nothing) { if (value === nothing) {
wrap(this.element).removeAttribute(this.name) this.element.removeAttribute(this.name)
} else { } else {
if (ENABLE_EXTRA_SECURITY_HOOKS) { if (ENABLE_EXTRA_SECURITY_HOOKS) {
if (this._sanitizer === void 0) { if (this._sanitizer === void 0) {
@ -732,16 +671,8 @@ class AttributePart {
} }
value = this._sanitizer(value !== null && value !== void 0 ? value : '') value = this._sanitizer(value !== null && value !== void 0 ? value : '')
} }
debugLogEvent2 === null || debugLogEvent2 === void 0
? void 0 this.element.setAttribute(
: debugLogEvent2({
kind: 'commit attribute',
element: this.element,
name: this.name,
value,
options: this.options
})
wrap(this.element).setAttribute(
this.name, this.name,
value !== null && value !== void 0 ? value : '' value !== null && value !== void 0 ? value : ''
) )
@ -764,15 +695,7 @@ class PropertyPart extends AttributePart {
} }
value = this._sanitizer(value) 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 this.element[this.name] = value === nothing ? void 0 : value
} }
} }
@ -783,22 +706,10 @@ class BooleanAttributePart extends AttributePart {
this.type = BOOLEAN_ATTRIBUTE_PART this.type = BOOLEAN_ATTRIBUTE_PART
} }
_commitValue(value) { _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) { if (value && value !== nothing) {
wrap(this.element).setAttribute( this.element.setAttribute(this.name, emptyStringForBooleanAttribute2)
this.name,
emptyStringForBooleanAttribute2
)
} else { } else {
wrap(this.element).removeAttribute(this.name) this.element.removeAttribute(this.name)
} }
} }
} }
@ -826,18 +737,7 @@ class EventPart extends AttributePart {
const shouldAddListener = const shouldAddListener =
newListener !== nothing && newListener !== nothing &&
(oldListener === nothing || shouldRemoveListener) (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) { if (shouldRemoveListener) {
this.element.removeEventListener(this.name, this, oldListener) this.element.removeEventListener(this.name, this, oldListener)
} }
@ -875,14 +775,6 @@ class ElementPart {
return this._$parent._$isConnected return this._$parent._$isConnected
} }
_$setValue(value) { _$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) resolveDirective(this, value)
} }
} }

View File

@ -3,6 +3,13 @@
* @author yutent<yutent.io@gmail.com> * @author yutent<yutent.io@gmail.com>
* @date 2023/03/07 18:10:43 * @date 2023/03/07 18:10:43
*/ */
import {
FINALIZED,
UPDATE,
DEFAULT_CONVERTER,
DEFAULT_PROPERTY_DECLARATION,
notEqual
} from './constants.js'
import { css, adoptStyles } from './css.js' import { css, adoptStyles } from './css.js'
import { render, html, svg } from './html.js' import { render, html, svg } from './html.js'
import { import {
@ -16,10 +23,9 @@ import {
clearOutsideClick, clearOutsideClick,
fire fire
} from './utils.js' } from './utils.js'
export { html, css, svg }
export { export {
html,
css,
svg,
$, $,
$$, $$,
nextTick, nextTick,
@ -30,52 +36,6 @@ export {
clearOutsideClick clearOutsideClick
} }
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 {
constructor() { constructor() {
super() super()
@ -85,14 +45,14 @@ export class Component extends HTMLElement {
this.hasUpdated = false this.hasUpdated = false
this.__reflectingProperty = null this.__reflectingProperty = null
this._initialize() this._initialize()
this.created && this.created()
} }
static addInitializer(initializer) { static addInitializer(initializer) {
var _a4
this.finalize() this.finalize()
;((_a4 = this._initializers) !== null && _a4 !== void 0 if (!this._initializers) {
? _a4 this._initializers = []
: (this._initializers = []) }
).push(initializer) this._initializers.push(initializer)
} }
static get observedAttributes() { static get observedAttributes() {
this.finalize() this.finalize()
@ -106,11 +66,11 @@ export class Component extends HTMLElement {
}) })
return attributes return attributes
} }
static createProperty(name, options = defaultPropertyDeclaration) { static createProperty(name, options = DEFAULT_PROPERTY_DECLARATION) {
if (options.state) { if (options.state) {
options.attribute = false options.attribute = false
} }
this.finalize()
this.elementProperties.set(name, options) this.elementProperties.set(name, options)
let key = Symbol(name) let key = Symbol(name)
@ -133,13 +93,13 @@ export class Component extends HTMLElement {
} }
} }
static getPropertyOptions(name) { static getPropertyOptions(name) {
return this.elementProperties.get(name) || defaultPropertyDeclaration return this.elementProperties.get(name) || DEFAULT_PROPERTY_DECLARATION
} }
static finalize() { static finalize() {
if (this.hasOwnProperty(finalized)) { if (this[FINALIZED]) {
return false return false
} }
this[finalized] = true this[FINALIZED] = true
this.elementProperties = new Map() this.elementProperties = new Map()
this.__attributeToPropertyMap = new Map() this.__attributeToPropertyMap = new Map()
@ -163,32 +123,24 @@ export class Component extends HTMLElement {
: void 0 : void 0
} }
_initialize() { _initialize() {
var _a4
this.__updatePromise = new Promise(res => (this.enableUpdating = res)) this.__updatePromise = new Promise(res => (this.enableUpdating = res))
this._$changedProperties = new Map() this._$changedProperties = new Map()
this.__saveInstanceProperties() this.__saveInstanceProperties()
this.requestUpdate() this.requestUpdate()
;(_a4 = this.constructor._initializers) === null || _a4 === void 0 this.constructor._initializers?.forEach(i => i(this))
? void 0
: _a4.forEach(i => i(this))
} }
addController(controller) { addController(controller) {
var _a4, _b4 if (!this.__controllers) {
;((_a4 = this.__controllers) !== null && _a4 !== void 0 this.__controllers = []
? _a4 }
: (this.__controllers = []) this.__controllers.push(controller)
).push(controller)
if (this.root !== void 0 && this.isConnected) { if (this.root !== void 0 && this.isConnected) {
;(_b4 = controller.hostConnected) === null || _b4 === void 0 controller.hostConnected?.call(controller)
? void 0
: _b4.call(controller)
} }
} }
removeController(controller) { removeController(controller) {
var _a4 this.__controllers?.splice(this.__controllers.indexOf(controller) >>> 0, 1)
;(_a4 = this.__controllers) === null || _a4 === void 0
? void 0
: _a4.splice(this.__controllers.indexOf(controller) >>> 0, 1)
} }
__saveInstanceProperties() { __saveInstanceProperties() {
this.constructor.elementProperties.forEach((_v, p) => { this.constructor.elementProperties.forEach((_v, p) => {
@ -198,54 +150,33 @@ export class Component extends HTMLElement {
} }
}) })
} }
createRenderRoot() {
let root = this.shadowRoot || this.attachShadow({ mode: 'open' })
adoptStyles(root, this.constructor.styles)
return root
}
connectedCallback() { connectedCallback() {
var _a4 this.root = this.shadowRoot || this.attachShadow({ mode: 'open' })
if (this.root === void 0) {
this.root = this.createRenderRoot() adoptStyles(this.root, this.constructor.styles)
}
this.enableUpdating(true) this.enableUpdating(true)
;(_a4 = this.__controllers) === null || _a4 === void 0
? void 0 this.__controllers?.forEach(it => it.hostConnected?.call(it))
: _a4.forEach(c => { this.__childPart?.setConnected(true)
var _a5
return (_a5 = c.hostConnected) === null || _a5 === void 0 this.mounted && this.mounted()
? void 0
: _a5.call(c)
})
this.__childPart && this.__childPart.setConnected(true)
} }
enableUpdating(_requestedUpdate) {} enableUpdating(_requestedUpdate) {}
disconnectedCallback() { disconnectedCallback() {
var _a4 this.__controllers?.forEach(it => it.hostDisconnected?.call(it))
;(_a4 = this.__controllers) === null || _a4 === void 0 this.__childPart?.setConnected(false)
? 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) { attributeChangedCallback(name, _old, value) {
this._$attributeToProperty(name, value) this._$attributeToProperty(name, value)
} }
__propertyToAttribute(name, value, options = defaultPropertyDeclaration) { __propertyToAttribute(name, value, options = DEFAULT_PROPERTY_DECLARATION) {
var _a4
const attr = this.constructor.__attributeNameForProperty(name, options) const attr = this.constructor.__attributeNameForProperty(name, options)
if (attr !== void 0 && options.reflect === true) { if (attr !== void 0 && options.reflect === true) {
const converter = const converter = options.converter?.toAttribute
((_a4 = options.converter) === null || _a4 === void 0
? void 0
: _a4.toAttribute) !== void 0
? options.converter ? options.converter
: defaultConverter : DEFAULT_CONVERTER
const attrValue = converter.toAttribute(value, options.type) const attrValue = converter.toAttribute(value, options.type)
this.__reflectingProperty = name this.__reflectingProperty = name
@ -258,7 +189,6 @@ export class Component extends HTMLElement {
} }
} }
_$attributeToProperty(name, value) { _$attributeToProperty(name, value) {
var _a4
const ctor = this.constructor const ctor = this.constructor
const propName = ctor.__attributeToPropertyMap.get(name) const propName = ctor.__attributeToPropertyMap.get(name)
if (propName !== void 0 && this.__reflectingProperty !== propName) { if (propName !== void 0 && this.__reflectingProperty !== propName) {
@ -266,11 +196,9 @@ export class Component extends HTMLElement {
const converter = const converter =
typeof options.converter === 'function' typeof options.converter === 'function'
? { fromAttribute: options.converter } ? { fromAttribute: options.converter }
: ((_a4 = options.converter) === null || _a4 === void 0 : options.converter?.fromAttribute
? void 0
: _a4.fromAttribute) !== void 0
? options.converter ? options.converter
: defaultConverter : DEFAULT_CONVERTER
this.__reflectingProperty = propName this.__reflectingProperty = propName
this[propName] = converter.fromAttribute(value, options.type) this[propName] = converter.fromAttribute(value, options.type)
this.__reflectingProperty = null this.__reflectingProperty = null
@ -316,7 +244,6 @@ export class Component extends HTMLElement {
return this.performUpdate() return this.performUpdate()
} }
performUpdate() { performUpdate() {
var _a4, _b4
if (!this.isUpdatePending) { if (!this.isUpdatePending) {
return return
} }
@ -325,44 +252,20 @@ export class Component extends HTMLElement {
this.__instanceProperties.forEach((v, p) => (this[p] = v)) this.__instanceProperties.forEach((v, p) => (this[p] = v))
this.__instanceProperties = void 0 this.__instanceProperties = void 0
} }
let shouldUpdate = false
const changedProperties = this._$changedProperties const changedProperties = this._$changedProperties
try { try {
shouldUpdate = this.shouldUpdate(changedProperties) this.__controllers?.forEach(it => it.hostUpdate?.call(it))
if (shouldUpdate) { this[UPDATE](changedProperties)
this.willUpdate(changedProperties) this._$didUpdate(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) { } catch (e) {
shouldUpdate = false
this.__markUpdated() this.__markUpdated()
throw e throw e
} }
if (shouldUpdate) {
this._$didUpdate(changedProperties)
} }
}
willUpdate(_changedProperties) {}
_$didUpdate(changedProperties) { _$didUpdate(changedProperties) {
var _a4 this.__controllers?.forEach(it => it.hostUpdated?.call(it))
;(_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) { if (!this.hasUpdated) {
this.hasUpdated = true this.hasUpdated = true
this.firstUpdated(changedProperties) this.firstUpdated(changedProperties)
@ -379,13 +282,10 @@ export class Component extends HTMLElement {
getUpdateComplete() { getUpdateComplete() {
return this.__updatePromise return this.__updatePromise
} }
shouldUpdate(_changedProperties) {
return true
}
update(_changedProperties) {
const value = this.render()
/* */ [UPDATE](_changedProperties) {
let value = this.render()
if (this.__reflectingProperties !== void 0) { if (this.__reflectingProperties !== void 0) {
this.__reflectingProperties.forEach((v, k) => this.__reflectingProperties.forEach((v, k) =>
this.__propertyToAttribute(k, this[k], v) this.__propertyToAttribute(k, this[k], v)