diff --git a/README.md b/README.md
index 14c81beb..df20f48e 100644
--- a/README.md
+++ b/README.md
@@ -117,6 +117,9 @@ yarn run start # 本地启动NextJS服务
 ifyz 🔧 🐛 |
+  SwwweetOrange 🔧 🐛 |
+
+
diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js
index 771915e9..1eced850 100644
--- a/lib/notion/getPageProperties.js
+++ b/lib/notion/getPageProperties.js
@@ -79,8 +79,8 @@ export default async function getPageProperties(id, block, schema, authToken, ta
properties.createdTime = formatDate(new Date(value.created_time).toString(), BLOG.LANG)
properties.lastEditedTime = formatDate(new Date(value?.last_edited_time).toString(), BLOG.LANG)
properties.fullWidth = value.format?.page_full_width ?? false
- properties.pageIcon = getPageIcon(id, block) ?? ''
- properties.page_cover = getPostCover(id, block) ?? siteInfo?.pageCover
+ properties.pageIcon = getImageUrl(block[id].value?.format?.page_icon, block[id].value) ?? ''
+ properties.page_cover = getImageUrl(block[id].value?.format?.page_cover, block[id].value) ?? siteInfo?.pageCover
properties.content = value.content ?? []
properties.tagItems = properties?.tags?.map(tag => {
return { name: tag, color: tagOptions?.find(t => t.value === tag)?.color || 'gray' }
@@ -89,20 +89,23 @@ export default async function getPageProperties(id, block, schema, authToken, ta
return properties
// 从Block获取封面图;优先取PageCover,否则取内容图片
- function getPostCover(id, block) {
- const pageCover = block[id].value?.format?.page_cover
- if (pageCover) {
- if (pageCover.startsWith('/')) return 'https://www.notion.so' + pageCover
- if (pageCover.startsWith('http')) return defaultMapImageUrl(pageCover, block[id].value)
+ function getImageUrl(imgObj, blockVal) {
+ if (!imgObj) {
+ return null
+ }
+ if (imgObj.startsWith('/')) {
+ return 'https://www.notion.so' + imgObj // notion内部图片转相对路径为绝对路径
}
- }
-}
-function getPageIcon(id, block) {
- const pageIcon = block[id].value?.format?.page_icon
- if (pageIcon) {
- if (pageIcon.startsWith('/')) return 'https://www.notion.so' + pageIcon
- if (pageIcon.startsWith('http')) return defaultMapImageUrl(pageIcon, block[id].value)
- return pageIcon
+ if (imgObj.startsWith('http')) {
+ // 判断如果是notion上传的图片要拼接访问token
+ const u = new URL(imgObj)
+ if (u.pathname.startsWith('/secure.notion-static.com') && u.hostname.endsWith('.amazonaws.com')) {
+ return defaultMapImageUrl(imgObj, blockVal) // notion上传的图片需要转换请求地址
+ }
+ }
+
+ // 其他图片链接 或 emoji
+ return imgObj
}
}
diff --git a/package.json b/package.json
index d111033e..2f5be0dc 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"gitalk": "^1.7.2",
"localStorage": "^1.0.4",
"lodash.throttle": "^4.1.1",
+ "mark.js": "^8.11.1",
"memory-cache": "^0.2.0",
"mermaid": "9.2.2",
"mongodb": "^4.6.0",
diff --git a/themes/example/LayoutSearch.js b/themes/example/LayoutSearch.js
index 984e47e7..23b10b7a 100644
--- a/themes/example/LayoutSearch.js
+++ b/themes/example/LayoutSearch.js
@@ -4,6 +4,7 @@ import { BlogListScroll } from './components/BlogListScroll'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import SearchInput from './components/SearchInput'
+import Mark from 'mark.js'
import LayoutBase from './LayoutBase'
import { isBrowser } from '@/lib/utils'
@@ -15,8 +16,12 @@ export const LayoutSearch = props => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
- const re = new RegExp(`${keyword}`, 'gim')
- container.innerHTML = container.innerHTML.replace(re, `${keyword}`)
+ const re = new RegExp(keyword, 'gim')
+ const instance = new Mark(container)
+ instance.markRegExp(re, {
+ element: 'span',
+ className: 'text-red-500 border-b border-dashed'
+ })
}
}, 100)
}, [router.events])
diff --git a/themes/fukasawa/LayoutSearch.js b/themes/fukasawa/LayoutSearch.js
index 9329846d..fcfa35b2 100644
--- a/themes/fukasawa/LayoutSearch.js
+++ b/themes/fukasawa/LayoutSearch.js
@@ -4,6 +4,7 @@ import BlogListPage from './components/BlogListPage'
import BlogListScroll from './components/BlogListScroll'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
+import Mark from 'mark.js'
import { isBrowser } from '@/lib/utils'
export const LayoutSearch = (props) => {
@@ -14,8 +15,12 @@ export const LayoutSearch = (props) => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
- const re = new RegExp(`${currentSearch}`, 'gim')
- container.innerHTML = container.innerHTML.replace(re, `${currentSearch}`)
+ const re = new RegExp(currentSearch, 'gim')
+ const instance = new Mark(container)
+ instance.markRegExp(re, {
+ element: 'span',
+ className: 'text-red-500 border-b border-dashed'
+ })
}
}, 100)
})
diff --git a/themes/hexo/LayoutSearch.js b/themes/hexo/LayoutSearch.js
index 6454ef3a..679975cb 100644
--- a/themes/hexo/LayoutSearch.js
+++ b/themes/hexo/LayoutSearch.js
@@ -6,6 +6,7 @@ import BlogPostListPage from './components/BlogPostListPage'
import LayoutBase from './LayoutBase'
import SearchInput from './components/SearchInput'
import { useGlobal } from '@/lib/global'
+import Mark from 'mark.js'
import TagItemMini from './components/TagItemMini'
import Card from './components/Card'
import Link from 'next/link'
@@ -25,10 +26,12 @@ export const LayoutSearch = props => {
const targets = document.getElementsByClassName('replace')
for (const container of targets) {
if (container && container.innerHTML) {
- const re = new RegExp(`${currentSearch}`, 'gim')
- container.innerHTML = container.innerHTML.replace(
- re, `${currentSearch}`
- )
+ const re = new RegExp(currentSearch, 'gim')
+ const instance = new Mark(container)
+ instance.markRegExp(re, {
+ element: 'span',
+ className: 'text-red-500 border-b border-dashed'
+ })
}
}
}
diff --git a/themes/medium/LayoutSearch.js b/themes/medium/LayoutSearch.js
index 9a34bcec..76a9ddae 100644
--- a/themes/medium/LayoutSearch.js
+++ b/themes/medium/LayoutSearch.js
@@ -6,6 +6,7 @@ import CategoryGroup from './components/CategoryGroup'
import { useEffect } from 'react'
import { isBrowser } from '@/lib/utils'
import BLOG from '@/blog.config'
+import Mark from 'mark.js'
import BlogPostListScroll from './components/BlogPostListScroll'
import BlogPostListPage from './components/BlogPostListPage'
@@ -16,8 +17,12 @@ export const LayoutSearch = (props) => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
- const re = new RegExp(`${keyword}`, 'gim')
- container.innerHTML = container.innerHTML.replace(re, `${keyword}`)
+ const re = new RegExp(keyword, 'gim')
+ const instance = new Mark(container)
+ instance.markRegExp(re, {
+ element: 'span',
+ className: 'text-red-500 border-b border-dashed'
+ })
}
},
100)
diff --git a/themes/next/LayoutSearch.js b/themes/next/LayoutSearch.js
index d4ec1bb8..78664343 100644
--- a/themes/next/LayoutSearch.js
+++ b/themes/next/LayoutSearch.js
@@ -4,6 +4,7 @@ import { useGlobal } from '@/lib/global'
import { isBrowser } from '@/lib/utils'
import BlogPostListScroll from './components/BlogPostListScroll'
import BlogPostListPage from './components/BlogPostListPage'
+import Mark from 'mark.js'
import BLOG from '@/blog.config'
export const LayoutSearch = (props) => {
@@ -12,8 +13,12 @@ export const LayoutSearch = (props) => {
setTimeout(() => {
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
- const re = new RegExp(`${keyword}`, 'gim')
- container.innerHTML = container.innerHTML.replace(re, `${keyword}`)
+ const re = new RegExp(keyword, 'gim')
+ const instance = new Mark(container)
+ instance.markRegExp(re, {
+ element: 'span',
+ className: 'text-red-500 border-b border-dashed'
+ })
}
}, 200)
return (