一大波精简

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",
"version": "0.1.0",
"version": "0.2.0",
"type": "module",
"description": "9号UI组件库的核心",
"main": "dist/index.js",

View File

@ -4,9 +4,57 @@
* @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 = `
* {box-sizing: border-box;margin: 0;padding: 0;}
::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 global3 = window
var debugLogEvent2 = void 0
var debugLogRenderId = 0
var issueWarning2
var wrap = node => node
var identityFunction = value => value
var noopSanitizer = (_node, _name, _type) => identityFunction
var setSanitizer = newSanitizer => {
@ -262,15 +259,6 @@ class Template {
}
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')
@ -396,16 +384,6 @@ class TemplateInstance {
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
@ -448,7 +426,7 @@ class ChildPart {
: this.__isConnected
}
get parentNode() {
let parentNode = wrap(this._$startNode).parentNode
let parentNode = this._$startNode.parentNode
const parent = this._$parent
if (parent !== void 0 && parentNode.nodeType === 11) {
parentNode = parent.parentNode
@ -468,15 +446,6 @@ class ChildPart {
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
@ -494,7 +463,7 @@ class ChildPart {
}
}
_insert(node, ref = this._$endNode) {
return wrap(wrap(this._$startNode).parentNode).insertBefore(node, ref)
return this._$startNode.parentNode.insertBefore(node, ref)
}
_commitNode(value) {
var _a4
@ -514,15 +483,7 @@ class ChildPart {
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)
}
}
@ -531,21 +492,14 @@ class ChildPart {
this._$committedValue !== nothing &&
isPrimitive(this._$committedValue)
) {
const node = wrap(this._$startNode).nextSibling
const node = 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) {
@ -555,25 +509,10 @@ class ChildPart {
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
@ -635,18 +574,18 @@ class ChildPart {
partIndex++
}
if (partIndex < itemParts.length) {
this._$clear(itemPart && wrap(itemPart._$endNode).nextSibling, partIndex)
this._$clear(itemPart && itemPart._$endNode.nextSibling, partIndex)
itemParts.length = partIndex
}
}
_$clear(start = wrap(this._$startNode).nextSibling, from) {
_$clear(start = 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()
const n = start.nextSibling
start.remove()
start = n
}
}
@ -720,7 +659,7 @@ class AttributePart {
}
_commitValue(value) {
if (value === nothing) {
wrap(this.element).removeAttribute(this.name)
this.element.removeAttribute(this.name)
} else {
if (ENABLE_EXTRA_SECURITY_HOOKS) {
if (this._sanitizer === void 0) {
@ -732,16 +671,8 @@ class AttributePart {
}
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.element.setAttribute(
this.name,
value !== null && value !== void 0 ? value : ''
)
@ -764,15 +695,7 @@ class PropertyPart extends AttributePart {
}
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
}
}
@ -783,22 +706,10 @@ class BooleanAttributePart extends AttributePart {
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
)
this.element.setAttribute(this.name, emptyStringForBooleanAttribute2)
} else {
wrap(this.element).removeAttribute(this.name)
this.element.removeAttribute(this.name)
}
}
}
@ -826,18 +737,7 @@ class EventPart extends AttributePart {
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)
}
@ -875,14 +775,6 @@ class ElementPart {
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)
}
}

View File

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