Skip to content
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

fix: 使用innerHTML赋值后转小程序时,a标签转view标签+img转image标签时,把width和height写入style属性 #16780

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions packages/taro-runtime/src/dom-external/inner-html/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { options } from '../../options'
import { Scaner, Token } from './scaner'
import StyleTagParser from './style'
import { isBlockElements, isInlineElements, isMiniElements, specialMiniElements } from './tags'
import { getSpecialElementMapping, isBlockElements, isInlineElements, isMiniElements, isSpecialElements, specialMiniElements } from './tags'
import { unquote } from './utils'

import type { TaroDocument } from '../../dom/document'
Expand Down Expand Up @@ -47,7 +47,7 @@
attributes: string[]
}

export interface ParsedTaroElement extends TaroElement{
export interface ParsedTaroElement extends TaroElement {
h5tagName?: string
}

Expand All @@ -71,7 +71,23 @@
return false
}

function getTagName (tag: string) {
/**
* 将属性数组转换为属性对象
* @param attributes 字符串数组,包含属性信息
* @returns 属性对象,键为属性名,值为属性值或true
*/
function attributesArray2Props (attributes: string[]): Record<string, string | true> {
const props: Record<string, string | true> = {}
for (let i = 0; i < attributes.length; i++) {
const attr = attributes[i]
const [key, value] = splitEqual(attr)

Check warning on line 83 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L79-L83

Added lines #L79 - L83 were not covered by tests
props[key] = value == null ? true : unquote(value)
}

return props

Check warning on line 87 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L87

Added line #L87 was not covered by tests
}

function getTagName (tag: string, attributes: string[]) {
if (options.html!.renderHTMLTag) {
return tag
}
Expand All @@ -84,6 +100,14 @@
return 'view'
} else if (isInlineElements(tag)) {
return 'text'
} else if (isSpecialElements(tag)) {
// if it's special tag, the real tag is determined by the config mapping
const mapping = getSpecialElementMapping(tag)
const props = attributesArray2Props(attributes)

Check warning on line 106 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L105-L106

Added lines #L105 - L106 were not covered by tests

if (mapping) {
return mapping.mapName(props)

Check warning on line 109 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L109

Added line #L109 was not covered by tests
}
}

return 'view'
Expand Down Expand Up @@ -127,8 +151,26 @@
parent?.appendChild(text)
return text
}
// img标签,把width和height写入style,删除原有的width、height和style属性
if (child.tagName === 'img') {
let styleText = ''
const toBeRemovedIndexs: number[] = []
for (let i = 0; i < child.attributes.length; i++) {
const attr = child.attributes[i]
const [key, value] = splitEqual(attr)

Check warning on line 160 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L156-L160

Added lines #L156 - L160 were not covered by tests
if (key === 'width' || key === 'height') {
styleText += `${key}:${value};`
toBeRemovedIndexs.push(i)

Check warning on line 163 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L162-L163

Added lines #L162 - L163 were not covered by tests
} else if (key === 'style') {
styleText = `${styleText}${value};`
toBeRemovedIndexs.push(i)

Check warning on line 166 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L165-L166

Added lines #L165 - L166 were not covered by tests
}
}
child.attributes = child.attributes.filter((_, index) => !toBeRemovedIndexs.includes(index))
child.attributes.push(`style=${styleText.replace(/['"]/g, '')}`)

Check warning on line 170 in packages/taro-runtime/src/dom-external/inner-html/parser.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/parser.ts#L169-L170

Added lines #L169 - L170 were not covered by tests
}

const el: ParsedTaroElement = document.createElement(getTagName(child.tagName))
const el: ParsedTaroElement = document.createElement(getTagName(child.tagName, child.attributes))
el.h5tagName = child.tagName

parent?.appendChild(el)
Expand Down
26 changes: 24 additions & 2 deletions packages/taro-runtime/src/dom-external/inner-html/tags.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a 标签是行内元素啊

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a标签在H5下是行内元素。
但在转小程序时,会根据参数的差异,转view 或者navigator(直接用a标签的时候)。

如果是innerHTML里用a标签的话,就直接转的text之前。如果a里套了image,就展示不出来了。
这里就是把innerHTML里a标签的转换逻辑,跟直接用a标签基本对齐

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { internalComponents } from '@tarojs/shared'
import { internalComponents, isString } from '@tarojs/shared'

export function makeMap (
str: string,
Expand All @@ -17,6 +17,25 @@
iframe: 'web-view'
}

interface SpecialMap {
mapName: (props: Record<string, string | boolean>) => string
}

const specialElements = new Map<string, SpecialMap>([
['a', {
mapName (props) {

Check warning on line 26 in packages/taro-runtime/src/dom-external/inner-html/tags.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/tags.ts#L26

Added line #L26 was not covered by tests
if (props.as && isString(props.as)) return props.as.toLowerCase()
return !props.href || isString(props.href) && (/^javascript/.test(props.href)) ? 'view' : 'navigator'
}
}],
])

export const getSpecialElementMapping = (tag: string, expectsLowerCase:boolean = true) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const getSpecialElementMapping = (tag: string, expectsLowerCase:boolean = true) => {
export const getSpecialElementMapping = (tag: string, expectsLowerCase: boolean = true) => {

tag = expectsLowerCase ? tag.toLowerCase() : tag
return specialElements.get(tag)

Check warning on line 35 in packages/taro-runtime/src/dom-external/inner-html/tags.ts

View check run for this annotation

Codecov / codecov/patch

packages/taro-runtime/src/dom-external/inner-html/tags.ts#L35

Added line #L35 was not covered by tests
}


const internalCompsList = Object.keys(internalComponents)
.map(i => i.toLowerCase())
.join(',')
Expand All @@ -25,7 +44,10 @@
export const isMiniElements = makeMap(internalCompsList, true)

// https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements
export const isInlineElements = makeMap('a,i,abbr,iframe,select,acronym,slot,small,span,bdi,kbd,strong,big,map,sub,sup,br,mark,mark,meter,template,canvas,textarea,cite,object,time,code,output,u,data,picture,tt,datalist,var,dfn,del,q,em,s,embed,samp,b', true)
export const isInlineElements = makeMap('i,abbr,iframe,select,acronym,slot,small,span,bdi,kbd,strong,big,map,sub,sup,br,mark,mark,meter,template,canvas,textarea,cite,object,time,code,output,u,data,picture,tt,datalist,var,dfn,del,q,em,s,embed,samp,b', true)

// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
export const isBlockElements = makeMap('address,fieldset,li,article,figcaption,main,aside,figure,nav,blockquote,footer,ol,details,form,p,dialog,h1,h2,h3,h4,h5,h6,pre,dd,header,section,div,hgroup,table,dl,hr,ul,dt', true)

// specialElements
export const isSpecialElements = makeMap('a', true)
Loading