mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-23 05:41:20 -08:00
refactor(core): [CORE-20] type entry and converge initialization
This commit is contained in:
1 parent
ccf77c4ed2
commit
ee895a558f
100 files changed
+33854
-839
No files matched your search
@@ -0,0 +1,22 @@
|
||||
interface EventPathSource {
|
||||
target: EventTarget | null
|
||||
composedPath?: () => EventTarget[]
|
||||
}
|
||||
|
||||
export function getComposedPath(event: EventPathSource): EventTarget[] {
|
||||
if (event.composedPath)
|
||||
return event.composedPath()
|
||||
const path: EventTarget[] = []
|
||||
let node = event.target
|
||||
while (node) {
|
||||
path.push(node)
|
||||
node = (node as EventTarget & { parentNode?: EventTarget | null }).parentNode ?? null
|
||||
}
|
||||
if (typeof window !== 'undefined' && !path.includes(window))
|
||||
path.push(window)
|
||||
return path
|
||||
}
|
||||
|
||||
export function includeFromEvent(event: EventPathSource, target: EventTarget | null | undefined): boolean {
|
||||
return getComposedPath(event).includes(target as EventTarget)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
export function supportsFlex(): boolean {
|
||||
const div = document.createElement('div')
|
||||
div.style.display = 'flex'
|
||||
return div.style.display === 'flex'
|
||||
}
|
||||
|
||||
export function getRect(el: Pick<Element, 'getBoundingClientRect'>): DOMRect {
|
||||
return el.getBoundingClientRect()
|
||||
}
|
||||
|
||||
export function isInViewport(el: Pick<Element, 'getBoundingClientRect'>, offset = 0): boolean {
|
||||
const rect = el.getBoundingClientRect()
|
||||
const windowHeight = window.innerHeight || document.documentElement.clientHeight
|
||||
const windowWidth = window.innerWidth || document.documentElement.clientWidth
|
||||
const vertInView = rect.top - offset <= windowHeight && rect.top + rect.height + offset >= 0
|
||||
const horInView = rect.left - offset <= windowWidth + offset && rect.left + rect.width + offset >= 0
|
||||
return vertInView && horInView
|
||||
}
|
||||
|
||||
export function getSafeAreaInsets(): { top: number, right: number, bottom: number, left: number } {
|
||||
const div = document.createElement('div')
|
||||
div.style.cssText
|
||||
= 'position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;'
|
||||
try {
|
||||
document.body.appendChild(div)
|
||||
const style = getComputedStyle(div)
|
||||
return {
|
||||
top: Number.parseFloat(style.top) || 0,
|
||||
right: Number.parseFloat(style.right) || 0,
|
||||
bottom: Number.parseFloat(style.bottom) || 0,
|
||||
left: Number.parseFloat(style.left) || 0,
|
||||
}
|
||||
}
|
||||
finally {
|
||||
div.remove()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { isMobile } from '../utils/compatibility'
|
||||
import { addClass, append, createElement } from './tree'
|
||||
|
||||
export function tooltip(target: Element, msg: string | number, pos = 'top'): void {
|
||||
if (isMobile)
|
||||
return
|
||||
target.setAttribute('aria-label', msg as string)
|
||||
addClass(target, 'hint--rounded')
|
||||
addClass(target, `hint--${pos}`)
|
||||
}
|
||||
|
||||
export function getIcon(key = '', html: string | HTMLElement = ''): HTMLElement {
|
||||
const icon = createElement('i')
|
||||
addClass(icon, 'art-icon')
|
||||
addClass(icon, `art-icon-${key}`)
|
||||
append(icon, html)
|
||||
return icon
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
interface StyledElement { style: CSSStyleDeclaration }
|
||||
|
||||
export function setStyle<T extends StyledElement>(element: T, key: PropertyKey, value: unknown): T {
|
||||
// Preserve bracket assignment, including native conversion and thrown setters.
|
||||
const style = element.style as unknown as Record<PropertyKey, unknown>
|
||||
style[key] = value
|
||||
return element
|
||||
}
|
||||
|
||||
export function setStyles<T extends StyledElement>(element: T, styles: object): T {
|
||||
for (const key in styles)
|
||||
setStyle(element, key, (styles as Record<string, unknown>)[key])
|
||||
return element
|
||||
}
|
||||
|
||||
export function getStyle(element: Element, key: string, numberType?: true): number
|
||||
export function getStyle(element: Element, key: string, numberType: false): string
|
||||
export function getStyle(element: Element, key: string, numberType: boolean): number | string
|
||||
export function getStyle(element: Element, key: string, numberType = true): number | string {
|
||||
const value = window.getComputedStyle(element, null).getPropertyValue(key)
|
||||
return numberType ? Number.parseFloat(value) : value
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
export function query<T extends Element = Element>(selector: string, parent: ParentNode = document): T | null {
|
||||
return parent.querySelector<T>(selector)
|
||||
}
|
||||
|
||||
export function queryAll<T extends Element = Element>(selector: string, parent: ParentNode = document): T[] {
|
||||
return Array.from(parent.querySelectorAll<T>(selector))
|
||||
}
|
||||
|
||||
export function addClass(target: Pick<Element, 'classList'>, className: string): void {
|
||||
return target.classList.add(className)
|
||||
}
|
||||
|
||||
export function removeClass(target: Pick<Element, 'classList'>, className: string): void {
|
||||
return target.classList.remove(className)
|
||||
}
|
||||
|
||||
export function hasClass(target: Pick<Element, 'classList'>, className: string): boolean {
|
||||
return target.classList.contains(className)
|
||||
}
|
||||
|
||||
export function append(parent: Element, child: unknown): Element | ChildNode | null {
|
||||
if (child instanceof Element) {
|
||||
parent.appendChild(child)
|
||||
}
|
||||
else {
|
||||
parent.insertAdjacentHTML('beforeend', String(child))
|
||||
}
|
||||
return parent.lastElementChild || parent.lastChild
|
||||
}
|
||||
|
||||
export function remove<T extends Node>(child: T): T {
|
||||
// Detached nodes retain their historical failure rather than becoming no-ops.
|
||||
return child.parentNode!.removeChild(child)
|
||||
}
|
||||
|
||||
export function siblings(target: Element): Element[] {
|
||||
return Array.from(target.parentElement!.children).filter(item => item !== target)
|
||||
}
|
||||
|
||||
export function inverseClass(target: Element, className: string): void {
|
||||
siblings(target).forEach(item => removeClass(item, className))
|
||||
addClass(target, className)
|
||||
}
|
||||
|
||||
export function replaceElement<T extends Node>(newChild: T, oldChild: Node): T {
|
||||
oldChild.parentNode!.replaceChild(newChild, oldChild)
|
||||
return newChild
|
||||
}
|
||||
|
||||
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K): HTMLElementTagNameMap[K]
|
||||
export function createElement(tag: string): HTMLElement
|
||||
export function createElement(tag: string): HTMLElement {
|
||||
return document.createElement(tag)
|
||||
}
|
||||
Reference in new issue
Block a user