Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-app
提交
8252b254
U
uni-app
项目概览
DCloud
/
uni-app
3 个月 前同步成功
通知
725
Star
38705
Fork
3642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
7
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
7
Issue
7
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8252b254
编写于
2月 17, 2022
作者:
D
DCloud_LXH
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(nvue): rich-text
上级
61ebfa6c
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
264 addition
and
3 deletion
+264
-3
packages/uni-components/src/components/rich-text/html-parser.js
...es/uni-components/src/components/rich-text/html-parser.js
+0
-0
packages/uni-components/src/components/rich-text/index.ts
packages/uni-components/src/components/rich-text/index.ts
+5
-1
packages/uni-components/src/nvue/components.ts
packages/uni-components/src/nvue/components.ts
+2
-0
packages/uni-components/src/nvue/rich-text/index.tsx
packages/uni-components/src/nvue/rich-text/index.tsx
+256
-0
packages/uni-components/src/vue/rich-text/index.tsx
packages/uni-components/src/vue/rich-text/index.tsx
+1
-2
未找到文件。
packages/uni-components/src/
vue
/rich-text/html-parser.js
→
packages/uni-components/src/
components
/rich-text/html-parser.js
浏览文件 @
8252b254
文件已移动
packages/uni-components/src/components/rich-text.ts
→
packages/uni-components/src/components/rich-text
/index
.ts
浏览文件 @
8252b254
export
const
props
=
{
import
parseHtml
from
'
./html-parser
'
const
props
=
{
nodes
:
{
type
:
[
Array
,
String
],
default
:
function
()
{
...
...
@@ -6,3 +8,5 @@ export const props = {
},
},
}
export
{
props
,
parseHtml
}
packages/uni-components/src/nvue/components.ts
浏览文件 @
8252b254
...
...
@@ -17,6 +17,7 @@ import Form from './form'
import
Icon
from
'
./icon
'
import
Swiper
from
'
./swiper
'
import
SwiperItem
from
'
./swiper-item
'
import
RichText
from
'
./rich-text
'
export
default
{
Navigator
,
Label
,
...
...
@@ -37,4 +38,5 @@ export default {
Icon
,
Swiper
,
SwiperItem
,
RichText
,
}
packages/uni-components/src/nvue/rich-text/index.tsx
0 → 100644
浏览文件 @
8252b254
import
{
defineComponent
,
ExtractPropTypes
,
getCurrentInstance
,
ComponentInternalInstance
,
// @ts-ignore
parseClassList
,
}
from
'
vue
'
import
{
props
,
parseHtml
}
from
'
../../components/rich-text
'
import
{
parseStyleText
}
from
'
../helpers
'
const
defaultFontSize
=
16
type
Props
=
ExtractPropTypes
<
typeof
props
>
export
default
defineComponent
({
name
:
'
RichText
'
,
props
,
setup
(
props
)
{
const
instance
=
getCurrentInstance
()
return
()
=>
{
let
nodes
=
props
.
nodes
if
(
typeof
nodes
===
'
string
'
)
{
nodes
=
parseHtml
(
nodes
)
}
return
(
<
u
-
rich
-
text
{
...{
value
:
normalizeNodes
(
nodes
||
[],
instance
,
{
defaultFontSize
,
}),
}
}
></
u
-
rich
-
text
>
)
}
},
})
function
normalizeNodes
(
nodes
:
Props
[
'
nodes
'
],
instance
:
ComponentInternalInstance
|
null
,
options
:
{
defaultFontSize
:
number
}
)
{
type
NodeType
=
keyof
typeof
strategies
|
'
span
'
|
'
img
'
|
'
image
'
|
'
text
'
type
NvueNode
=
{
type
?:
NodeType
__type
?:
string
name
?:
string
attrs
?:
{
class
:
string
width
:
string
height
:
string
style
:
string
}
attr
?:
{
value
:
string
}
text
?:
string
__block
?:
boolean
__break
?:
boolean
__value
?:
string
style
?:
Record
<
string
,
any
>
children
?:
NvueNode
[]
}
const
TAGS
=
[
'
span
'
,
'
a
'
,
'
image
'
,
'
img
'
]
const
strategies
=
{
blockquote
:
block
,
br
:
br
,
div
:
block
,
dl
:
block
,
h1
:
createHeading
(
2
),
h2
:
createHeading
(
1.5
),
h3
:
createHeading
(
1.17
),
h4
:
createHeading
(
1
),
h5
:
createHeading
(
0.83
),
h6
:
createHeading
(
0.67
),
hr
:
block
,
ol
:
block
,
p
:
block
,
strong
:
bold
,
table
:
block
,
tbody
:
block
,
tfoot
:
block
,
thead
:
block
,
ul
:
block
,
}
const
HTML_RE
=
/&
(
amp|gt|lt|nbsp|quot|apos
)
;/g
const
CHARS
=
{
amp
:
'
&
'
,
gt
:
'
>
'
,
lt
:
'
<
'
,
nbsp
:
'
'
,
quot
:
'
"
'
,
apos
:
"
'
"
,
}
// 插入换行
const
breakNode
:
NvueNode
=
{
type
:
'
span
'
,
__type
:
'
break
'
,
attr
:
{
value
:
'
\n
'
,
},
}
let
lastNode
:
NvueNode
=
{
__block
:
true
,
__break
:
true
,
children
:
[],
}
let
breakNodes
:
NvueNode
[]
|
null
=
null
function
parseStyle
(
node
:
NvueNode
)
{
const
styles
=
Object
.
create
(
null
)
if
(
node
.
attrs
)
{
const
classList
=
(
node
.
attrs
.
class
||
''
).
split
(
'
'
)
Object
.
assign
(
styles
,
parseClassList
(
classList
,
instance
),
parseStyleText
(
node
.
attrs
.
style
||
''
)
)
}
if
(
node
.
name
===
'
img
'
||
node
.
name
===
'
image
'
)
{
const
attrs
=
node
.
attrs
styles
.
width
=
styles
.
width
||
attrs
!
.
width
styles
.
height
=
styles
.
height
||
attrs
!
.
height
}
return
styles
}
function
block
(
node
:
NvueNode
)
{
node
.
__block
=
true
// node.attr.value = (node.attr.value || '') + '\n'
return
node
}
function
heading
(
node
:
NvueNode
,
em
:
number
)
{
if
(
node
.
style
)
!
node
.
style
.
fontSize
&&
(
node
.
style
.
fontSize
=
options
.
defaultFontSize
*
em
)
return
block
(
bold
(
node
))
}
function
createHeading
(
em
:
number
)
{
return
function
(
node
:
NvueNode
)
{
return
heading
(
node
,
em
)
}
}
function
bold
(
node
:
NvueNode
)
{
if
(
node
.
style
)
!
node
.
style
.
fontWeight
&&
(
node
.
style
.
fontWeight
=
'
bold
'
)
return
node
}
function
br
(
node
:
NvueNode
)
{
node
.
__value
=
'
'
return
block
(
node
)
}
function
normalizeText
(
str
:
string
)
{
return
str
.
replace
(
HTML_RE
,
function
(
match
,
entity
:
keyof
typeof
CHARS
)
{
return
CHARS
[
entity
]
})
}
function
normalizeNode
(
node
:
NvueNode
)
{
let
type
:
NodeType
=
(
node
.
name
||
''
).
toLowerCase
()
as
NodeType
const
__type
=
type
const
strategy
=
strategies
[
type
as
keyof
typeof
strategies
]
if
(
TAGS
.
indexOf
(
type
)
===
-
1
)
{
type
=
'
span
'
}
if
(
type
===
'
img
'
)
{
type
=
'
image
'
}
const
nvueNode
:
NvueNode
=
{
type
,
__type
,
attr
:
Object
.
create
(
null
),
}
if
(
node
.
type
===
'
text
'
||
node
.
text
)
{
nvueNode
.
__value
=
nvueNode
.
attr
!
.
value
=
normalizeText
(
(
node
.
text
||
''
).
trim
()
)
}
if
(
node
.
attrs
)
{
Object
.
keys
(
node
.
attrs
).
forEach
((
name
)
=>
{
if
(
name
!==
'
class
'
&&
name
!==
'
style
'
)
{
;(
nvueNode
.
attr
as
any
)[
name
]
=
(
node
.
attrs
as
any
)[
name
]
}
})
}
nvueNode
.
style
=
parseStyle
(
node
)
if
(
strategy
)
{
strategy
(
nvueNode
)
}
if
(
lastNode
.
__block
||
nvueNode
.
__block
)
{
if
(
!
breakNodes
)
{
lastNode
.
children
!
.
push
(
breakNode
)
breakNodes
=
[
lastNode
,
breakNode
]
}
}
// 进入节点
lastNode
=
nvueNode
if
(
lastNode
.
__value
||
(
lastNode
.
type
===
'
image
'
&&
(
lastNode
.
attr
as
any
).
src
)
)
{
// 文本和图像消费换行
breakNodes
=
null
}
nvueNode
.
children
=
normalizeNodes
(
node
.
children
)
// 退出节点
lastNode
=
nvueNode
if
(
lastNode
.
__block
&&
(
lastNode
.
style
as
any
).
height
&&
!
/^0
(
px
)?
$/
.
test
((
lastNode
.
style
as
any
).
height
)
)
{
// 有高度的块元素消费换行
breakNodes
=
null
}
return
nvueNode
}
function
normalizeNodes
(
nodes
?:
NvueNode
[])
{
if
(
Array
.
isArray
(
nodes
))
{
return
nodes
.
map
((
node
)
=>
normalizeNode
(
node
))
}
return
[]
}
const
nvueNodes
=
normalizeNodes
(
nodes
as
NvueNode
[])
if
(
breakNodes
)
{
// 撤销未消费的换行
const
[
lastNode
,
breakNode
]
=
breakNodes
as
NvueNode
[]
const
children
=
lastNode
.
children
!
const
index
=
children
.
indexOf
(
breakNode
)
children
.
splice
(
index
,
1
)
}
return
nvueNodes
}
packages/uni-components/src/vue/rich-text/index.tsx
浏览文件 @
8252b254
...
...
@@ -4,9 +4,8 @@ import {
useCustomEvent
,
EmitEvent
,
}
from
'
@dcloudio/uni-components
'
import
parseHtml
from
'
./html-parser
'
import
parseNodes
from
'
./nodes-parser
'
import
{
props
}
from
'
../../components/rich-text
'
import
{
props
,
parseHtml
}
from
'
../../components/rich-text
'
export
default
/*#__PURE__*/
defineBuiltInComponent
({
name
:
'
RichText
'
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录