/* eslint-disable no-underscore-dangle */ /* eslint-disable yoda */ import { defineComponentMetadata } from '@/components/define' import { CommentItem, CommentReplyItem } from '@/components/utils/comment-apis' import { select } from '@/core/spin-query' // 新版评论区IP属地获取 const getIpLocation = (item: CommentReplyItem) => { const reply = item.frameworkSpecificProps return reply?.reply_control?.location ?? undefined } let version = 2 let bbComment: any const marginLeft = 15 // 带IP属地显示的评论创建 const createListCon = function listCon(item, i, pos) { const blCon = this._parentBlacklistDom(item, i, pos) const con = [ `
`, `
${this._createNickNameDom(item)}`, this._createLevelLink(item), this._identity(item.mid, item.assist, item.member.fans_detail), `${this._createNameplate(item.member.nameplate) + this._createUserSailing(item)}
`, this._createMsgContent(item), this._createPerfectReply(item), '
', this._createPlatformDom(item.content.plat), '', ''.concat(this._formateTime(item.ctime), ''), item?.reply_control?.location ? `${ item?.reply_control?.location || '' }` : '', '', item.lottery_id ? '' : ``, item.lottery_id ? '' : ``, item.lottery_id ? '' : this._createReplyBtn(item.rcount), item.lottery_id && item.mid !== bbComment.userStatus.mid ? '' : `
    ${ this._canSetTop(item) ? `
  • ${item.isUpTop ? '取消置顶' : '设为置顶'}
  • ` : '' }${this._canBlackList(item.mid) ? '
  • 加入黑名单
  • ' : ''}${ this._canReport(item.mid) ? '
  • 举报
  • ' : '' }${ this._canDel(item.mid) && !item.isTop ? `
  • 删除
  • ` : '' }
`, this._createLotteryContent(item.content), this._createVoteContent(item.content), this._createTags(item), '
', '
', this._createSubReplyList( item.replies, item.rcount, false, item.rpid, item.folder && item.folder.has_folded, item.reply_control, ), '
', '
', '
', '
', ].join('') return item.state === bbComment.blacklistCode ? blCon : con } // 带IP属地显示的回复创建 const createSubReplyItem = function subReply(item, i) { const dom = [ `
`, this._createSubReplyUserFace(item), '
', '
', this._createNickNameDom(item), this._createLevelLink(item), this._identity(item.mid), this._createSubMsgContent(item), '
', '
', '
', '', ''.concat(this._formateTime(item.ctime), ''), item?.reply_control?.location ? `${ item?.reply_control?.location || '' }` : '', '', ``, ``, '回复', `
    ${ this._canBlackList(item.mid) ? '
  • 加入黑名单
  • ' : '' }${this._canReport(item.mid) ? '
  • 举报
  • ' : ''}${ this._canDel(item.mid) ? `
  • 删除
  • ` : '' }
`, '
', '
', ].join('') return dom } // 小黑屋专用带IP属地显示的评论创建 const blackroomCreateListCon = function listCon(e, n, t) { const r = this._parentBlacklistDom(e, n, t) const i = [ `
`, `
${this._identity(e.mid, e.assist, e.member.fans_detail)}`, `${this._unhtmlFix( e.member.uname, )}${this._createNameplate(e.member.nameplate)}${this._createUserSailing( (e.member && e.member.user_sailing) || {}, )}
`, this._createMsgContent(e), '
', e.floor ? `#${e.floor}` : '', this._createPlatformDom(e.content.plat), `${this._formateTime(e.ctime)}`, e?.reply_control?.location ? `${e?.reply_control?.location || ''}` : '', e.lottery_id ? '' : ``, e.lottery_id ? '' : ``, e.lottery_id ? '' : this._createReplyBtn(e.rcount), e.lottery_id && e.mid !== this.userStatus.mid ? '' : `
    ${ this._canSetTop(e) ? `
  • ${e.isUpTop ? '取消置顶' : '设为置顶'}
  • ` : '' }${this._canBlackList(e.mid) ? '
  • 加入黑名单
  • ' : ''}${ this._canReport(e.mid) ? '
  • 举报
  • ' : '' }${ this._canDel(e.mid) && !e.isTop ? `
  • 删除
  • ` : '' }
`, this._createLotteryContent(e.content), this._createVoteContent(e.content), this._createTags(e), '
', '
', this._createSubReplyList(e.replies, e.rcount, !1, e.rpid, e.folder && e.folder.has_folded), '
', '
', '
', '
', ].join('') return e.state === this.blacklistCode ? r : i } // 小黑屋专用带IP属地显示的回复创建 const blackroomCreateSubReplyItem = function subReply(e, n) { const t = [ `
`, ``, ``, '', '
', '
', `${this._unhtmlFix(e.member.uname)}`, ``, this._createSubMsgContent(e), '
', '
', '
', `${this._formateTime(e.ctime)}`, e?.reply_control?.location ? `${e?.reply_control?.location || ''}` : '', ``, ``, '回复', `
    ${ this._canBlackList(e.mid) ? '
  • 加入黑名单
  • ' : '' }${this._canReport(e.mid) ? '
  • 举报
  • ' : ''}${ this._canDel(e.mid) ? `
  • 删除
  • ` : '' }
`, '
', '
', ].join('') return t } const observer = new MutationObserver(mutations => { mutations.forEach(() => { // 监听旧版评论区全局变量 if (typeof unsafeWindow.bbComment !== 'undefined') { // 评论创建函数替换 bbComment = unsafeWindow.bbComment if (unsafeWindow.location.href.split('/')[3] === 'blackroom') { // 小黑屋特判 // 三个谜之函数的polyfill(不知为何无法直接调用,会报错) bbComment.prototype._unhtmlFix = function unhtml(e, n) { return e ? // eslint-disable-next-line @typescript-eslint/no-shadow e.replace(n || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp|#\\d+);)?/g, function (e, n) { return n ? e : { '<': '', '&': '', '"': '', '>': '', "'": '' }[e] }) : '' } bbComment.prototype._trimHttpFix = function trimHttp(e) { return e ? e.replace(/^http:/, '') : '' } bbComment.prototype._webpFix = function webp(e, n) { if (!e) { return e } const t = e.match(/(.*\\.(jpg|jpeg|gif|png|bmp))(\\?.*)?/) let r = -1 !== e.indexOf('/bfs/') if (!t || 'gif' === t[2] || 'bmp' === t[2] || !r) { return e } r = n.w e = n.h e = r && e ? `@${r}w_${e}h` : '@' n = t[3] || '' return this.isWebp ? `${t[1] + e}.webp${n}` : `${t[1] + e}.${t[2]}${n}` } bbComment.prototype._createListCon = blackroomCreateListCon bbComment.prototype._createSubReplyItem = blackroomCreateSubReplyItem } else { // 其他情况旧版评论区替换 bbComment.prototype._createListCon = createListCon bbComment.prototype._createSubReplyItem = createSubReplyItem } version = 1 observer.disconnect() } }) }) observer.observe(document.head, { childList: true }) const processItems = (items: CommentReplyItem[]) => { items.forEach(async item => { const location = getIpLocation(item) if (location === undefined) { return } const replyTime = await (() => { if (item.shadowDomEntry) { return select(() => item.shadowDomEntry.querySelector('#pubdate'), { queryInterval: 100, maxRetry: 30, }) } return ( item.element.querySelector('.reply-info>.reply-time') ?? item.element.querySelector('.sub-reply-info>.sub-reply-time') ) })() if (replyTime === null) { return } const existingLocation = replyTime.querySelector('.ip-location') as HTMLElement | null if (existingLocation !== null) { existingLocation.innerText = location return } const replyLocation = document.createElement('span') replyLocation.className = 'ip-location' replyLocation.style.marginLeft = `${marginLeft}px` replyLocation.innerText = location replyTime.appendChild(replyLocation) }) } const entry = async () => { const { forEachCommentItem } = await import('@/components/utils/comment-apis') const addIpLocation = (comment: CommentItem) => { if (version === 2) { processItems([comment, ...comment.replies]) comment.addEventListener('repliesUpdate', replies => processItems(replies.detail)) } } forEachCommentItem({ added: addIpLocation, }) } export const component = defineComponentMetadata({ name: 'ipShow', author: { name: 'Light_Quanta', link: 'https://github.com/LightQuanta', }, displayName: '评论区IP属地显示', tags: [componentsTags.utils], entry, description: { 'zh-CN': '在评论区显示评论的IP属地信息', }, })