Skip to content

Commit d2fdfae

Browse files
authored
Merge pull request #852 from n4ze3m/dev
v1.5.63
2 parents de4fb42 + 14e5ee8 commit d2fdfae

10 files changed

Lines changed: 77 additions & 55 deletions

File tree

bun.lockb

3.85 KB
Binary file not shown.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
"@mantine/form": "^7.5.0",
3232
"@mantine/hooks": "^7.5.3",
3333
"@modelcontextprotocol/sdk": "^1.27.1",
34-
"@mozilla/readability": "^0.5.0",
3534
"@plasmohq/storage": "^1.9.0",
3635
"@tailwindcss/forms": "^0.5.7",
3736
"@tailwindcss/typography": "^0.5.10",
@@ -44,6 +43,7 @@
4443
"cheerio": "^1.0.0-rc.12",
4544
"d3-dsv": "2",
4645
"dayjs": "^1.11.10",
46+
"defuddle": "^0.18.1",
4747
"dexie": "^4.0.11",
4848
"dexie-react-hooks": "^1.1.7",
4949
"html-to-text": "^9.0.5",

src/components/Common/Playground/Message.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,11 @@ const PlaygroundMessageComponent = (props: Props) => {
287287
return (
288288
<div
289289
className={`group relative flex w-full max-w-3xl flex-col items-end justify-center pb-2 text-gray-800 dark:text-gray-100 md:px-4 lg:w-4/5 ${checkWideMode ? "max-w-none" : ""}`}
290-
style={messageRenderStyle}>
290+
style={
291+
props.isLastMessage || props.isStreaming || props.isProcessing
292+
? undefined
293+
: messageRenderStyle
294+
}>
291295
<div className="m-auto my-2 flex w-full flex-row gap-4 md:gap-6">
292296
<div className="relative flex w-8 flex-col items-end">
293297
{props.isBot ? (

src/components/Common/Playground/PlaygroundUserMessage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ export const PlaygroundUserMessageBubble: React.FC<Props> = (props) => {
6060
return (
6161
<div
6262
className={`group gap-2 relative flex w-full max-w-3xl flex-col items-end justify-center pb-2 md:px-4 lg:w-4/5 text-[#242424] dark:text-gray-100 ${checkWideMode ? "max-w-none" : ""}`}
63-
style={messageRenderStyle}>
63+
style={
64+
props.isLastMessage || props.isStreaming || props.isProcessing
65+
? undefined
66+
: messageRenderStyle
67+
}>
6468
{!editMode && props?.message_type ? (
6569
<Tag color={props?.message_type?.startsWith("custom_copilot_custom_") ? "orange" : tagColors[props?.message_type] || "default"}>
6670
{props?.message_type?.startsWith("custom_copilot_custom_")

src/components/Common/TableBlock.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export const TableBlock: FC<TableProps> = ({ children }) => {
166166
<div className="overflow-x-auto">
167167
<div
168168
ref={ref}
169-
className={`prose prose-gray dark:prose-invert max-w-none [&_table]:table-fixed [&_table]:w-full [&_table]:border-collapse [&_thead]:bg-neutral-50 [&_thead]:dark:bg-[#2a2a2a] [&_th]:px-6 [&_th]:py-4 [&_th]:text-left [&_th]:font-semibold [&_th]:text-gray-900 [&_th]:dark:text-gray-100 [&_th]:uppercase [&_th]:tracking-wider ${tableTextWrap ? '[&_th]:break-words [&_th]:overflow-wrap-anywhere' : '[&_th]:whitespace-nowrap'} [&_th:nth-child(1)]:w-1/2 [&_th:nth-child(2)]:w-1/2 [&_th:nth-child(3)]:w-1/3 [&_th]:border-b [&_th]:border-gray-200 [&_th]:dark:border-gray-700 [&_td]:px-6 [&_td]:py-4 [&_td]:text-gray-700 [&_td]:dark:text-gray-300 [&_td]:text-left ${tableTextWrap ? '[&_td]:break-words [&_td]:overflow-wrap-anywhere' : '[&_td]:whitespace-nowrap'} [&_td]:border-b [&_td]:border-gray-200 [&_td]:dark:border-gray-700 [&_tr:last-child_td]:border-b-0`}
169+
className={`prose prose-gray dark:prose-invert max-w-none [&_table]:w-full [&_table]:border-collapse [&_thead]:bg-neutral-50 [&_thead]:dark:bg-[#2a2a2a] [&_th]:px-6 [&_th]:py-4 [&_th]:text-left [&_th]:font-semibold [&_th]:text-gray-900 [&_th]:dark:text-gray-100 [&_th]:uppercase [&_th]:tracking-wider ${tableTextWrap ? '[&_th]:break-words [&_th]:overflow-wrap-anywhere' : '[&_th]:whitespace-nowrap'} [&_th]:border-b [&_th]:border-gray-200 [&_th]:dark:border-gray-700 [&_td]:px-6 [&_td]:py-4 [&_td]:text-gray-700 [&_td]:dark:text-gray-300 [&_td]:text-left ${tableTextWrap ? '[&_td]:break-words [&_td]:overflow-wrap-anywhere' : '[&_td]:whitespace-nowrap'} [&_td]:border-b [&_td]:border-gray-200 [&_td]:dark:border-gray-700 [&_tr:last-child_td]:border-b-0`}
170170
style={{
171171
fontSize: `calc(0.875rem * var(--font-scale, 1))`
172172
}}>

src/entries/background.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,43 @@ export default defineBackground({
330330
}
331331
})
332332

333+
const sidePanelClose = (chrome.sidePanel as any)?.close as
334+
| ((options: { tabId?: number; windowId?: number }) => Promise<void>)
335+
| undefined
336+
333337
browser.commands.onCommand.addListener((command) => {
334338
switch (command) {
335339
case "execute_side_panel":
336340
chrome.tabs.query(
337341
{ active: true, currentWindow: true },
338342
async (tabs) => {
339343
const tab = tabs[0]
344+
if (!tab?.id) return
345+
346+
if (isCopilotRunning && sidePanelClose) {
347+
const closeAttempts: Array<{
348+
tabId?: number
349+
windowId?: number
350+
}> = []
351+
if (tab.windowId !== undefined) {
352+
closeAttempts.push({ windowId: tab.windowId })
353+
}
354+
closeAttempts.push({ tabId: tab.id })
355+
356+
for (const attempt of closeAttempts) {
357+
try {
358+
await sidePanelClose(attempt)
359+
return
360+
} catch (e) {
361+
}
362+
}
363+
console.warn(
364+
"Side panel reported open but close() rejected for both windowId and tabId"
365+
)
366+
}
367+
340368
chrome.sidePanel.open({
341-
tabId: tab.id!
369+
tabId: tab.id
342370
})
343371
}
344372
)

src/libs/get-html.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ export const getDataFromCurrentTab = async () => {
431431
}
432432
}
433433
}
434-
const data = defaultExtractContent(content)
434+
const data = defaultExtractContent(content, url)
435435
return { url, content: data, type, pdf: [], html: content }
436436
}
437437

src/parser/default.ts

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,39 @@
1-
import * as cheerio from "cheerio"
2-
import TurndownService from "turndown"
3-
import { Readability, isProbablyReaderable } from "@mozilla/readability"
1+
import Defuddle, { createMarkdownContent } from "defuddle/full"
42

5-
export const defaultExtractContent = (html: string) => {
6-
const doc = new DOMParser().parseFromString(html, "text/html")
7-
if (isProbablyReaderable(doc)) {
8-
const reader = new Readability(doc)
9-
const article = reader.parse()
10-
if (article && article.content) {
11-
const $article = cheerio.load(article.content)
12-
$article("script, style, link, svg, [src^='data:image/']").remove()
13-
article.content = $article.html() || ""
14-
}
15-
const turndownService = new TurndownService({
16-
headingStyle: "atx",
17-
codeBlockStyle: "fenced"
18-
})
19-
return turndownService.turndown(article?.content || "").trim()
20-
}
3+
export const defaultExtractContent = (html: string, url: string = "") => {
4+
if (!html) return ""
215

22-
const $ = cheerio.load(html)
6+
try {
7+
const doc = new DOMParser().parseFromString(html, "text/html")
238

24-
$("script, style, link, svg, [src^='data:image/']").remove()
9+
const result = new Defuddle(doc as unknown as Document, { url }).parse()
2510

26-
$("*").each((_, element) => {
27-
if ("attribs" in element) {
28-
const attributes = element.attribs
29-
for (const attr in attributes) {
30-
if (attr !== "href" && attr !== "src") {
31-
$(element).removeAttr(attr)
32-
}
33-
}
11+
if (result?.content && result.content.trim().length > 0) {
12+
return createMarkdownContent(result.content, url).trim()
3413
}
35-
})
36-
37-
const mainContent =
38-
$('[role="main"]').html() || $("main").html() || $("body").html() || ""
39-
40-
const turndownService = new TurndownService({
41-
headingStyle: "atx",
42-
codeBlockStyle: "fenced"
43-
})
44-
const markdown = turndownService.turndown(mainContent)
14+
} catch (error) {
15+
console.warn(
16+
"[defaultExtractContent] defuddle extraction failed, falling back:",
17+
error
18+
)
19+
}
4520

46-
return markdown.trim()
21+
try {
22+
const doc = new DOMParser().parseFromString(html, "text/html")
23+
doc
24+
.querySelectorAll("script, style, link, noscript, svg, [aria-hidden=\"true\"]")
25+
.forEach((el) => el.remove())
26+
const body =
27+
doc.querySelector("[role=\"main\"]") ||
28+
doc.querySelector("main") ||
29+
doc.querySelector("article") ||
30+
doc.body
31+
return createMarkdownContent(body?.innerHTML || html, url).trim()
32+
} catch (error) {
33+
console.warn(
34+
"[defaultExtractContent] fallback markdown conversion failed:",
35+
error
36+
)
37+
return ""
38+
}
4739
}

src/parser/reader.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Readability } from "@mozilla/readability"
21
import { defaultExtractContent } from "./default"
2+
33
export const extractReadabilityContent = async (url: string) => {
44
const response = await fetch(url, {
55
headers: {
@@ -23,11 +23,5 @@ export const extractReadabilityContent = async (url: string) => {
2323
}
2424

2525
const html = await response.text()
26-
27-
const doc = new DOMParser().parseFromString(html, "text/html")
28-
const reader = new Readability(doc)
29-
const article = reader.parse()
30-
31-
const markdown = defaultExtractContent(article.content)
32-
return markdown
26+
return defaultExtractContent(html, url)
3327
}

wxt.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export default defineConfig({
5151
outDir: "build",
5252

5353
manifest: {
54-
version: "1.5.62",
54+
version: "1.5.63",
5555
name:
5656
process.env.TARGET === "firefox"
5757
? "Page Assist - A Web UI for Local AI Models"

0 commit comments

Comments
 (0)