Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
n8n_ai_assistant
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
n8n_ai_assistant
Commits
307cb86f
Commit
307cb86f
authored
May 04, 2024
by
baotlake
Committed by
Domi
May 18, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: context menu
parent
0cc896d9
Changes
24
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
2856 additions
and
5426 deletions
+2856
-5426
env.d.ts
env.d.ts
+8
-0
package-lock.json
package-lock.json
+2456
-5261
package.json
package.json
+3
-3
base.css
src/assets/base.css
+21
-4
index.ts
src/bg/index.ts
+92
-15
sidebar.ts
src/bg/sidebar.ts
+34
-17
ContentSidebar.vue
src/components/sidebar/ContentSidebar.vue
+8
-1
ContentSidebarAddon.vue
src/components/sidebar/ContentSidebarAddon.vue
+27
-6
Navbar.vue
src/components/sidebar/Navbar.vue
+1
-1
SidebarHome.vue
src/components/sidebar/SidebarHome.vue
+2
-2
App.vue
src/content/App.vue
+4
-2
index.ts
src/content/index.ts
+8
-9
manifest.ts
src/manifest.ts
+9
-2
Popup.vue
src/pages/Popup.vue
+16
-36
Sidebar.vue
src/pages/Sidebar.vue
+32
-28
popup.ts
src/pages/popup.ts
+3
-0
sidebar.ts
src/pages/sidebar.ts
+14
-0
content.ts
src/store/content.ts
+1
-2
extension.ts
src/types/extension.ts
+1
-1
index.ts
src/types/index.ts
+4
-6
ext.ts
src/utils/ext.ts
+59
-1
Invoke.ts
src/utils/invoke/Invoke.ts
+31
-22
MessageInvoke.ts
src/utils/invoke/MessageInvoke.ts
+16
-5
tsconfig.node.json
tsconfig.node.json
+6
-2
No files found.
env.d.ts
View file @
307cb86f
...
@@ -20,6 +20,14 @@ export declare global {
...
@@ -20,6 +20,14 @@ export declare global {
platform
:
string
platform
:
string
}
}
}
}
interface
PromiseConstructor
{
withResolvers
:
()
=>
{
promise
:
Promise
<
any
>
resolve
:
(
value
:
any
)
=>
void
reject
:
(
reason
:
any
)
=>
void
}
}
}
}
export
{}
export
{}
package-lock.json
View file @
307cb86f
This source diff could not be displayed because it is too large. You can
view the blob
instead.
package.json
View file @
307cb86f
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
},
},
"dependencies"
:
{
"dependencies"
:
{
"
@firebase/remote-config
"
:
"
^0.4.5
"
,
"
@firebase/remote-config
"
:
"
^0.4.5
"
,
"
@types/chrome
"
:
"
^0.0.267
"
,
"
@types/turndown
"
:
"
^5.0.4
"
,
"
@types/turndown
"
:
"
^5.0.4
"
,
"
@vueuse/core
"
:
"
^10.7.1
"
,
"
@vueuse/core
"
:
"
^10.7.1
"
,
"
@vueuse/gesture
"
:
"
^2.0.0-beta.1
"
,
"
@vueuse/gesture
"
:
"
^2.0.0-beta.1
"
,
...
@@ -36,7 +37,6 @@
...
@@ -36,7 +37,6 @@
"
@crxjs/vite-plugin
"
:
"
^2.0.0-beta.23
"
,
"
@crxjs/vite-plugin
"
:
"
^2.0.0-beta.23
"
,
"
@intlify/unplugin-vue-i18n
"
:
"
^1.5.0
"
,
"
@intlify/unplugin-vue-i18n
"
:
"
^1.5.0
"
,
"
@tsconfig/node18
"
:
"
^18.2.2
"
,
"
@tsconfig/node18
"
:
"
^18.2.2
"
,
"
@types/chrome
"
:
"
^0.0.261
"
,
"
@types/lodash-es
"
:
"
^4.17.11
"
,
"
@types/lodash-es
"
:
"
^4.17.11
"
,
"
@types/node
"
:
"
^18.18.5
"
,
"
@types/node
"
:
"
^18.18.5
"
,
"
@vitejs/plugin-vue
"
:
"
^4.4.0
"
,
"
@vitejs/plugin-vue
"
:
"
^4.4.0
"
,
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
"
@vue/tsconfig
"
:
"
^0.4.0
"
,
"
@vue/tsconfig
"
:
"
^0.4.0
"
,
"
autoprefixer
"
:
"
^10.4.16
"
,
"
autoprefixer
"
:
"
^10.4.16
"
,
"
cross-env
"
:
"
^7.0.3
"
,
"
cross-env
"
:
"
^7.0.3
"
,
"
gulp
"
:
"
^
4.0.2
"
,
"
gulp
"
:
"
^
5.0.0
"
,
"
gulp-zip
"
:
"
^6.0.0
"
,
"
gulp-zip
"
:
"
^6.0.0
"
,
"
npm-run-all2
"
:
"
^6.1.1
"
,
"
npm-run-all2
"
:
"
^6.1.1
"
,
"
postcss
"
:
"
^8.4.31
"
,
"
postcss
"
:
"
^8.4.31
"
,
...
@@ -52,7 +52,7 @@
...
@@ -52,7 +52,7 @@
"
sass
"
:
"
^1.71.1
"
,
"
sass
"
:
"
^1.71.1
"
,
"
tailwindcss
"
:
"
^3.4.1
"
,
"
tailwindcss
"
:
"
^3.4.1
"
,
"
typescript
"
:
"
~5.2.0
"
,
"
typescript
"
:
"
~5.2.0
"
,
"
vite
"
:
"
^4.
4.11
"
,
"
vite
"
:
"
^4.
5.3
"
,
"
vitest
"
:
"
^1.1.0
"
,
"
vitest
"
:
"
^1.1.0
"
,
"
vue-tsc
"
:
"
^1.8.19
"
"
vue-tsc
"
:
"
^1.8.19
"
}
}
...
...
src/assets/base.css
View file @
307cb86f
...
@@ -61,6 +61,8 @@
...
@@ -61,6 +61,8 @@
--fg-hsl
:
var
(
--fg-hue
)
var
(
--fg-s
)
var
(
--fg-l
);
--fg-hsl
:
var
(
--fg-hue
)
var
(
--fg-s
)
var
(
--fg-l
);
--section-gap
:
160px
;
--section-gap
:
160px
;
color-scheme
:
light
;
}
}
@media
(
prefers-color-scheme
:
dark
)
{
@media
(
prefers-color-scheme
:
dark
)
{
...
@@ -88,6 +90,8 @@
...
@@ -88,6 +90,8 @@
--fg-hue
:
200
;
--fg-hue
:
200
;
--fg-s
:
0%
;
--fg-s
:
0%
;
--fg-l
:
100%
;
--fg-l
:
100%
;
color-scheme
:
dark
;
}
}
input
,
input
,
...
@@ -105,13 +109,26 @@
...
@@ -105,13 +109,26 @@
}
}
body
,
body
,
#app
{
#app
,
:root
{
color
:
var
(
--color-text
);
color
:
var
(
--color-text
);
background
:
var
(
--color-background
);
background
:
var
(
--color-background
);
transition
:
color
0.5s
,
background-color
0.5s
;
/* transition:
color 0.5s,
background-color 0.5s; */
line-height
:
1.6
;
line-height
:
1.6
;
font-family
:
Inter
,
-apple-system
,
BlinkMacSystemFont
,
"Segoe UI"
,
Roboto
,
font-family
:
Oxygen
,
Ubuntu
,
Cantarell
,
"Fira Sans"
,
"Droid Sans"
,
"Helvetica Neue"
,
Inter
,
-apple-system
,
BlinkMacSystemFont
,
"Segoe UI"
,
Roboto
,
Oxygen
,
Ubuntu
,
Cantarell
,
"Fira Sans"
,
"Droid Sans"
,
"Helvetica Neue"
,
sans-serif
;
sans-serif
;
font-size
:
15px
;
font-size
:
15px
;
text-rendering
:
optimizeLegibility
;
text-rendering
:
optimizeLegibility
;
...
...
src/bg/index.ts
View file @
307cb86f
...
@@ -12,8 +12,8 @@ import {
...
@@ -12,8 +12,8 @@ import {
}
from
"./offscreen"
}
from
"./offscreen"
import
{
import
{
registerContentSidebar
,
registerContentSidebar
,
unregisterContentSidebar
,
handleContentMounted
,
handleContentMounted
,
getContentSidebarItem
,
}
from
"./sidebar"
}
from
"./sidebar"
import
config
from
"@/assets/config.json"
import
config
from
"@/assets/config.json"
import
{
allFrameScript
,
contentMainScript
}
from
"@/manifest"
import
{
allFrameScript
,
contentMainScript
}
from
"@/manifest"
...
@@ -39,13 +39,29 @@ chrome.commands.onCommand.addListener(handleCommand)
...
@@ -39,13 +39,29 @@ chrome.commands.onCommand.addListener(handleCommand)
chrome
.
runtime
.
onStartup
.
addListener
(()
=>
{
chrome
.
runtime
.
onStartup
.
addListener
(()
=>
{
updateConfig
()
updateConfig
()
})
})
chrome
.
runtime
.
onInstalled
.
addListener
(
handleOnInstalled
)
chrome
.
contextMenus
.
onClicked
.
addListener
(
handleContextMenusClicked
)
if
(
isEdge
)
{
if
(
isEdge
&&
chrome
.
sidePanel
)
{
chrome
.
sidePanel
.
setOptions
({
chrome
.
sidePanel
.
setOptions
({
enabled
:
false
,
enabled
:
false
,
})
})
}
}
async
function
handleOnInstalled
(
details
:
chrome
.
runtime
.
InstalledDetails
)
{
chrome
.
contextMenus
.
create
({
contexts
:
[
"action"
],
id
:
"toggle-sidebar"
,
title
:
"Toggle Sidebar"
,
})
chrome
.
contextMenus
.
create
({
contexts
:
[
"link"
],
id
:
"open-in-sidebar"
,
title
:
"Open Link in Sidebar"
,
})
}
async
function
openPipBackground
(
url
:
string
)
{
async
function
openPipBackground
(
url
:
string
)
{
const
tab
=
await
chrome
.
tabs
.
create
({
const
tab
=
await
chrome
.
tabs
.
create
({
url
:
url
,
url
:
url
,
...
@@ -101,16 +117,16 @@ async function handleInvokeRequest(
...
@@ -101,16 +117,16 @@ async function handleInvokeRequest(
sender
:
chrome
.
runtime
.
MessageSender
sender
:
chrome
.
runtime
.
MessageSender
)
{
)
{
currentSender
=
sender
currentSender
=
sender
let
res
ult
=
await
messageInvoke
.
handleReqMsg
(
message
)
let
res
=
await
messageInvoke
.
handleReqMsg
(
message
)
if
(
!
sender
.
tab
?.
id
)
{
if
(
!
sender
.
tab
?.
id
)
{
console
.
error
(
"sender tab id is undefined"
,
sender
)
console
.
error
(
"sender tab id is undefined"
,
sender
)
}
}
if
(
res
ult
)
{
if
(
res
)
{
chrome
.
tabs
.
sendMessage
(
sender
.
tab
?.
id
!
,
{
chrome
.
tabs
.
sendMessage
(
sender
.
tab
?.
id
!
,
{
type
:
MessageType
.
invokeResponse
,
type
:
MessageType
.
invokeResponse
,
...
res
ult
,
...
res
,
})
})
}
}
}
}
...
@@ -134,24 +150,22 @@ function handleMessage(message: any, sender: chrome.runtime.MessageSender) {
...
@@ -134,24 +150,22 @@ function handleMessage(message: any, sender: chrome.runtime.MessageSender) {
chrome
.
tabs
.
sendMessage
(
message
.
tabId
,
message
.
message
)
chrome
.
tabs
.
sendMessage
(
message
.
tabId
,
message
.
message
)
break
break
case
MessageType
.
invokeRequest
:
case
MessageType
.
invokeRequest
:
handleInvokeRequest
(
message
,
sender
)
currentSender
=
sender
messageInvoke
.
handleReqMsg
(
message
,
sender
)
break
break
case
MessageType
.
invokeResponse
:
case
MessageType
.
invokeResponse
:
messageInvoke
.
handleResMsg
(
message
)
messageInvoke
.
handleResMsg
(
message
)
break
break
case
MessageType
.
contentMounted
:
case
MessageType
.
contentMounted
:
handleContentMounted
(
sender
.
tab
!
.
id
!
)
handleContentMounted
(
sender
)
break
break
case
MessageType
.
registerContentSidebar
:
case
MessageType
.
registerContentSidebar
:
registerContentSidebar
({
tabId
:
sender
.
tab
!
.
id
!
,
url
:
message
.
url
})
registerContentSidebar
(
sender
.
tab
!
.
id
!
,
message
.
info
)
break
case
MessageType
.
unregisterContentSidebar
:
unregisterContentSidebar
(
sender
.
tab
!
.
id
!
)
break
break
}
}
}
}
async
function
handleT
oggleMinimize
()
{
async
function
t
oggleMinimize
()
{
const
{
pipWindow
}
=
await
chrome
.
storage
.
local
.
get
({
pipWindow
:
null
})
const
{
pipWindow
}
=
await
chrome
.
storage
.
local
.
get
({
pipWindow
:
null
})
if
(
!
pipWindow
)
return
if
(
!
pipWindow
)
return
const
windowInfo
=
await
chrome
.
windows
.
get
(
pipWindow
.
windowId
)
const
windowInfo
=
await
chrome
.
windows
.
get
(
pipWindow
.
windowId
)
...
@@ -160,17 +174,65 @@ async function handleToggleMinimize() {
...
@@ -160,17 +174,65 @@ async function handleToggleMinimize() {
const
tabId
=
pipWindow
.
tabId
const
tabId
=
pipWindow
.
tabId
messageInvoke
.
invoke
({
messageInvoke
.
invoke
({
tabId
,
func
:
ServiceFunc
.
toggleMinimize
,
func
:
ServiceFunc
.
toggleMinimize
,
args
:
[],
args
:
[],
tabId
,
})
}
async
function
toggleSidebar
(
tab
?:
chrome
.
tabs
.
Tab
)
{
if
(
tab
?.
windowId
)
{
chrome
.
sidePanel
.
open
({
windowId
:
tab
?.
windowId
,
})
}
messageInvoke
.
invoke
({
func
:
ServiceFunc
.
toggleSidebar
,
args
:
[],
})
}
async
function
openInSidebar
(
url
:
string
,
tab
?:
chrome
.
tabs
.
Tab
)
{
let
contentMode
=
isEdge
||
!
chrome
.
sidePanel
const
contentSidebar
=
getContentSidebarItem
(
tab
?.
id
!
)
if
(
contentSidebar
&&
contentSidebar
.
visible
)
{
contentMode
=
true
}
if
(
contentMode
)
{
await
messageInvoke
.
invoke
({
func
:
ServiceFunc
.
toggleContentSidebar
,
args
:
[{
visible
:
true
,
collapse
:
false
}],
tabId
:
tab
?.
id
,
})
}
else
{
await
chrome
.
sidePanel
.
open
({
windowId
:
tab
?.
windowId
!
,
})
}
await
messageInvoke
.
invoke
({
key
:
ServiceFunc
.
waitSidebar
,
func
:
ServiceFunc
.
waitSidebar
,
args
:
[],
timeout
:
300
,
})
await
messageInvoke
.
invoke
({
func
:
ServiceFunc
.
openInSidebar
,
args
:
[{
urls
:
[
url
]
}],
})
})
}
}
function
handleCommand
(
command
:
string
)
{
function
handleCommand
(
command
:
string
,
tab
?:
chrome
.
tabs
.
Tab
)
{
console
.
log
(
"command: "
,
command
)
console
.
log
(
"command: "
,
command
)
switch
(
command
)
{
switch
(
command
)
{
case
"toggleMinimize"
:
case
"toggleMinimize"
:
handleToggleMinimize
()
toggleMinimize
()
break
case
"toggleSidebar"
:
toggleSidebar
(
tab
)
break
break
}
}
}
}
...
@@ -234,3 +296,18 @@ async function updateConfig() {
...
@@ -234,3 +296,18 @@ async function updateConfig() {
loadCandidates
,
loadCandidates
,
})
})
}
}
async
function
handleContextMenusClicked
(
info
:
chrome
.
contextMenus
.
OnClickData
,
tab
?:
chrome
.
tabs
.
Tab
)
{
console
.
log
(
info
)
switch
(
info
.
menuItemId
)
{
case
"toggle-sidebar"
:
toggleSidebar
(
tab
)
break
case
"open-in-sidebar"
:
openInSidebar
(
info
.
linkUrl
!
,
tab
)
break
}
}
src/bg/sidebar.ts
View file @
307cb86f
import
{
MessageType
}
from
"@/types"
import
{
MessageType
}
from
"@/types"
import
{
messageInvoke
}
from
"@/utils/invoke"
import
{
ServiceFunc
}
from
"@/types"
import
{
openSidebar
}
from
"@/utils/ext"
type
ContentSidebar
=
{
type
ContentSidebarItem
=
{
visible
:
boolean
tabId
:
number
tabId
:
number
url
?:
string
url
s
:
string
[]
}
}
const
contentSidebarMap
=
new
Map
<
number
,
ContentSidebar
>
()
const
contentSidebarMap
=
new
Map
<
number
,
ContentSidebar
Item
>
()
export
function
registerContentSidebar
({
tabId
,
url
}:
ContentSidebar
)
{
export
function
registerContentSidebar
(
contentSidebarMap
.
set
(
tabId
,
{
tabId
,
url
})
tabId
:
number
,
info
:
Partial
<
ContentSidebarItem
>
)
{
const
item
=
contentSidebarMap
.
get
(
tabId
)
||
{
visible
:
false
,
urls
:
[]
}
contentSidebarMap
.
set
(
tabId
,
{
...
item
,
...
info
,
tabId
,
})
}
}
export
function
unregisterContentSidebar
(
tabId
:
number
)
{
export
async
function
handleContentMounted
(
contentSidebarMap
.
delete
(
tabId
)
sender
:
chrome
.
runtime
.
MessageSender
}
)
{
if
(
sender
.
frameId
!==
0
)
return
if
(
!
sender
.
tab
)
return
const
tabId
=
sender
.
tab
.
id
!
export
async
function
handleContentMounted
(
tabId
:
number
)
{
const
item
=
contentSidebarMap
.
get
(
tabId
)
const
sidebar
=
contentSidebarMap
.
get
(
tabId
)
console
.
log
(
"handleContentMounted"
,
item
)
if
(
sidebar
)
{
if
(
item
&&
item
.
visible
)
{
await
chrome
.
storage
.
session
.
set
({
openSidebar
({
sidebarInitUrl
:
{
content
:
sidebar
.
url
},
urls
:
item
.
urls
,
})
tab
:
sender
.
tab
,
chrome
.
tabs
.
sendMessage
(
tabId
,
{
sidePanel
:
false
,
type
:
MessageType
.
openContentSidebar
,
url
:
sidebar
.
url
,
})
})
}
}
}
}
export
function
getContentSidebarItem
(
tabId
:
number
)
{
return
contentSidebarMap
.
get
(
tabId
)
}
src/components/sidebar/ContentSidebar.vue
View file @
307cb86f
...
@@ -109,6 +109,9 @@ onMounted(() => {
...
@@ -109,6 +109,9 @@ onMounted(() => {
window
.
addEventListener
(
"message"
,
handleMessage
)
window
.
addEventListener
(
"message"
,
handleMessage
)
chrome
.
runtime
.
sendMessage
({
chrome
.
runtime
.
sendMessage
({
type
:
MessageType
.
registerContentSidebar
,
type
:
MessageType
.
registerContentSidebar
,
info
:
{
visible
:
true
,
},
})
})
})
})
...
@@ -118,8 +121,12 @@ onUnmounted(() => {
...
@@ -118,8 +121,12 @@ onUnmounted(() => {
window
.
removeEventListener
(
"keyup"
,
handleKeyUp
)
window
.
removeEventListener
(
"keyup"
,
handleKeyUp
)
window
.
removeEventListener
(
"message"
,
handleMessage
)
window
.
removeEventListener
(
"message"
,
handleMessage
)
chrome
.
runtime
.
sendMessage
({
chrome
.
runtime
.
sendMessage
({
type
:
MessageType
.
unregisterContentSidebar
,
type
:
MessageType
.
registerContentSidebar
,
info
:
{
visible
:
false
,
},
})
})
console
.
log
(
"content sidebar unmounted"
)
})
})
</
script
>
</
script
>
...
...
src/components/sidebar/ContentSidebarAddon.vue
View file @
307cb86f
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
"vue"
import
{
ref
,
onMounted
}
from
"vue"
import
ContentSidebar
from
"./ContentSidebar.vue"
import
ContentSidebar
from
"./ContentSidebar.vue"
import
{
sidebarAddon
}
from
"@/store/content"
import
{
sidebarAddon
}
from
"@/store/content"
import
{
autoPointerCapture
}
from
"@/utils/dom"
import
{
autoPointerCapture
}
from
"@/utils/dom"
import
{
messageInvoke
}
from
"@/utils/invoke"
import
{
ServiceFunc
}
from
"@/types"
const
logoUrl
=
chrome
.
runtime
.
getURL
(
"/logo.svg"
)
const
logoUrl
=
chrome
.
runtime
.
getURL
(
"/logo.svg"
)
const
top
=
ref
(
72
)
const
top
=
ref
(
72
)
...
@@ -13,18 +15,37 @@ function handlePointerMove(e: PointerEvent) {
...
@@ -13,18 +15,37 @@ function handlePointerMove(e: PointerEvent) {
top
.
value
=
Math
.
max
(
12
,
Math
.
min
(
window
.
innerHeight
-
60
,
value
))
top
.
value
=
Math
.
max
(
12
,
Math
.
min
(
window
.
innerHeight
-
60
,
value
))
}
}
}
}
onMounted
(()
=>
{
messageInvoke
.
register
(
ServiceFunc
.
toggleContentSidebar
,
async
({
visible
,
collapse
}:
{
visible
:
boolean
;
collapse
?:
boolean
})
=>
{
sidebarAddon
.
visible
=
visible
??
!
sidebarAddon
.
visible
sidebarAddon
.
collapse
=
collapse
??
sidebarAddon
.
collapse
// how to
awai
messageInvoke
.
invoke
({
key
:
ServiceFunc
.
waitSidebar
,
func
:
ServiceFunc
.
waitSidebar
,
args
:
[],
timeout
:
300
,
})
}
)
})
</
script
>
</
script
>
<
template
>
<
template
>
<ContentSidebar
<ContentSidebar
v-if=
"sidebarAddon.visible"
v-if=
"sidebarAddon.visible"
:hidden=
"sidebarAddon.
hidden"
:hidden=
"sidebarAddon.
collapse"
@
close=
"sidebarAddon.visible = false"
@
close=
"sidebarAddon.visible = false"
@
hide=
"sidebarAddon.
hidden
= true"
@
hide=
"sidebarAddon.
collapse
= true"
/>
/>
<div
<div
v-if=
"sidebarAddon.
hidden
"
v-if=
"sidebarAddon.
collapse
"
:class=
"[
:class=
"[
'fixed top-16 right-0 p-1.5 bg-background/65 backdrop-blur-md cursor-pointer',
'fixed top-16 right-0 p-1.5 bg-background/65 backdrop-blur-md cursor-pointer',
'rounded-s shadow-lg z-[999999] hover:bg-background-mute/65',
'rounded-s shadow-lg z-[999999] hover:bg-background-mute/65',
...
@@ -32,7 +53,7 @@ function handlePointerMove(e: PointerEvent) {
...
@@ -32,7 +53,7 @@ function handlePointerMove(e: PointerEvent) {
:style=
"
{ top: top + 'px' }"
:style=
"
{ top: top + 'px' }"
@pointerdown="autoPointerCapture"
@pointerdown="autoPointerCapture"
@pointermove="handlePointerMove"
@pointermove="handlePointerMove"
@click="sidebarAddon.
hidden
= false"
@click="sidebarAddon.
collapse
= false"
>
>
<img
:src=
"logoUrl"
class=
"size-4 pointer-events-none select-none"
/>
<img
:src=
"logoUrl"
class=
"size-4 pointer-events-none select-none"
/>
</div>
</div>
...
...
src/components/sidebar/Navbar.vue
View file @
307cb86f
...
@@ -81,7 +81,7 @@ const handleDrop = (e: DragEvent) => {
...
@@ -81,7 +81,7 @@ const handleDrop = (e: DragEvent) => {
<
template
>
<
template
>
<div
<div
:class=
"[
:class=
"[
'flex gap-1 items-center justify-between h-9 px-1 z-10 shadow-sm',
'flex gap-1 items-center justify-between h-9 px-1 z-10 shadow-sm
shrink-0
',
'*:size-7 *:flex *:items-center *:justify-center ',
'*:size-7 *:flex *:items-center *:justify-center ',
]"
]"
@
dragenter=
"handleDragEnter"
@
dragenter=
"handleDragEnter"
...
...
src/components/sidebar/SidebarHome.vue
View file @
307cb86f
...
@@ -29,7 +29,7 @@ const emit = defineEmits({
...
@@ -29,7 +29,7 @@ const emit = defineEmits({
<Search
@
go=
"(url) => emit('go', url)"
/>
<Search
@
go=
"(url) => emit('go', url)"
/>
</div>
</div>
<div
class=
"flex flex-wrap gap-x-
4
gap-y-4 justify-center"
>
<div
class=
"flex flex-wrap gap-x-
3
gap-y-4 justify-center"
>
<SiteButton
<SiteButton
v-for=
"item of recentItems.slice(0, 12)"
v-for=
"item of recentItems.slice(0, 12)"
:key=
"item.url"
:key=
"item.url"
...
@@ -44,7 +44,7 @@ const emit = defineEmits({
...
@@ -44,7 +44,7 @@ const emit = defineEmits({
<!--
<div
class=
"text-center my-3"
>
Popular
</div>
-->
<!--
<div
class=
"text-center my-3"
>
Popular
</div>
-->
<div
class=
"w-full my-6 border-b border-background-soft h-0"
></div>
<div
class=
"w-full my-6 border-b border-background-soft h-0"
></div>
<div
class=
"flex flex-wrap gap-x-
4
gap-y-4 justify-center"
>
<div
class=
"flex flex-wrap gap-x-
3
gap-y-4 justify-center"
>
<SiteButton
<SiteButton
v-for=
"item of popularItems"
v-for=
"item of popularItems"
:icon=
"item.icon"
:icon=
"item.icon"
...
...
src/content/App.vue
View file @
307cb86f
...
@@ -12,7 +12,9 @@ const { t } = useI18n()
...
@@ -12,7 +12,9 @@ const { t } = useI18n()
const
topFrame
=
window
.
parent
==
window
const
topFrame
=
window
.
parent
==
window
onMounted
(()
=>
{
onMounted
(()
=>
{
if
(
topFrame
)
{
chrome
.
runtime
?.
sendMessage
({
type
:
MessageType
.
contentMounted
})
chrome
.
runtime
?.
sendMessage
({
type
:
MessageType
.
contentMounted
})
}
})
})
</
script
>
</
script
>
...
...
src/content/index.ts
View file @
307cb86f
...
@@ -46,16 +46,15 @@ function handleMessage(
...
@@ -46,16 +46,15 @@ function handleMessage(
})
})
sendResponse
({
type
:
MessageType
.
contentHere
})
sendResponse
({
type
:
MessageType
.
contentHere
})
break
break
case
MessageType
.
invokeResponse
:
messageInvoke
.
handleResMsg
(
message
)
break
case
MessageType
.
showChatDocs
:
case
MessageType
.
showChatDocs
:
chatDocsPanel
.
visible
=
true
chatDocsPanel
.
visible
=
true
break
break
case
MessageType
.
openContentSidebar
:
// case MessageType.openContentSidebar:
sidebarAddon
.
visible
=
true
// sidebarAddon.visible = true
sidebarAddon
.
hidden
=
false
// sidebarAddon.collapse = false
sidebarAddon
.
url
=
message
.
url
// break
case
MessageType
.
invokeResponse
:
messageInvoke
.
handleResMsg
(
message
)
break
break
case
MessageType
.
invokeRequest
:
case
MessageType
.
invokeRequest
:
messageInvoke
.
handleReqMsg
(
message
).
then
((
result
)
=>
{
messageInvoke
.
handleReqMsg
(
message
).
then
((
result
)
=>
{
...
@@ -172,12 +171,12 @@ function handleFrameMessage(e: MessageEvent) {
...
@@ -172,12 +171,12 @@ function handleFrameMessage(e: MessageEvent) {
detail
:
{
url
:
e
.
data
.
url
},
detail
:
{
url
:
e
.
data
.
url
},
})
})
case
FrameMessageType
.
invokeRequest
:
case
FrameMessageType
.
invokeRequest
:
handleInvokeRequest
(
e
.
data
,
e
.
source
as
Window
)
handle
Webview
InvokeRequest
(
e
.
data
,
e
.
source
as
Window
)
break
break
}
}
}
}
async
function
handleInvokeRequest
(
message
:
any
,
source
:
Window
)
{
async
function
handle
Webview
InvokeRequest
(
message
:
any
,
source
:
Window
)
{
const
{
key
,
func
,
args
}
=
message
const
{
key
,
func
,
args
}
=
message
let
result
=
null
let
result
=
null
let
error
=
null
let
error
=
null
...
...
src/manifest.ts
View file @
307cb86f
...
@@ -77,6 +77,7 @@ const manifest = {
...
@@ -77,6 +77,7 @@ const manifest = {
"sidePanel"
,
"sidePanel"
,
"declarativeNetRequestWithHostAccess"
,
"declarativeNetRequestWithHostAccess"
,
"declarativeNetRequestFeedback"
,
"declarativeNetRequestFeedback"
,
"contextMenus"
,
// "cookies",
// "cookies",
],
],
optional_permissions
:
[],
optional_permissions
:
[],
...
@@ -90,6 +91,12 @@ const manifest = {
...
@@ -90,6 +91,12 @@ const manifest = {
description
:
"__MSG_toggle_minimize_desc__"
,
description
:
"__MSG_toggle_minimize_desc__"
,
global
:
true
,
global
:
true
,
},
},
toggleSidebar
:
{
suggested_key
:
{
default
:
"Ctrl+0"
,
},
description
:
"Toggle Sidebar"
,
},
},
},
web_accessible_resources
:
[
web_accessible_resources
:
[
{
{
...
@@ -100,9 +107,9 @@ const manifest = {
...
@@ -100,9 +107,9 @@ const manifest = {
],
],
content_security_policy
:
{
content_security_policy
:
{
extension_pages
:
__DEV__
extension_pages
:
__DEV__
?
`script-src 'self' http://localhost:
3000
'wasm-unsafe-eval';`
?
`script-src 'self' http://localhost:
5173
'wasm-unsafe-eval';`
:
`script-src 'self' 'wasm-unsafe-eval'`
,
:
`script-src 'self' 'wasm-unsafe-eval'`
,
},
},
}
satisfies
Manifest
as
unknown
as
chrome
.
runtime
.
Manifest
}
satisfies
Manifest
as
any
export
default
manifest
export
default
manifest
src/pages/Popup.vue
View file @
307cb86f
...
@@ -20,7 +20,7 @@ import IconArrowCircleRight from "@/components/icons/IconArrowCircleRight.vue"
...
@@ -20,7 +20,7 @@ import IconArrowCircleRight from "@/components/icons/IconArrowCircleRight.vue"
import
IconSplitscreenRight
from
"@/components/icons/IconSplitscreenRight.vue"
import
IconSplitscreenRight
from
"@/components/icons/IconSplitscreenRight.vue"
import
IconLogo
from
"@/components/icons/IconLogo.vue"
import
IconLogo
from
"@/components/icons/IconLogo.vue"
import
SiteButton
from
"@/components/SiteButton.vue"
import
SiteButton
from
"@/components/SiteButton.vue"
import
{
getIsEdge
}
from
"@/utils/ext"
import
{
getIsEdge
,
openSidebar
}
from
"@/utils/ext"
import
{
handleImgError
}
from
"@/utils/dom"
import
{
handleImgError
}
from
"@/utils/dom"
import
{
homeUrl
,
feedbackUrl
}
from
"@/utils/const"
import
{
homeUrl
,
feedbackUrl
}
from
"@/utils/const"
...
@@ -113,7 +113,9 @@ function handleKeydown(e: KeyboardEvent) {
...
@@ -113,7 +113,9 @@ function handleKeydown(e: KeyboardEvent) {
}
}
if
(
e
.
code
==
"Backslash"
&&
(
e
.
ctrlKey
||
e
.
metaKey
))
{
if
(
e
.
code
==
"Backslash"
&&
(
e
.
ctrlKey
||
e
.
metaKey
))
{
e
.
preventDefault
()
e
.
preventDefault
()
openSidebar
()
openSidebar
({
urls
:
[],
}).
then
(()
=>
close
())
}
}
if
(
e
.
code
==
"ControlLeft"
||
e
.
code
==
"ControlRight"
)
{
if
(
e
.
code
==
"ControlLeft"
||
e
.
code
==
"ControlRight"
)
{
...
@@ -158,30 +160,7 @@ async function handlePipPopup() {
...
@@ -158,30 +160,7 @@ async function handlePipPopup() {
window
.
close
()
window
.
close
()
}
}
async
function
openSidebar
(
url
=
""
)
{
function
close
()
{
chrome
.
runtime
.
sendMessage
({
type
:
MessageType
.
openInSidebar
,
tabId
:
-
1
,
url
,
})
const
win
=
await
chrome
.
windows
.
getCurrent
()
await
chrome
.
storage
.
session
.
set
({
sidebarInitUrl
:
{
sidepanel
:
url
},
})
await
chrome
.
sidePanel
.
open
({
windowId
:
win
.
id
!
})
window
.
close
()
}
async
function
openContentSidebar
(
url
=
""
)
{
await
chrome
.
storage
.
session
.
set
({
sidebarInitUrl
:
{
content
:
url
},
})
await
chrome
.
tabs
.
sendMessage
(
activeTab
.
value
.
id
!
,
{
type
:
MessageType
.
openContentSidebar
,
tabId
:
activeTab
.
value
.
id
,
url
,
})
window
.
close
()
window
.
close
()
}
}
...
@@ -308,17 +287,18 @@ function showChatDocs() {
...
@@ -308,17 +287,18 @@ function showChatDocs() {
:disabled=
"isEdge && !avaiable"
:disabled=
"isEdge && !avaiable"
:title=
"t('openInSidebar')"
:title=
"t('openInSidebar')"
@
click=
"
@
click=
"
() =>
{
(e) =>
{
if (isEdge || keyboard.ctrl) {
openSidebar({
return openContentSidebar()
urls: [activeTab.url!],
}
sidePanel: !(isEdge || e.ctrlKey || e.metaKey),
openSidebar(activeTab.url)
tab: activeTab,
}).then(() => close())
}
}
"
"
>
>
<IconSplitscreenRight
class=
"size-8 shrink-0 scale-95"
/>
<IconSplitscreenRight
class=
"size-8 shrink-0 scale-95"
/>
<div
class=
"flex items-center justify-between flex-1 w-2/3 gap-2"
>
<div
class=
"flex items-center justify-between flex-1 w-2/3 gap-2"
>
<span
class=
"text-
sm
font-bold leading-4 truncate"
>
<span
class=
"text-
base
font-bold leading-4 truncate"
>
{{
isEdge
?
t
(
"openSidebar"
)
:
t
(
"openInSidebar"
)
}}
{{
isEdge
?
t
(
"openSidebar"
)
:
t
(
"openInSidebar"
)
}}
</span>
</span>
<span
class=
"text-xs"
>
CTRL + \
</span>
<span
class=
"text-xs"
>
CTRL + \
</span>
...
@@ -372,10 +352,10 @@ function showChatDocs() {
...
@@ -372,10 +352,10 @@ function showChatDocs() {
return handleClickLaunch(item.url)
return handleClickLaunch(item.url)
}
}
if (isEdge || keyboard.ctrl)
{
openSidebar(
{
return openContentSidebar(item.url)
urls: [item.url],
}
sidePanel: !(isEdge || keyboard.ctrl),
openSidebar(item.url
)
}).then(() => close()
)
}
}
"
"
/>
/>
...
...
src/pages/Sidebar.vue
View file @
307cb86f
...
@@ -10,7 +10,8 @@ import {
...
@@ -10,7 +10,8 @@ import {
import
config
from
"@/assets/config.json"
import
config
from
"@/assets/config.json"
import
Webview
,
{
type
PageInfo
}
from
"@/components/Webview.vue"
import
Webview
,
{
type
PageInfo
}
from
"@/components/Webview.vue"
import
{
useI18n
}
from
"@/utils/i18n"
import
{
useI18n
}
from
"@/utils/i18n"
import
{
MessageType
}
from
"@/types"
import
{
messageInvoke
}
from
"@/utils/invoke"
import
{
MessageType
,
ServiceFunc
}
from
"@/types"
import
SidebarHome
from
"@/components/sidebar/SidebarHome.vue"
import
SidebarHome
from
"@/components/sidebar/SidebarHome.vue"
import
Navbar
from
"@/components/sidebar/Navbar.vue"
import
Navbar
from
"@/components/sidebar/Navbar.vue"
import
{
FrameMessageType
}
from
"@/types"
import
{
FrameMessageType
}
from
"@/types"
...
@@ -121,37 +122,33 @@ onMounted(() => {
...
@@ -121,37 +122,33 @@ onMounted(() => {
}
}
)
)
getSession
({
sidebarInitUrl
:
{}
as
Record
<
string
,
string
>
,
}).
then
(({
sidebarInitUrl
})
=>
{
console
.
log
(
"[sidebar]"
,
sidebarInitUrl
,
mode
.
value
)
const
url
=
sidebarInitUrl
?.[
mode
.
value
]
if
(
url
&&
!
isProtectedUrl
(
url
))
{
go
(
url
)
}
})
chrome
.
tabs
.
getCurrent
().
then
((
t
)
=>
{
chrome
.
tabs
.
getCurrent
().
then
((
t
)
=>
{
currentTab
.
tabId
=
t
?.
id
||
-
1
currentTab
.
tabId
=
t
?.
id
||
-
1
})
})
chrome
.
runtime
.
onMessage
.
addListener
(
handleMessage
)
const
mountedAt
=
Date
.
now
()
})
messageInvoke
.
register
(
ServiceFunc
.
waitSidebar
,
()
=>
{})
onUnmounted
(()
=>
{
.
register
(
ServiceFunc
.
toggleSidebar
,
()
=>
{
chrome
.
runtime
.
onMessage
.
removeListener
(
handleMessage
)
if
(
Date
.
now
()
-
mountedAt
>
200
)
{
})
window
.
close
()
async
function
handleMessage
(
message
:
any
)
{
switch
(
message
.
type
)
{
case
MessageType
.
openInSidebar
:
const
url
=
message
.
url
if
(
message
.
tabId
==
currentTab
.
tabId
&&
!
isProtectedUrl
(
url
))
{
go
(
url
)
}
}
break
})
.
register
(
ServiceFunc
.
openInSidebar
,
({
urls
}:
{
urls
:
string
[]
})
=>
{
urls
.
forEach
((
url
)
=>
{
if
(
!
isProtectedUrl
(
url
))
{
go
(
url
)
}
}
}
})
})
chrome
.
runtime
.
sendMessage
({
type
:
MessageType
.
invokeResponse
,
key
:
ServiceFunc
.
waitSidebar
,
success
:
true
,
value
:
null
,
})
})
function
handlePageLoad
(
i
:
number
)
{
function
handlePageLoad
(
i
:
number
)
{
pagesInfo
[
i
]
=
{
...
pagesInfo
[
i
]
!
,
loading
:
true
}
pagesInfo
[
i
]
=
{
...
pagesInfo
[
i
]
!
,
loading
:
true
}
...
@@ -163,7 +160,9 @@ async function handlePageLoaded(i: number, pageInfo: PageInfo) {
...
@@ -163,7 +160,9 @@ async function handlePageLoaded(i: number, pageInfo: PageInfo) {
if
(
mode
.
value
===
"content"
)
{
if
(
mode
.
value
===
"content"
)
{
chrome
.
runtime
.
sendMessage
({
chrome
.
runtime
.
sendMessage
({
type
:
MessageType
.
registerContentSidebar
,
type
:
MessageType
.
registerContentSidebar
,
pages
:
pages
,
info
:
{
urls
:
pages
.
map
((
p
)
=>
p
.
url
),
},
})
})
}
}
...
@@ -328,7 +327,12 @@ function handlePointerLeave() {
...
@@ -328,7 +327,12 @@ function handlePointerLeave() {
@
drop=
"go"
@
drop=
"go"
/>
/>
<div
:class=
"['w-full h-full',
{ hidden: active != -1 }]">
<div
:class=
"[
'scrollbar w-full h-full flex-1 overflow-auto ',
{ hidden: active != -1 },
]"
>
<SidebarHome
<SidebarHome
:recentItems=
"recentItems"
:recentItems=
"recentItems"
:popularItems=
"popularItems"
:popularItems=
"popularItems"
...
...
src/pages/popup.ts
View file @
307cb86f
...
@@ -16,5 +16,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
...
@@ -16,5 +16,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
case
MessageType
.
invokeResponse
:
case
MessageType
.
invokeResponse
:
messageInvoke
.
handleResMsg
(
message
)
messageInvoke
.
handleResMsg
(
message
)
break
break
case
MessageType
.
invokeRequest
:
messageInvoke
.
handleReqMsg
(
message
,
sender
)
break
}
}
})
})
src/pages/sidebar.ts
View file @
307cb86f
...
@@ -2,9 +2,23 @@ import "@/assets/main.css"
...
@@ -2,9 +2,23 @@ import "@/assets/main.css"
import
{
createApp
}
from
"vue"
import
{
createApp
}
from
"vue"
import
{
i18n
}
from
"@/utils/i18n"
import
{
i18n
}
from
"@/utils/i18n"
import
{
messageInvoke
}
from
"@/utils/invoke"
import
Sidebar
from
"./Sidebar.vue"
import
Sidebar
from
"./Sidebar.vue"
import
{
MessageType
}
from
"@/types"
const
app
=
createApp
(
Sidebar
)
const
app
=
createApp
(
Sidebar
)
app
.
use
(
i18n
)
app
.
use
(
i18n
)
app
.
mount
(
"#app"
)
app
.
mount
(
"#app"
)
chrome
.
runtime
.
onMessage
.
addListener
((
message
,
sender
,
sendResponse
)
=>
{
console
.
log
(
"[sidebar] "
,
message
.
type
,
message
,
sender
)
switch
(
message
.
type
)
{
case
MessageType
.
invokeResponse
:
messageInvoke
.
handleResMsg
(
message
)
break
case
MessageType
.
invokeRequest
:
messageInvoke
.
handleReqMsg
(
message
,
sender
)
break
}
})
src/store/content.ts
View file @
307cb86f
...
@@ -23,8 +23,7 @@ export const docsAddon = reactive({
...
@@ -23,8 +23,7 @@ export const docsAddon = reactive({
export
const
sidebarAddon
=
reactive
({
export
const
sidebarAddon
=
reactive
({
visible
:
false
,
visible
:
false
,
hidden
:
false
,
collapse
:
false
,
url
:
""
,
})
})
type
DocInputItem
=
{
type
DocInputItem
=
{
...
...
src/types/
chrome
.ts
→
src/types/
extension
.ts
View file @
307cb86f
declare
namespace
chrome
.
declarativeNetRequest
{
declare
namespace
chrome
.
declarativeNetRequest
{
export
function
getSessionRules
(
filter
:
{
export
function
getSessionRules
(
filter
:
{
ruleIds
:
number
[]
ruleIds
:
number
[]
}):
Promise
<
Rule
[]
>
}):
Promise
<
chrome
.
declarativeNetRequest
.
Rule
[]
>
}
}
declare
interface
ManifestPatch
{
declare
interface
ManifestPatch
{
...
...
src/types/index.ts
View file @
307cb86f
...
@@ -6,20 +6,14 @@ export enum MessageType {
...
@@ -6,20 +6,14 @@ export enum MessageType {
bgPipLaunch
=
"bg-pip-launch"
,
bgPipLaunch
=
"bg-pip-launch"
,
pipLaunch
=
"pip-launch"
,
pipLaunch
=
"pip-launch"
,
contentMounted
=
"content-mount"
,
contentMounted
=
"content-mount"
,
// getPipWinInfo = "get-pip-win-info",
// pipWinInfo = "pip-win-info",
updateWindow
=
"update-window"
,
updateWindow
=
"update-window"
,
removeWindow
=
"remove-window"
,
removeWindow
=
"remove-window"
,
forwardToTab
=
"forward-to-tab"
,
forwardToTab
=
"forward-to-tab"
,
// toOffscreen = "to-offscreen",
// fromOffscreen = "from-offscreen",
invokeRequest
=
"invoke-request"
,
invokeRequest
=
"invoke-request"
,
invokeResponse
=
"invoke-Response"
,
invokeResponse
=
"invoke-Response"
,
showChatDocs
=
"show-chat-docs"
,
showChatDocs
=
"show-chat-docs"
,
openInSidebar
=
"open-in-sidebar"
,
openInSidebar
=
"open-in-sidebar"
,
registerContentSidebar
=
"register-content-sidebar"
,
registerContentSidebar
=
"register-content-sidebar"
,
unregisterContentSidebar
=
"unregister-content-sidebar"
,
openContentSidebar
=
"open-content-sidebar"
,
}
}
export
enum
ServiceFunc
{
export
enum
ServiceFunc
{
...
@@ -33,6 +27,10 @@ export enum ServiceFunc {
...
@@ -33,6 +27,10 @@ export enum ServiceFunc {
getPipWindow
=
"get-pip-window"
,
getPipWindow
=
"get-pip-window"
,
getMyTab
=
"get-my-tab"
,
getMyTab
=
"get-my-tab"
,
waitOffscreen
=
"wait-offscreen"
,
waitOffscreen
=
"wait-offscreen"
,
toggleSidebar
=
"toggle-sidebar"
,
toggleContentSidebar
=
"toggle-content-sidebar"
,
waitSidebar
=
"wait-sidebar"
,
openInSidebar
=
"open-in-sidebar"
,
}
}
export
type
ParseDocOptions
=
{
export
type
ParseDocOptions
=
{
...
...
src/utils/ext.ts
View file @
307cb86f
import
{
contentMainScript
}
from
"@/manifest"
import
{
contentMainScript
}
from
"@/manifest"
import
{
MessageType
}
from
"@/types"
import
{
MessageType
,
ServiceFunc
}
from
"@/types"
import
{
messageInvoke
}
from
"./invoke"
type
MessageSender
=
chrome
.
runtime
.
MessageSender
type
MessageSender
=
chrome
.
runtime
.
MessageSender
...
@@ -346,3 +347,60 @@ export async function getPipWindow({
...
@@ -346,3 +347,60 @@ export async function getPipWindow({
const
win
=
windows
.
find
((
w
)
=>
w
.
width
===
width
&&
w
.
height
===
height
)
const
win
=
windows
.
find
((
w
)
=>
w
.
width
===
width
&&
w
.
height
===
height
)
return
win
return
win
}
}
export
async
function
openSidebar
({
urls
,
tab
,
sidePanel
,
}:
{
urls
:
string
[]
tab
?:
chrome
.
tabs
.
Tab
sidePanel
?:
boolean
})
{
sidePanel
=
sidePanel
??
!!
chrome
.
sidePanel
if
(
sidePanel
)
{
let
windowId
=
tab
?.
windowId
if
(
!
windowId
)
{
const
win
=
await
chrome
.
windows
.
getCurrent
()
windowId
=
win
.
id
}
await
chrome
.
sidePanel
.
open
({
windowId
:
windowId
!
,
})
await
messageInvoke
.
invoke
({
key
:
ServiceFunc
.
waitSidebar
,
func
:
ServiceFunc
.
waitSidebar
,
args
:
[],
timeout
:
300
,
})
messageInvoke
.
invoke
({
func
:
ServiceFunc
.
openInSidebar
,
args
:
[{
urls
}],
})
return
}
let
tabId
=
tab
?.
id
if
(
!
tabId
)
{
const
tabs
=
await
chrome
.
tabs
.
query
({
active
:
true
,
currentWindow
:
true
,
})
tabId
=
tabs
[
0
].
id
}
await
messageInvoke
.
invoke
({
func
:
ServiceFunc
.
toggleContentSidebar
,
args
:
[{
visible
:
true
,
collapse
:
false
}],
tabId
:
tabId
,
})
messageInvoke
.
invoke
({
func
:
ServiceFunc
.
openInSidebar
,
args
:
[{
urls
}],
tabId
:
tabId
,
})
}
src/utils/invoke/Invoke.ts
View file @
307cb86f
type
CallbackItem
=
{
resolve
:
(
v
:
any
)
=>
void
reject
:
(
e
:
any
)
=>
void
}
export
interface
InvokeReq
{
export
interface
InvokeReq
{
func
:
string
func
:
string
args
:
any
[]
args
:
any
[]
...
@@ -17,8 +12,10 @@ export interface InvokeRes {
...
@@ -17,8 +12,10 @@ export interface InvokeRes {
value
:
any
value
:
any
}
}
type
PromiseObject
=
ReturnType
<
PromiseConstructor
[
"withResolvers"
]
>
export
abstract
class
Invoke
{
export
abstract
class
Invoke
{
private
pendingCallback
:
Record
<
string
,
CallbackItem
>
private
pendingCallback
:
Record
<
string
,
PromiseObject
>
private
count
:
number
private
count
:
number
private
name
:
string
private
name
:
string
private
uniqueId
:
string
private
uniqueId
:
string
...
@@ -39,28 +36,29 @@ export abstract class Invoke {
...
@@ -39,28 +36,29 @@ export abstract class Invoke {
protected
getReturnValue
(
key
:
string
,
req
:
InvokeReq
)
{
protected
getReturnValue
(
key
:
string
,
req
:
InvokeReq
)
{
let
timer
:
any
let
timer
:
any
const
{
func
,
timeout
}
=
req
const
{
func
,
timeout
}
=
req
const
promise
=
new
Promise
<
any
>
((
resolve
,
reject
)
=>
{
this
.
pendingCallback
[
key
]
=
{
resolve
,
reject
}
const
p
=
this
.
pendingCallback
[
key
]
||
Promise
.
withResolvers
()
this
.
pendingCallback
[
key
]
=
p
if
(
timeout
)
{
if
(
timeout
)
{
timer
=
setTimeout
(
timer
=
setTimeout
(
()
=>
reject
(
`"
${
this
.
name
}
" invoke timeout:
${
func
}
key:
${
key
}
`
),
()
=>
p
.
reject
(
`"
${
this
.
name
}
" invoke timeout:
${
func
}
key:
${
key
}
`
),
timeout
timeout
)
)
}
}
})
promise
.
finally
(()
=>
{
p
.
p
romise
.
finally
(()
=>
{
delete
this
.
pendingCallback
[
key
]
delete
this
.
pendingCallback
[
key
]
timer
&&
clearTimeout
(
timer
)
timer
&&
clearTimeout
(
timer
)
})
})
return
promise
return
p
.
p
romise
}
}
protected
setReturnValue
(
key
:
string
,
success
:
boolean
,
value
:
any
)
{
protected
setReturnValue
(
key
:
string
,
success
:
boolean
,
value
:
any
)
{
const
callback
=
this
.
pendingCallback
[
key
]
const
p
=
this
.
pendingCallback
[
key
]
if
(
callback
)
{
if
(
p
)
{
const
fn
=
success
!=
false
?
callback
.
resolve
:
callback
.
reject
const
fn
=
success
!=
false
?
p
.
resolve
:
p
.
reject
fn
(
value
)
fn
(
value
)
}
else
{
}
else
{
console
.
error
(
`unknown invoke callback message:
${
key
}
`
)
console
.
error
(
`unknown invoke callback message:
${
key
}
`
)
...
@@ -69,12 +67,21 @@ export abstract class Invoke {
...
@@ -69,12 +67,21 @@ export abstract class Invoke {
}
}
abstract
send
(
req
:
InvokeReq
):
Promise
<
{
key
:
string
}
>
abstract
send
(
req
:
InvokeReq
):
Promise
<
{
key
:
string
}
>
public
sendRes
?(
res
:
InvokeRes
,
sender
?:
any
):
void
public
handleResMsg
(
message
:
InvokeRes
)
{
public
handleResMsg
(
message
:
InvokeRes
)
{
const
{
key
,
success
,
value
}
=
message
const
{
key
,
success
,
value
}
=
message
if
(
!
key
||
typeof
success
!==
"boolean"
)
{
console
.
error
(
`invalid invoke response:
${
key
}
`
,
message
)
}
this
.
setReturnValue
(
key
,
success
,
value
)
this
.
setReturnValue
(
key
,
success
,
value
)
}
}
public
async
handleReqMsg
(
message
:
InvokeReq
)
{
public
async
handleReqMsg
(
message
:
InvokeReq
&
{
key
:
string
},
sender
?:
any
)
{
const
{
key
,
func
,
args
,
timeout
}
=
message
const
{
key
,
func
,
args
,
timeout
}
=
message
let
result
=
null
let
result
=
null
let
error
=
null
let
error
=
null
...
@@ -92,7 +99,9 @@ export abstract class Invoke {
...
@@ -92,7 +99,9 @@ export abstract class Invoke {
error
=
err
error
=
err
}
}
return
{
key
,
success
:
!
error
,
value
:
!
error
?
result
:
error
}
const
res
=
{
key
,
success
:
!
error
,
value
:
!
error
?
result
:
error
}
this
.
sendRes
?.(
res
,
sender
)
return
res
}
}
public
async
invoke
<
T
=
any
>
(
req
:
InvokeReq
):
Promise
<
T
>
{
public
async
invoke
<
T
=
any
>
(
req
:
InvokeReq
):
Promise
<
T
>
{
...
...
src/utils/invoke/MessageInvoke.ts
View file @
307cb86f
import
{
MessageType
,
ServiceFunc
,
type
ParseDocOptions
}
from
"@/types"
import
{
MessageType
,
ServiceFunc
,
type
ParseDocOptions
}
from
"@/types"
import
Invoke
,
{
type
InvokeReq
}
from
"./Invoke"
import
Invoke
,
{
type
InvokeReq
,
type
InvokeRes
}
from
"./Invoke"
class
MessageInvoke
extends
Invoke
{
class
MessageInvoke
extends
Invoke
{
public
async
send
(
req
:
InvokeReq
&
{
tabId
?:
number
})
{
public
async
send
(
req
:
InvokeReq
&
{
tabId
?:
number
})
{
...
@@ -22,10 +22,21 @@ class MessageInvoke extends Invoke {
...
@@ -22,10 +22,21 @@ class MessageInvoke extends Invoke {
return
{
key
}
return
{
key
}
}
}
public
handleResMsg
(
message
:
any
)
{
public
sendRes
(
res
:
InvokeRes
,
sender
?:
chrome
.
runtime
.
MessageSender
)
{
if
(
message
?.
type
===
MessageType
.
invokeResponse
)
{
if
(
!
sender
)
{
const
{
key
,
success
,
value
}
=
message
return
this
.
setReturnValue
(
key
,
success
,
value
)
}
if
(
sender
.
tab
?.
id
)
{
chrome
.
tabs
.
sendMessage
(
sender
.
tab
.
id
,
{
type
:
MessageType
.
invokeResponse
,
...
res
,
})
}
else
{
chrome
.
runtime
.
sendMessage
({
type
:
MessageType
.
invokeResponse
,
...
res
,
})
}
}
}
}
...
...
tsconfig.node.json
View file @
307cb86f
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
"include"
:
[
"include"
:
[
"utils"
,
"utils"
,
"./src/manifest.ts"
,
"./src/manifest.ts"
,
"./src/types/**/*.ts"
,
"package.json"
,
"package.json"
,
"vite.config.*"
,
"vite.config.*"
,
"vitest.config.*"
,
"vitest.config.*"
,
...
@@ -14,6 +15,9 @@
...
@@ -14,6 +15,9 @@
"composite"
:
true
,
"composite"
:
true
,
"module"
:
"ESNext"
,
"module"
:
"ESNext"
,
"moduleResolution"
:
"Bundler"
,
"moduleResolution"
:
"Bundler"
,
"types"
:
[
"node"
]
"types"
:
[
"node"
,
"@types/chrome"
]
}
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment