/* * Copyright (c) Baidu, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import {DirectiveInfo} from './interface'; import Citation from '@cosui/cosmic-dqa/citation'; import type {CitationProps, Source as CitationSource} from '../citation/interface'; // 格式化返回source中tag的数据,tag中注入颜色和背景色的css变量 function getFormatTagSource(source?: CitationSource) { if (!source || !source.tag) { return { ...(source || {}), tag: {} }; } const tag = typeof source.tag === 'object' ? source.tag : {text: source.tag}; const vars: string[] = []; const tagColor = tag.color || '--cos-color-text-on-primary-light'; const tagBgColor = tag.bgColor || '--cos-color-bg-primary-light'; vars.push(`--cosd-citation-tag-color:${tagColor.startsWith('--') ? `var(${tagColor})` : tagColor}`); vars.push(`--cosd-citation-tag-bg-color:${tagBgColor.startsWith('--') ? `var(${tagBgColor})` : tagBgColor}`); return { ...source, tag: { text: tag.text || '', colorVars: vars.join(';') } }; } // 所有:ml-citation的指令都会走到这里,溯源角标和可信溯源都是:ml-citation指令 const mlCitation = { directive: 'ml-citation', ssr: function (node: DirectiveInfo) { const citationsData = node.properties?.data || []; let data = {} as CitationProps; let str = ''; // 这里的ref实际上就是每一个:ml-citation指令携带的ref参数 const refs = node.properties?.ref ? (node.properties?.ref as string).split(',') : [node.content]; const appearance = (node.properties?.appearance as string) || ''; if (appearance === 'link') { const allDefault = refs.every(ref => { if (ref && Array.isArray(citationsData)) { data = citationsData[+ref - 1] || {}; } else { data = (citationsData || {}) as CitationProps; } return data?.source?.type === 'default'; }); if (allDefault) { str = '搜索结果'; return `${str}`; } } // 聚合溯源特殊处理:多个ref只渲染一个聚合图标 if (appearance === 'aggregated') { // eslint-disable-next-line @babel/new-cap const citationHtml = Citation({ appearance: 'aggregated' }); str += citationHtml; return `${str}`; } refs.map(ref => { if (!ref) { return; } let curRef = +ref; if (ref && Array.isArray(citationsData)) { data = citationsData[+ref - 1] || {}; // 判断本项前面是否有隐藏项,如果有隐藏项,下标需要减去本项之前隐藏项的数量 curRef -= citationsData.slice(0, curRef - 1).reduce((acc, item) => (item.hidden ? acc + 1 : acc), 0); } else { data = (citationsData || {}) as CitationProps; } // 权威溯源 (link 类型的溯源),直接展示链接到文本中 if (appearance === 'link') { // 有文本且没中兜底,则渲染,否则不渲染 if (data?.source?.name && data?.source?.type !== 'default') { // eslint-disable-next-line @babel/new-cap const citationHtml = Citation({ appearance: 'link', ...data }); str += citationHtml; } return; } // 可信溯源,溯源类型在 data 中 if (appearance === 'tag' || data.appearance === 'tag') { // 有来源信息则渲染,否则不渲染 if (data?.source?.tag && !data.hidden) { // eslint-disable-next-line @babel/new-cap const citationHtml = Citation({ ...data, appearance: 'tag', citationId: curRef, source: getFormatTagSource(data.source) }); str += citationHtml; } return; } if (data.hidden) { // 隐藏该项,结束这一次循环,不对str进行拼接 return; } // eslint-disable-next-line max-len str += `${curRef}`; }); // link 模式下,需要被播报 return `${str}`; }, csr: function (node: DirectiveInfo) { const element = document.createElement('span'); // 兼容单个和多个数据 const refs = node.properties?.ref ? (node.properties?.ref as string).split(',') : [node.content]; const appearance = (node.properties?.appearance as string) || ''; const aggregatedIndexes = node.properties?.aggregatedIndexes ? (node.properties?.aggregatedIndexes as string).split(',') : []; if (appearance === 'link') { const citationsData = node.properties?.data || []; let data = {} as CitationProps; const allDefault = refs.every(ref => { if (ref && Array.isArray(citationsData)) { data = citationsData[+ref - 1] || {}; } else { data = (citationsData || {}) as CitationProps; } return data?.source?.type === 'default'; }); if (allDefault) { element.textContent = '搜索结果'; return element; } } else { element.setAttribute('disable-audio', 'true'); element.setAttribute('disable-copy', 'true'); element.setAttribute('disable-jump', 'true'); } // 聚合溯源特殊处理:多个ref只渲染一个聚合图标 if (appearance === 'aggregated') { if (refs.length > 0) { const el = document.createElement('span'); el.setAttribute('rl-type', 'stop'); const citationCompData = { appearance: 'aggregated' } as CitationProps; const citationComp = new Citation({ data: citationCompData }); citationComp.on('click', (params: any) => { // @ts-ignore - this 指向 Markdown 组件实例 this.fire('click', { directive: mlCitation.directive, ...params, data: { aggregatedIndexes: refs } }); }); citationComp.attach(el); // @ts-ignore this.setDirectiveComponents(mlCitation.directive, citationComp); element.appendChild(el); } return element; } refs.forEach(ref => { if (!ref) { return; } let curRef = +ref; const el = document.createElement('span'); const citationsData = node.properties?.data || []; let data = {} as CitationProps; // 打字机效果下,可能存在数据没返回的情况 if (!citationsData || typeof citationsData === 'string') { data = {} as CitationProps; // link 类型强依赖数据,没有数据则不展现 if (appearance === 'link') { return; } // eslint-disable-next-line max-len el.innerHTML = `${ref}`; // bca-disable-line element.appendChild(el); return; } else if (Array.isArray(citationsData)) { data = citationsData[curRef - 1] || {}; // 判断本项前面是否有隐藏项,如果有隐藏项,下标需要减去本项之前隐藏项的数量 curRef -= citationsData.slice(0, curRef - 1).reduce((acc, item) => (item.hidden ? acc + 1 : acc), 0); } else { data = (citationsData || {}) as CitationProps; } if ((appearance !== 'link' && data.hidden) || (appearance === 'link' && (!data?.source?.name || data?.source?.type === 'default')) || ((data.appearance || appearance) === 'tag' && !data.source?.tag) ) { return; } el.setAttribute('rl-type', 'stop'); data.citationId = String(curRef); const config = this.data.get('config')[mlCitation.directive]; if (config && typeof config.getPopupContainer === 'function') { data.getPopupContainer = config.getPopupContainer; } // 兼容老组件的数据,待业务修改后删除 // @ts-ignore data.isVideo = data.type === 'video'; let citationCompData = { ...data, appearance: data.appearance || appearance, source: getFormatTagSource(data.source) }; const citationComp = new Citation({ data: citationCompData }); citationComp.on('click', (params: any) => { this.fire('click', { directive: mlCitation.directive, ...params, data: { ...data, aggregatedIndexes } }); }); citationComp.on('toggle', (params: any) => { this.fire('toggle', { directive: mlCitation.directive, ...params, data }); }); citationComp.attach(el); // @ts-ignore this.setDirectiveComponents(mlCitation.directive, citationComp); element.appendChild(el); }); return element; } }; export default mlCitation;