refactor: use context style

This commit is contained in:
Acid Chicken (硫酸鶏) 2024-05-30 18:21:47 +09:00
parent c953d238a6
commit 475ba6baba
No known key found for this signature in database
GPG Key ID: 3E87B98A3F6BAB99
22 changed files with 220 additions and 188 deletions

5
src/context.ts Normal file
View File

@ -0,0 +1,5 @@
export default interface Context {
html: HTMLRewriter
request: Request
url: URL
}

View File

@ -2,6 +2,7 @@ import { Hono } from "hono"
import { requestInit } from "./config"
import { normalize } from "./encoding"
import summary from "./summary"
import type Context from "./context"
export interface Env {
// Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
// MY_KV_NAMESPACE: KVNamespace;
@ -33,7 +34,11 @@ app.get("/url", async (context) => {
const response = (await fetch(url, requestInit(context.req.raw))) as any as Response
url = new URL(response.url)
const rewriter = new HTMLRewriter()
const summarized = summary(context.req.raw, url, rewriter)
const summarized = summary({
html: rewriter,
request: context.req.raw,
url,
})
const reader = (rewriter.transform(await normalize(response)).body as ReadableStream<Uint8Array>).getReader()
while (!(await reader.read()).done);
return context.json(await summarized)

View File

@ -2,20 +2,22 @@ import { decode } from "html-entities"
import clip from "summaly/built/utils/clip"
import { BufferedTextHandler, assign } from "../common"
import type { PrioritizedReference } from "../common"
import type Context from "../../context"
export default function getDescription(url: URL, html: HTMLRewriter) {
export default function getDescription(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 3, // 0-7
priority: 0,
content: null,
}
html.on(
context.html.on(
"#productDescription",
new BufferedTextHandler((text) => {
assign(result, 7, decode(text))
}),
)
html.on('meta[property="og:description"]', {
context.html.on('meta[property="og:description"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -23,7 +25,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:description"]', {
context.html.on('meta[name="twitter:description"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -31,7 +33,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="description"]', {
context.html.on('meta[name="description"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -39,11 +41,10 @@ export default function getDescription(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content && clip(result.content, 300))
},
})
context.html.onDocument({
end() {
resolve(result.content && clip(result.content, 300))
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign, toAbsoluteURL } from "../common"
import type { PrioritizedReference } from "../common"
import type Context from "../../context"
export default function getImage(url: URL, html: HTMLRewriter) {
export default function getImage(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 4, // 0-15
priority: 0,
content: null,
}
html.on("#landingImage", {
context.html.on("#landingImage", {
element(element) {
const content = element.getAttribute("src")
if (content) {
@ -16,7 +18,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[property="og:image"]', {
context.html.on('meta[property="og:image"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,7 +26,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:image"]', {
context.html.on('meta[name="twitter:image"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -32,7 +34,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="image_src"]', {
context.html.on('link[rel="image_src"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -40,7 +42,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="apple-touch-icon"]', {
context.html.on('link[rel="apple-touch-icon"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -48,7 +50,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="apple-touch-icon image_src"]', {
context.html.on('link[rel="apple-touch-icon image_src"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -56,11 +58,10 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, url.href) : null)
},
})
context.html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null)
},
})
return promise
}

View File

@ -10,12 +10,13 @@ import getPlayerUrlWidth from "../general/playerUrlWidth"
import getSiteName from "../general/siteName"
import getTitle from "./title"
import getSensitive from "../general/sensitive"
import type Context from "../../context"
export default function amazon(url: URL, html: HTMLRewriter) {
const card = getCard(url, html)
const title = getTitle(url, html)
const thumbnail = getImage(url, html)
const player = Promise.all([card, getPlayerUrlGeneral(url, html), getPlayerUrlCommon(url, html), getPlayerUrlWidth(url, html), getPlayerUrlHeight(url, html)]).then(([card, general, common, width, height]) => {
export default function amazon(context: Context) {
const card = getCard(context)
const title = getTitle(context)
const thumbnail = getImage(context)
const player = Promise.all([card, getPlayerUrlGeneral(context), getPlayerUrlCommon(context), getPlayerUrlWidth(context), getPlayerUrlHeight(context)]).then(([card, general, common, width, height]) => {
const url = (card !== "summary_large_image" && general) || common
if (url !== null && width !== null && height !== null) {
return {
@ -31,10 +32,10 @@ export default function amazon(url: URL, html: HTMLRewriter) {
}
}
})
const description = getDescription(url, html)
const siteName = getSiteName(url, html)
const favicon = getFavicon(url, html)
const sensitive = getSensitive(url, html)
const description = getDescription(context)
const siteName = getSiteName(context)
const favicon = getFavicon(context)
const sensitive = getSensitive(context)
return Promise.all([title, thumbnail, player, description, siteName, favicon, sensitive]).then(([title, thumbnail, player, description, siteName, favicon, sensitive]) => {
if (title === null) {
@ -51,7 +52,7 @@ export default function amazon(url: URL, html: HTMLRewriter) {
sitename: siteName,
icon: favicon,
sensitive,
url: url.href,
url: context.url.href,
}
})
}

View File

@ -2,20 +2,22 @@ import { decode } from "html-entities"
import clip from "summaly/built/utils/clip"
import { BufferedTextHandler, assign } from "../common"
import type { PrioritizedReference } from "../common"
import type Context from "../../context"
export default function getTitle(url: URL, html: HTMLRewriter) {
export default function getTitle(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 3, // 0-7
priority: 0,
content: null,
}
html.on(
context.html.on(
"#title",
new BufferedTextHandler((text) => {
assign(result, 7, decode(text))
}),
)
html.on('meta[property="og:title"]', {
context.html.on('meta[property="og:title"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -23,7 +25,7 @@ export default function getTitle(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:title"]', {
context.html.on('meta[name="twitter:title"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -31,17 +33,16 @@ export default function getTitle(url: URL, html: HTMLRewriter) {
}
},
})
html.on(
context.html.on(
"title",
new BufferedTextHandler((text) => {
assign(result, 1, decode(text))
}),
)
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content && clip(result.content, 100))
},
})
context.html.onDocument({
end() {
resolve(result.content && clip(result.content, 100))
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getCard(url: URL, html: HTMLRewriter) {
export default function getCard(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[name="twitter:card"]', {
context.html.on('meta[name="twitter:card"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getCard(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[property="twitter:card"]', {
context.html.on('meta[property="twitter:card"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,11 +26,10 @@ export default function getCard(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content)
},
})
context.html.onDocument({
end() {
resolve(result.content)
},
})
return promise
}

View File

@ -1,15 +1,17 @@
import { decode } from "html-entities"
import clip from "summaly/built/utils/clip"
import { assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
import { decode } from "html-entities"
export default function getDescription(url: URL, html: HTMLRewriter) {
export default function getDescription(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[property="og:description"]', {
context.html.on('meta[property="og:description"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -17,7 +19,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:description"]', {
context.html.on('meta[name="twitter:description"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -25,7 +27,7 @@ export default function getDescription(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="description"]', {
context.html.on('meta[name="description"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -33,11 +35,10 @@ export default function getDescription(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content && clip(result.content, 300))
},
})
context.html.onDocument({
end() {
resolve(result.content && clip(result.content, 300))
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign, toAbsoluteURL } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getFavicon(url: URL, html: HTMLRewriter) {
export default function getFavicon(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string>()
const result: PrioritizedReference<string> = {
bits: 2, // 0-3
priority: 0,
content: "/favicon.ico",
}
html.on('link[rel="shortcut icon"]', {
context.html.on('link[rel="shortcut icon"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -16,7 +18,7 @@ export default function getFavicon(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="icon"]', {
context.html.on('link[rel="icon"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -24,11 +26,10 @@ export default function getFavicon(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string>((resolve) => {
html.onDocument({
end() {
resolve(toAbsoluteURL(result.content, url.href))
},
})
context.html.onDocument({
end() {
resolve(toAbsoluteURL(result.content, context.url.href))
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign, toAbsoluteURL } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getImage(url: URL, html: HTMLRewriter) {
export default function getImage(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 3, // 0-7
priority: 0,
content: null,
}
html.on('meta[property="og:image"]', {
context.html.on('meta[property="og:image"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:image"]', {
context.html.on('meta[name="twitter:image"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,7 +26,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="image_src"]', {
context.html.on('link[rel="image_src"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -32,7 +34,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="apple-touch-icon"]', {
context.html.on('link[rel="apple-touch-icon"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -40,7 +42,7 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
html.on('link[rel="apple-touch-icon image_src"]', {
context.html.on('link[rel="apple-touch-icon image_src"]', {
element(element) {
const content = element.getAttribute("href")
if (content) {
@ -48,11 +50,10 @@ export default function getImage(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, url.href) : null)
},
})
context.html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null)
},
})
return promise
}

View File

@ -7,12 +7,13 @@ import getSiteName from "./siteName"
import getTitle from "./title"
import getSensitive from "./sensitive"
import getPlayer, { Player } from "./player"
import type Context from "../../context"
export default function general(request: Request, url: URL, html: HTMLRewriter) {
const card = getCard(url, html)
const title = getTitle(url, html)
const image = getImage(url, html)
const player = Promise.all([card, getPlayer(request, url, html)]).then<Player>(([card, parsedPlayer]) => {
export default function general(context: Context) {
const card = getCard(context)
const title = getTitle(context)
const image = getImage(context)
const player = Promise.all([card, getPlayer(context)]).then<Player>(([card, parsedPlayer]) => {
return {
url: (card !== "summary_large_image" && parsedPlayer.urlGeneral) || parsedPlayer.urlCommon,
width: parsedPlayer.width,
@ -20,10 +21,10 @@ export default function general(request: Request, url: URL, html: HTMLRewriter)
allow: parsedPlayer.allow,
}
})
const description = getDescription(url, html)
const siteName = getSiteName(url, html)
const favicon = getFavicon(url, html)
const sensitive = getSensitive(url, html)
const description = getDescription(context)
const siteName = getSiteName(context)
const favicon = getFavicon(context)
const sensitive = getSensitive(context)
return Promise.all([card, title, image, player, description, siteName, favicon, sensitive]).then(([card, title, image, player, description, siteName, favicon, sensitive]) => {
if (title === null) {
@ -41,7 +42,7 @@ export default function general(request: Request, url: URL, html: HTMLRewriter)
icon: favicon,
sensitive,
large: card === "summary_large_image",
url: url.href,
url: context.url.href,
}
})
}

View File

@ -3,6 +3,7 @@ import getPlayerUrlCommon from "./playerUrlCommon"
import getPlayerUrlGeneral from "./playerUrlGeneral"
import getPlayerUrlHeight from "./playerUrlHeight"
import getPlayerUrlWidth from "./playerUrlWidth"
import type Context from "../../context"
export interface Player {
url: string | null
@ -16,12 +17,12 @@ export interface ParsedPlayer extends Omit<Player, "url"> {
urlGeneral: string | null
}
export default function getPlayer(request: Request, url: URL, html: HTMLRewriter): Promise<ParsedPlayer> {
const oEmbed = getPlayerOEmbed(request, url, html)
const urlGeneral = getPlayerUrlGeneral(url, html)
const urlCommon = getPlayerUrlCommon(url, html)
const width = getPlayerUrlWidth(url, html)
const height = getPlayerUrlHeight(url, html)
export default function getPlayer(context: Context): Promise<ParsedPlayer> {
const oEmbed = getPlayerOEmbed(context)
const urlGeneral = getPlayerUrlGeneral(context)
const urlCommon = getPlayerUrlCommon(context)
const width = getPlayerUrlWidth(context)
const height = getPlayerUrlHeight(context)
return Promise.all([oEmbed, urlGeneral, urlCommon, width, height]).then(([oEmbed, urlGeneral, urlCommon, width, height]) => {
if (oEmbed) {

View File

@ -2,6 +2,7 @@ import { decode } from "html-entities"
import { z } from "zod"
import { requestInit } from "../../config"
import { assign, PrioritizedReference } from "../common"
import type Context from "../../context"
import type { ParsedPlayer } from "./player"
const oEmbedBase = z.object({
@ -41,7 +42,7 @@ const oEmbed = z.union([
}),
])
export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRewriter) {
export default function getPlayerOEmbed(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<ParsedPlayer>()
const result: PrioritizedReference<ParsedPlayer> = {
bits: 1, // 0-1
@ -54,7 +55,7 @@ export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRe
allow: [],
},
}
html.on('link[type="application/json+oembed"]', {
context.html.on('link[type="application/json+oembed"]', {
async element(element) {
const oEmbedHref = decode(element.getAttribute("href") ?? "")
if (!oEmbedHref) {
@ -62,7 +63,7 @@ export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRe
}
let init: RequestInit
try {
init = requestInit(request)
init = requestInit(context.request)
} catch (e) {
reject(e)
return
@ -120,7 +121,7 @@ export default function getPlayerOEmbed(request: Request, url: URL, html: HTMLRe
}
},
})
html.onDocument({
context.html.onDocument({
end() {
resolve(result.content)
},

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign, toAbsoluteURL } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) {
export default function getPlayerUrlCommon(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[property="og:video"]', {
context.html.on('meta[property="og:video"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[property="og:video:secure_url"]', {
context.html.on('meta[property="og:video:secure_url"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,7 +26,7 @@ export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[property="og:video:url"]', {
context.html.on('meta[property="og:video:url"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -32,11 +34,10 @@ export default function getPlayerUrlCommon(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, url.href) : null)
},
})
context.html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null)
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign, toAbsoluteURL } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getPlayerUrlGeneral(url: URL, html: HTMLRewriter) {
export default function getPlayerUrlGeneral(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[property="twitter:player"]', {
context.html.on('meta[property="twitter:player"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getPlayerUrlGeneral(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:player"]', {
context.html.on('meta[name="twitter:player"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,11 +26,10 @@ export default function getPlayerUrlGeneral(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, url.href) : null)
},
})
context.html.onDocument({
end() {
resolve(result.content ? toAbsoluteURL(result.content, context.url.href) : null)
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) {
export default function getPlayerUrlHeight(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<number | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[property="twitter:player:height"]', {
context.html.on('meta[property="twitter:player:height"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:player:height"]', {
context.html.on('meta[name="twitter:player:height"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,7 +26,7 @@ export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[property="og:video:height"]', {
context.html.on('meta[property="og:video:height"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -32,12 +34,11 @@ export default function getPlayerUrlHeight(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<number | null>((resolve) => {
html.onDocument({
end() {
const content = parseInt(result.content!, 10)
resolve(Number.isNaN(content) ? null : content)
},
})
context.html.onDocument({
end() {
const content = parseInt(result.content!, 10)
resolve(Number.isNaN(content) ? null : content)
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) {
export default function getPlayerUrlWidth(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<number | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[property="twitter:player:width"]', {
context.html.on('meta[property="twitter:player:width"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:player:width"]', {
context.html.on('meta[name="twitter:player:width"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,7 +26,7 @@ export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[property="og:video:width"]', {
context.html.on('meta[property="og:video:width"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -32,12 +34,11 @@ export default function getPlayerUrlWidth(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<number | null>((resolve) => {
html.onDocument({
end() {
const content = parseInt(result.content!, 10)
resolve(Number.isNaN(content) ? null : content)
},
})
context.html.onDocument({
end() {
const content = parseInt(result.content!, 10)
resolve(Number.isNaN(content) ? null : content)
},
})
return promise
}

View File

@ -1,22 +1,23 @@
import { assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getSensitive(url: URL, html: HTMLRewriter) {
export default function getSensitive(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<boolean>()
const result: PrioritizedReference<boolean> = {
bits: 1, // 0-1
priority: 0,
content: false,
}
html.on('.tweet[data-possibly-sensitive="true"]', {
context.html.on('.tweet[data-possibly-sensitive="true"]', {
element() {
assign(result, 1, true)
},
})
return new Promise<boolean>((resolve) => {
html.onDocument({
end() {
resolve(result.content)
},
})
context.html.onDocument({
end() {
resolve(result.content)
},
})
return promise
}

View File

@ -1,14 +1,16 @@
import { decode } from "html-entities"
import { assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getSiteName(url: URL, html: HTMLRewriter) {
export default function getSiteName(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: url.hostname,
content: context.url.hostname,
}
html.on('meta[property="og:site_name"]', {
context.html.on('meta[property="og:site_name"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -16,7 +18,7 @@ export default function getSiteName(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="application-name"]', {
context.html.on('meta[name="application-name"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -24,11 +26,10 @@ export default function getSiteName(url: URL, html: HTMLRewriter) {
}
},
})
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content)
},
})
context.html.onDocument({
end() {
resolve(result.content)
},
})
return promise
}

View File

@ -1,15 +1,17 @@
import { decode } from "html-entities"
import clip from "summaly/built/utils/clip"
import { BufferedTextHandler, assign } from "../common"
import type Context from "../../context"
import type { PrioritizedReference } from "../common"
export default function getTitle(url: URL, html: HTMLRewriter) {
export default function getTitle(context: Context) {
const { promise, resolve, reject } = Promise.withResolvers<string | null>()
const result: PrioritizedReference<string | null> = {
bits: 2, // 0-3
priority: 0,
content: null,
}
html.on('meta[property="og:title"]', {
context.html.on('meta[property="og:title"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -17,7 +19,7 @@ export default function getTitle(url: URL, html: HTMLRewriter) {
}
},
})
html.on('meta[name="twitter:title"]', {
context.html.on('meta[name="twitter:title"]', {
element(element) {
const content = element.getAttribute("content")
if (content) {
@ -25,17 +27,16 @@ export default function getTitle(url: URL, html: HTMLRewriter) {
}
},
})
html.on(
context.html.on(
"title",
new BufferedTextHandler((text) => {
assign(result, 1, decode(text))
}),
)
return new Promise<string | null>((resolve) => {
html.onDocument({
end() {
resolve(result.content && clip(result.content, 100))
},
})
context.html.onDocument({
end() {
resolve(result.content && clip(result.content, 100))
},
})
return promise
}

View File

@ -1,13 +1,14 @@
import amazon from "./amazon"
import general from "./general"
import wikipedia from "./wikipedia"
import type Context from "../context"
export default function summary(request: Request, url: URL, html: HTMLRewriter) {
if (url.hostname === "www.amazon.com" || url.hostname === "www.amazon.co.jp" || url.hostname === "www.amazon.ca" || url.hostname === "www.amazon.com.br" || url.hostname === "www.amazon.com.mx" || url.hostname === "www.amazon.co.uk" || url.hostname === "www.amazon.de" || url.hostname === "www.amazon.fr" || url.hostname === "www.amazon.it" || url.hostname === "www.amazon.es" || url.hostname === "www.amazon.nl" || url.hostname === "www.amazon.cn" || url.hostname === "www.amazon.in" || url.hostname === "www.amazon.au") {
return amazon(url, html)
export default function summary(context: Context) {
if (context.url.hostname === "www.amazon.com" || context.url.hostname === "www.amazon.co.jp" || context.url.hostname === "www.amazon.ca" || context.url.hostname === "www.amazon.com.br" || context.url.hostname === "www.amazon.com.mx" || context.url.hostname === "www.amazon.co.uk" || context.url.hostname === "www.amazon.de" || context.url.hostname === "www.amazon.fr" || context.url.hostname === "www.amazon.it" || context.url.hostname === "www.amazon.es" || context.url.hostname === "www.amazon.nl" || context.url.hostname === "www.amazon.cn" || context.url.hostname === "www.amazon.in" || context.url.hostname === "www.amazon.au") {
return amazon(context)
}
if (`.${url.hostname}`.endsWith(".wikipedia.org")) {
return wikipedia(url, html)
if (`.${context.url.hostname}`.endsWith(".wikipedia.org")) {
return wikipedia(context)
}
return general(request, url, html)
return general(context)
}

View File

@ -1,10 +1,12 @@
import clip from "summaly/built/utils/clip"
import { requestInit } from "../../config"
import type Context from "../../context"
export default async function wikipedia(url: URL, html: HTMLRewriter) {
const lang = url.hostname.split(".")[0]
const title = url.pathname.split("/")[2]
const response = await fetch(`https://${lang}.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=${title}`)
const json = await response.json<any>()
export default async function wikipedia(context: Context) {
const lang = context.url.hostname.split(".")[0]
const title = context.url.pathname.split("/")[2]
const response = await fetch(`https://${lang}.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=${title}`, requestInit(context.request))
const json: any = await response.json()
const info = json.query.pages[Object.keys(json.query.pages)[0]]
return {
title: info.title,
@ -15,8 +17,9 @@ export default async function wikipedia(url: URL, html: HTMLRewriter) {
url: null,
width: null,
height: null,
allow: [],
},
sitename: "Wikipedia",
url: url.href,
url: context.url.href,
}
}