feat: enhance link handling in reading page
- Added functionality to open article links in a mini program web-view, allowing users to preview external links. - Implemented mobile hints for external links to improve user experience on mobile devices. - Updated content parser to support new link types, including regular hyperlinks. - Enhanced styling for article links to improve visibility and interaction. Made-with: Cursor
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* { type: 'text', text }
|
||||
* { type: 'mention', userId, nickname } — @某人,点击加好友(提交存客宝见 utils/soulBridge.submitCkbLead)
|
||||
* { type: 'linkTag', label, url, ... } — #链接标签,点击跳转(阅读页 onLinkTagTap:外链→link-preview、小程序→navigateToMiniProgram)
|
||||
* { type: 'link', text, url } — 普通超链接,点击外链预览(阅读页 onArticleLinkTap)
|
||||
* { type: 'image', src, alt } — 图片
|
||||
* { type: 'video', src } — 内嵌视频(管理端 rich-video-wrap / <video>)
|
||||
*/
|
||||
@@ -100,7 +101,7 @@ function stripTrailingAtForMention(before) {
|
||||
|
||||
/**
|
||||
* 将一个 HTML block 字符串解析为 segments 数组
|
||||
* 处理内联元素:mention / linkTag(span) / linkTag(a) / img / video
|
||||
* 处理内联元素:mention / linkTag(span) / linkTag(a) / link(a) / img / video
|
||||
*/
|
||||
function parseBlockToSegments(block, config) {
|
||||
const segs = []
|
||||
@@ -111,7 +112,7 @@ function parseBlockToSegments(block, config) {
|
||||
if (token) personTokenSet.add(token)
|
||||
}
|
||||
// 合并匹配所有内联元素
|
||||
const tokenRe = /<span[^>]*data-type="mention"[^>]*>[\s\S]*?<\/span>|<span[^>]*data-type="linkTag"[^>]*>[\s\S]*?<\/span>|<a[^>]*href="([^"]*)"[^>]*>(#[^<]*)<\/a>|<video[^>]*>[\s\S]*?<\/video>|<video[^>]*\/>|<img[^>]*\/?>/gi
|
||||
const tokenRe = /<span[^>]*data-type="mention"[^>]*>[\s\S]*?<\/span>|<span[^>]*data-type="linkTag"[^>]*>[\s\S]*?<\/span>|<a[^>]*href=(?:"[^"]*"|'[^']*')[^>]*>[\s\S]*?<\/a>|<video[^>]*>[\s\S]*?<\/video>|<video[^>]*\/>|<img[^>]*\/?>/gi
|
||||
let lastEnd = 0
|
||||
let m
|
||||
|
||||
@@ -162,12 +163,21 @@ function parseBlockToSegments(block, config) {
|
||||
segs.push({ type: 'linkTag', label: innerText || '#', url, tagType, pagePath, tagId, appId, mpKey, passPhone, phoneParamName })
|
||||
|
||||
} else if (/^<a /i.test(tag)) {
|
||||
// #linkTag — 旧格式 <a href>(insertLinkTag 旧版产生,url 可能为空)
|
||||
// m[1] = href, m[2] = innerText(以 # 开头)
|
||||
const url = m[1] || ''
|
||||
const label = cleanSingleLineField((m[2] || '').replace(/^#/, ''))
|
||||
// 旧格式没有 tagType,在 onLinkTagTap 中会按 label 匹配缓存的 linkTags 配置降级处理
|
||||
segs.push({ type: 'linkTag', label: label || '#', url, tagType: '', pagePath: '', tagId: '' })
|
||||
// <a href>:兼容旧 #linkTag 与普通超链接
|
||||
const hrefMatch =
|
||||
tag.match(/href\s*=\s*"([^"]*)"/i) ||
|
||||
tag.match(/href\s*=\s*'([^']*)'/i)
|
||||
const url = hrefMatch ? decodeEntities((hrefMatch[1] || '').trim()) : ''
|
||||
const anchorText = decodeEntities((tag.replace(/<[^>]+>/g, '') || '').trim())
|
||||
|
||||
// 旧格式:#标签仍走 linkTag 逻辑,复用现有 onLinkTagTap
|
||||
if (/^[##]/u.test(anchorText)) {
|
||||
const label = cleanSingleLineField(anchorText.replace(/^[##]/u, ''))
|
||||
segs.push({ type: 'linkTag', label: label || '#', url, tagType: '', pagePath: '', tagId: '' })
|
||||
} else {
|
||||
// 普通链接:展示锚文本;无锚文本则回退展示 url
|
||||
segs.push({ type: 'link', text: anchorText || url, url })
|
||||
}
|
||||
|
||||
} else if (/^<video/i.test(tag)) {
|
||||
const rawSrc = extractVideoSrcFromTag(tag)
|
||||
|
||||
Reference in New Issue
Block a user