-
Notifications
You must be signed in to change notification settings - Fork 4.9k
feat: taro 支持 ttdom #18850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: taro 支持 ttdom #18850
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,5 @@ | ||||||||||||||||||||||||||||||||||||||||
| import { convertNumber2PX, FormElement } from '@tarojs/runtime' | ||||||||||||||||||||||||||||||||||||||||
| import { capitalize, internalComponents, isFunction, isNumber, isObject, isString, PLATFORM_TYPE, toCamelCase } from '@tarojs/shared' | ||||||||||||||||||||||||||||||||||||||||
| import { convertNumber2PX, eventHandlerTTDom, FormElement, setInnerHTML } from '@tarojs/runtime' | ||||||||||||||||||||||||||||||||||||||||
| import { capitalize, internalComponents, isEnableTTDom, isFunction, isNumber, isObject, isString, PLATFORM_TYPE, toCamelCase, UNITLESS_PROPERTIES_SET } from '@tarojs/shared' | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| import type { Style, TaroElement } from '@tarojs/runtime' | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
@@ -8,6 +8,7 @@ import type { Style, TaroElement } from '@tarojs/runtime' | |||||||||||||||||||||||||||||||||||||||
| export type Props = Record<string, unknown> | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const IS_NON_DIMENSIONAL = /aspect|acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i | ||||||||||||||||||||||||||||||||||||||||
| const IS_DATASET_OR_ARIA = /^(data|aria)-/ | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| function isEventName (s: string) { | ||||||||||||||||||||||||||||||||||||||||
| return s[0] === 'o' && s[1] === 'n' | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -125,6 +126,17 @@ function setEvent (dom: TaroElement, name: string, value: unknown, oldValue?: un | |||||||||||||||||||||||||||||||||||||||
| eventName = 'tap' | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { | ||||||||||||||||||||||||||||||||||||||||
| if (isFunction(oldValue)) { | ||||||||||||||||||||||||||||||||||||||||
| (dom as any).removeEventListener(`bind${eventName}`, dom[`__${eventName}__`]) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| if (isFunction(value)) { | ||||||||||||||||||||||||||||||||||||||||
| dom[`__${eventName}__`] = eventHandlerTTDom.bind(null, dom, value) | ||||||||||||||||||||||||||||||||||||||||
| dom.addEventListener(`bind${eventName}`, dom[`__${eventName}__`], isCapture) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
xzdadada marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (isFunction(value)) { | ||||||||||||||||||||||||||||||||||||||||
| if (oldValue) { | ||||||||||||||||||||||||||||||||||||||||
| dom.removeEventListener(eventName, oldValue as any, process.env.TARO_PLATFORM !== PLATFORM_TYPE.HARMONY ? false : undefined) | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -228,42 +240,50 @@ function setProperty (dom: TaroElement, name: string, value: unknown, oldValue?: | |||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||
| // skip | ||||||||||||||||||||||||||||||||||||||||
| } else if (name === 'style') { | ||||||||||||||||||||||||||||||||||||||||
| if (/harmony.*cpp/.test(process.env.TARO_ENV || '')) { | ||||||||||||||||||||||||||||||||||||||||
| return dom.setAttribute('_style4cpp', value) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| const style = dom.style | ||||||||||||||||||||||||||||||||||||||||
| if (isString(value)) { | ||||||||||||||||||||||||||||||||||||||||
| style.cssText = value | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { | ||||||||||||||||||||||||||||||||||||||||
| if (isString(value)) { | ||||||||||||||||||||||||||||||||||||||||
| dom.setAttribute('style', value) | ||||||||||||||||||||||||||||||||||||||||
| } else if (isObject(value)) { | ||||||||||||||||||||||||||||||||||||||||
| dom.setAttribute('style', styleObjectToCss(value as StyleValue)) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
xzdadada marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||
| if (isString(oldValue)) { | ||||||||||||||||||||||||||||||||||||||||
| style.cssText = '' | ||||||||||||||||||||||||||||||||||||||||
| oldValue = null | ||||||||||||||||||||||||||||||||||||||||
| if (/harmony.*cpp/.test(process.env.TARO_ENV || '')) { | ||||||||||||||||||||||||||||||||||||||||
| return dom.setAttribute('_style4cpp', value) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| const style = dom.style | ||||||||||||||||||||||||||||||||||||||||
| if (isString(value)) { | ||||||||||||||||||||||||||||||||||||||||
| style.cssText = value | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| if (isString(oldValue)) { | ||||||||||||||||||||||||||||||||||||||||
| style.cssText = '' | ||||||||||||||||||||||||||||||||||||||||
| oldValue = null | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (isObject<StyleValue>(oldValue)) { | ||||||||||||||||||||||||||||||||||||||||
| for (const i in oldValue) { | ||||||||||||||||||||||||||||||||||||||||
| if (!(value && i in (value as StyleValue))) { | ||||||||||||||||||||||||||||||||||||||||
| // Harmony特殊处理 | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position' && oldValue[i] === 'fixed') { | ||||||||||||||||||||||||||||||||||||||||
| // @ts-ignore | ||||||||||||||||||||||||||||||||||||||||
| dom.setLayer(0) | ||||||||||||||||||||||||||||||||||||||||
| if (isObject<StyleValue>(oldValue)) { | ||||||||||||||||||||||||||||||||||||||||
| for (const i in oldValue) { | ||||||||||||||||||||||||||||||||||||||||
| if (!(value && i in (value as StyleValue))) { | ||||||||||||||||||||||||||||||||||||||||
| // Harmony特殊处理 | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position' && oldValue[i] === 'fixed') { | ||||||||||||||||||||||||||||||||||||||||
| // @ts-ignore | ||||||||||||||||||||||||||||||||||||||||
| dom.setLayer(0) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| setStyle(style, i, '') | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| setStyle(style, i, '') | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (isObject<StyleValue>(value)) { | ||||||||||||||||||||||||||||||||||||||||
| for (const i in value) { | ||||||||||||||||||||||||||||||||||||||||
| if (!oldValue || !isEqual(value[i], (oldValue as StyleValue)[i])) { | ||||||||||||||||||||||||||||||||||||||||
| // Harmony特殊处理 | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position') { | ||||||||||||||||||||||||||||||||||||||||
| if (value[i] === 'fixed' || (value[i] !== 'fixed' && oldValue?.[i])) { | ||||||||||||||||||||||||||||||||||||||||
| // @ts-ignore | ||||||||||||||||||||||||||||||||||||||||
| dom.setLayer(value[i] === 'fixed' ? 1 : 0) | ||||||||||||||||||||||||||||||||||||||||
| if (isObject<StyleValue>(value)) { | ||||||||||||||||||||||||||||||||||||||||
| for (const i in value) { | ||||||||||||||||||||||||||||||||||||||||
| if (!oldValue || !isEqual(value[i], (oldValue as StyleValue)[i])) { | ||||||||||||||||||||||||||||||||||||||||
| // Harmony特殊处理 | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position') { | ||||||||||||||||||||||||||||||||||||||||
| if (value[i] === 'fixed' || (value[i] !== 'fixed' && oldValue?.[i])) { | ||||||||||||||||||||||||||||||||||||||||
| // @ts-ignore | ||||||||||||||||||||||||||||||||||||||||
| dom.setLayer(value[i] === 'fixed' ? 1 : 0) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| setStyle(style, i, value[i]) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| setStyle(style, i, value[i]) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -275,10 +295,17 @@ function setProperty (dom: TaroElement, name: string, value: unknown, oldValue?: | |||||||||||||||||||||||||||||||||||||||
| const oldHtml = (oldValue as DangerouslySetInnerHTML)?.__html ?? '' | ||||||||||||||||||||||||||||||||||||||||
| if (newHtml || oldHtml) { | ||||||||||||||||||||||||||||||||||||||||
| if (oldHtml !== newHtml) { | ||||||||||||||||||||||||||||||||||||||||
| dom.innerHTML = newHtml | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { | ||||||||||||||||||||||||||||||||||||||||
| setInnerHTML(dom, newHtml) | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| dom.innerHTML = newHtml | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } else if (!isFunction(value)) { | ||||||||||||||||||||||||||||||||||||||||
| if (process.env.TARO_ENV === 'tt' && isEnableTTDom() && !IS_DATASET_OR_ARIA.test(name)) { | ||||||||||||||||||||||||||||||||||||||||
| name = toCamelCase(name) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| if (value == null) { | ||||||||||||||||||||||||||||||||||||||||
| dom.removeAttribute(name) | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -297,3 +324,13 @@ function setPseudo(dom: TaroElement, name: '::after' | '::before', value: StyleV | |||||||||||||||||||||||||||||||||||||||
| dom.set_pseudo_before(value) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| function styleObjectToCss(style: StyleValue) { | ||||||||||||||||||||||||||||||||||||||||
| return Object.entries(style) | ||||||||||||||||||||||||||||||||||||||||
| .map(([key, value]) => { | ||||||||||||||||||||||||||||||||||||||||
| const kebabCaseKey = key.replace(/([A-Z])/g, '-$1').toLowerCase() | ||||||||||||||||||||||||||||||||||||||||
| const cssValue = typeof value === 'number' && !UNITLESS_PROPERTIES_SET.has(kebabCaseKey) ? `${value}px` : value === null ? '' : value | ||||||||||||||||||||||||||||||||||||||||
| return `${kebabCaseKey}: ${cssValue};` | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| .join(' ') | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+328
to
+336
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
当 style 对象中某个属性值为 🔧 建议修复 function styleObjectToCss(style: StyleValue) {
return Object.entries(style)
+ .filter(([, value]) => value != null)
.map(([key, value]) => {
const kebabCaseKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()
const cssValue = typeof value === 'number' && !UNITLESS_PROPERTIES_SET.has(kebabCaseKey) ? `${value}px` : value === null ? '' : value
return `${kebabCaseKey}: ${cssValue};`
})
.join(' ')
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TT DOM 事件缓存键会让冒泡/捕获监听互相覆盖。
这里把缓存固定在
dom[\${eventName}`]。onClick和onClickCapture` 会落到同一个键上,后注册的会覆盖前一个;后续更新或卸载其中一个 prop 时,也会把另一个监听误删/遗留。🔧 建议修复
function setEvent (dom: TaroElement, name: string, value: unknown, oldValue?: unknown) { const isCapture = name.endsWith('Capture') + const handlerKey = `__${name}__` let eventName = name.toLowerCase().slice(2) if (isCapture) { eventName = eventName.slice(0, -7) } @@ if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { if (isFunction(oldValue)) { - (dom as any).removeEventListener(`bind${eventName}`, dom[`__${eventName}__`]) + (dom as any).removeEventListener(`bind${eventName}`, dom[handlerKey], isCapture) } if (isFunction(value)) { - dom[`__${eventName}__`] = eventHandlerTTDom.bind(null, dom, value) - dom.addEventListener(`bind${eventName}`, dom[`__${eventName}__`], isCapture) + dom[handlerKey] = eventHandlerTTDom.bind(null, dom, value) + dom.addEventListener(`bind${eventName}`, dom[handlerKey], isCapture) } return }🤖 Prompt for AI Agents