Commit f1552320 authored by Domi's avatar Domi

feat: sidebar navigate bar

parent b2aead94
...@@ -12,7 +12,7 @@ import { ...@@ -12,7 +12,7 @@ import {
handleContentMounted, handleContentMounted,
} from "./sidebar" } from "./sidebar"
import config from "@/assets/config.json" import config from "@/assets/config.json"
import { allFrameScript, mainContentScript } from "@/manifest" import { allFrameScript, contentMainScript } from "@/manifest"
import { getIsEdge } from "@/utils/ext" import { getIsEdge } from "@/utils/ext"
type Config = typeof config type Config = typeof config
...@@ -28,7 +28,7 @@ const contentScript = { ...@@ -28,7 +28,7 @@ const contentScript = {
runAt: placeholder.run_at as "document_start", runAt: placeholder.run_at as "document_start",
} satisfies chrome.scripting.RegisteredContentScript } satisfies chrome.scripting.RegisteredContentScript
chrome.scripting.registerContentScripts([contentScript, mainContentScript]) chrome.scripting.registerContentScripts([contentScript, contentMainScript])
chrome.runtime.onMessage.addListener(handleMessage) chrome.runtime.onMessage.addListener(handleMessage)
chrome.commands.onCommand.addListener(handleCommand) chrome.commands.onCommand.addListener(handleCommand)
chrome.runtime.onStartup.addListener(() => { chrome.runtime.onStartup.addListener(() => {
......
...@@ -15,6 +15,14 @@ const emit = defineEmits<{ ...@@ -15,6 +15,14 @@ const emit = defineEmits<{
pageInfo: [pageInfo: { url: string; title: string; icon: string }] pageInfo: [pageInfo: { url: string; title: string; icon: string }]
}>() }>()
defineExpose({
reload,
goBack,
goForward,
})
const onceCallback = new Map<string, (e: MessageEvent) => boolean>()
const frame = ref<HTMLIFrameElement>() const frame = ref<HTMLIFrameElement>()
const patchs = reactive(config.data.webviewPatchs) const patchs = reactive(config.data.webviewPatchs)
const loadUrls = reactive(config.data.loadCandidates) const loadUrls = reactive(config.data.loadCandidates)
...@@ -22,27 +30,6 @@ const inited = ref(false) ...@@ -22,27 +30,6 @@ const inited = ref(false)
const frameUrl = ref("") const frameUrl = ref("")
const pageInfo = reactive({ url: "", title: "", icon: "" }) const pageInfo = reactive({ url: "", title: "", icon: "" })
const onceCallback = new Map<string, (e: MessageEvent) => boolean>()
function handleFrameMessage(e: MessageEvent) {
console.log("frame message: ", e, e.source !== frame.value?.contentWindow)
if (e.source !== frame.value?.contentWindow) return
const type = e.data.type
if (!type) return
onceCallback.get(type)?.(e) && onceCallback.delete(type)
switch (type) {
case FrameMessageType.pageInfo:
if (!pageInfo.url) {
pageInfo.url = e.data.url
pageInfo.title = e.data.title
pageInfo.icon = e.data.icon
emit("pageInfo", pageInfo)
}
break
}
}
onMounted(() => { onMounted(() => {
getLocal({ getLocal({
webviewPatchs: config.data.webviewPatchs, webviewPatchs: config.data.webviewPatchs,
...@@ -157,11 +144,63 @@ watch(patch, async (patch) => { ...@@ -157,11 +144,63 @@ watch(patch, async (patch) => {
} }
iframe.contentWindow?.postMessage( iframe.contentWindow?.postMessage(
{ {
type: FrameMessageType.contentRun, type: FrameMessageType.webviewRun,
}, },
"*" "*"
) )
}) })
function handleFrameMessage(e: MessageEvent) {
console.log("frame message: ", e, e.source !== frame.value?.contentWindow)
if (e.source !== frame.value?.contentWindow) return
const type = e.data.type
if (!type) return
onceCallback.get(type)?.(e) && onceCallback.delete(type)
switch (type) {
case FrameMessageType.pageInfo:
if (!pageInfo.url) {
pageInfo.url = e.data.url
pageInfo.title = e.data.title
pageInfo.icon = e.data.icon
emit("pageInfo", pageInfo)
}
break
}
}
function reload() {
console.log("reload")
frame.value?.contentWindow?.postMessage(
{
type: FrameMessageType.reload,
},
"*"
)
}
function goBack() {
console.log("goBack")
frame.value?.contentWindow?.postMessage(
{
type: FrameMessageType.goBack,
},
"*"
)
}
function goForward() {
console.log("goForward")
frame.value?.contentWindow?.postMessage(
{
type: FrameMessageType.goForward,
},
"*"
)
}
</script> </script>
<template> <template>
......
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 -960 960 960"
width="24"
fill="currentColor"
>
<path d="M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z" />
</svg>
</template>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 -960 960 960"
width="24"
fill="currentColor"
>
<path d="m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z" />
</svg>
</template>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 -960 960 960"
width="24"
fill="currentColor"
>
<path
d="M240-200h120v-240h240v240h120v-360L480-740 240-560v360Zm-80 80v-480l320-240 320 240v480H520v-240h-80v240H160Zm320-350Z"
/>
</svg>
</template>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 -960 960 960"
width="24"
fill="currentColor"
>
<path d="M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z" />
</svg>
</template>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 -960 960 960"
width="24"
fill="currentColor"
>
<path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z" />
</svg>
</template>
...@@ -125,7 +125,7 @@ function run() { ...@@ -125,7 +125,7 @@ function run() {
} }
async function postPageInfo() { async function postPageInfo() {
await new Promise((r) => setTimeout(r, 1000 * 3)) await new Promise((r) => setTimeout(r, 200))
window.parent?.postMessage( window.parent?.postMessage(
{ {
type: FrameMessageType.pageInfo, type: FrameMessageType.pageInfo,
...@@ -141,7 +141,7 @@ function handleFrameMessage(e: MessageEvent) { ...@@ -141,7 +141,7 @@ function handleFrameMessage(e: MessageEvent) {
if (!e.data || typeof e.data !== "object") return if (!e.data || typeof e.data !== "object") return
const type = e.data.type const type = e.data.type
switch (type) { switch (type) {
case FrameMessageType.contentRun: case FrameMessageType.webviewRun:
run() run()
postPageInfo() postPageInfo()
return return
...@@ -150,6 +150,12 @@ function handleFrameMessage(e: MessageEvent) { ...@@ -150,6 +150,12 @@ function handleFrameMessage(e: MessageEvent) {
type: ContentEventType.escapeLoad, type: ContentEventType.escapeLoad,
detail: { url: e.data.url }, detail: { url: e.data.url },
}) })
case FrameMessageType.reload:
return location.reload()
case FrameMessageType.goBack:
return history.back()
case FrameMessageType.goForward:
return history.forward()
} }
} }
......
...@@ -3,7 +3,7 @@ import { ContentScriptId } from "./types" ...@@ -3,7 +3,7 @@ import { ContentScriptId } from "./types"
const __DEV__ = process.env.NODE_ENV == "development" const __DEV__ = process.env.NODE_ENV == "development"
/** Manually register in the service worker */ /** Manually register in the service worker */
export const mainContentScript = { export const contentMainScript = {
id: ContentScriptId.main, id: ContentScriptId.main,
js: ["js/content-main.js"], js: ["js/content-main.js"],
runAt: "document_start", runAt: "document_start",
...@@ -24,7 +24,7 @@ export const defaultSidebarPath = "sidebar.html" ...@@ -24,7 +24,7 @@ export const defaultSidebarPath = "sidebar.html"
const manifest = { const manifest = {
// maximum of 45 characters // maximum of 45 characters
name: "__MSG_name__", name: "__MSG_name__",
version: "1.2.7", version: "1.2.8",
// edge 12 characters // edge 12 characters
// short_name: "__MSG_short_name__", // short_name: "__MSG_short_name__",
// no more than 132 characters // no more than 132 characters
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, reactive, computed, onUnmounted } from "vue" import { ref, onMounted, reactive, computed, onUnmounted } from "vue"
import { import { getLocal, getSession, isProtectedUrl } from "@/utils/ext"
emptyTab,
getLocal,
getSession,
isProtectedUrl,
updateFrameNetRules,
} from "@/utils/ext"
import config from "@/assets/config.json" import config from "@/assets/config.json"
import LoadingBar from "@/components/LoadingBar.vue"
import Webview from "@/components/Webview.vue" import Webview from "@/components/Webview.vue"
import { useI18n } from "@/utils/i18n" import { useI18n } from "@/utils/i18n"
import { MessageType } from "@/types" import { MessageType } from "@/types"
import SiteButton from "@/components/SiteButton.vue"
import Search from "@/components/Search.vue"
import SidebarHome from "@/components/sidebar/SidebarHome.vue" import SidebarHome from "@/components/sidebar/SidebarHome.vue"
import IconClose from "@/components/icons/IconClose.vue"
import IconSplitscreenRight from "@/components/icons/IconSplitscreenRight.vue"
import IconNavigateBefore from "@/components/icons/IconNavigateBefore.vue"
import IconNavigateNext from "@/components/icons/IconNavigateNext.vue"
import IconRefresh from "@/components/icons/IconRefresh.vue"
import IconHome from "@/components/icons/IconHome.vue"
const logoUrl = chrome.runtime.getURL("/logo.svg") const logoUrl = chrome.runtime.getURL("/logo.svg")
const { t } = useI18n() const { t } = useI18n()
...@@ -27,6 +24,7 @@ const currentTab = reactive({ ...@@ -27,6 +24,7 @@ const currentTab = reactive({
tabId: 0, tabId: 0,
}) })
const ua = ref("") const ua = ref("")
const webview = ref<InstanceType<typeof Webview> | null>(null)
const protectedUrl = computed(() => { const protectedUrl = computed(() => {
return isProtectedUrl(url.value) return isProtectedUrl(url.value)
...@@ -139,8 +137,51 @@ function go(link: string) { ...@@ -139,8 +137,51 @@ function go(link: string) {
<template> <template>
<div class="w-full h-screen flex flex-col"> <div class="w-full h-screen flex flex-col">
<div
:class="[
'flex gap-1 items-center justify-between h-8 px-1',
'*:size-7 *:rounded-full *:flex *:items-center *:justify-center ',
]"
>
<button @click="" class="group hover:bg-background-soft mr-auto">
<!-- <img class="size-4" :src="logoUrl" /> -->
<IconHome class="size-5 group-active:scale-90 transition-transform" />
</button>
<button class="group hover:bg-background-soft" @click="webview?.goBack()">
<IconNavigateBefore
class="size-5 scale-125 group-active:-translate-x-1 transition-transform"
/>
</button>
<button
class="group hover:bg-background-soft"
@click="webview?.goForward()"
>
<IconNavigateNext
class="size-5 scale-125 group-active:translate-x-1 transition-transform"
/>
</button>
<button class="group hover:bg-background-soft" @click="webview?.reload()">
<IconRefresh
class="size-5 group-active:rotate-180 transition-transform"
/>
</button>
<button class="group hover:bg-background-soft">
<IconSplitscreenRight
class="size-5 scale-95 group-active:scale-90 transition-transform"
/>
</button>
<button class="group hover:bg-background-soft">
<IconClose class="size-5 group-active:scale-90 transition-transform" />
</button>
</div>
<div class="w-full h-full" v-if="!protectedUrl"> <div class="w-full h-full" v-if="!protectedUrl">
<Webview :url="url" :ua="ua" @page-info="updateRecentItems" /> <Webview
ref="webview"
:url="url"
:ua="ua"
@page-info="updateRecentItems"
/>
</div> </div>
<SidebarHome <SidebarHome
......
...@@ -51,7 +51,10 @@ export enum ContentEventType { ...@@ -51,7 +51,10 @@ export enum ContentEventType {
export enum FrameMessageType { export enum FrameMessageType {
frameReady = "anything-copilot_frame-ready", frameReady = "anything-copilot_frame-ready",
contentRun = "anything-copilot_content-run", webviewRun = "anything-copilot_webview-run",
escapeLoad = "anything-copilot_escape-load", escapeLoad = "anything-copilot_escape-load",
pageInfo = "anything-copilot_page-info", pageInfo = "anything-copilot_page-info",
reload = "anything-copilot_reload",
goBack = "anything-copilot_go-back",
goForward = "anything-copilot_go-forward",
} }
import { mainContentScript } from "@/manifest" import { contentMainScript } from "@/manifest"
import { MessageType } from "@/types" import { MessageType } from "@/types"
type MessageSender = chrome.runtime.MessageSender type MessageSender = chrome.runtime.MessageSender
...@@ -114,7 +114,7 @@ export async function checkContent(tabId: number) { ...@@ -114,7 +114,7 @@ export async function checkContent(tabId: number) {
return false return false
} }
const contentScripts = [...manifest.content_scripts, mainContentScript] const contentScripts = [...manifest.content_scripts, contentMainScript]
try { try {
for (let item of contentScripts) { for (let item of contentScripts) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment