mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-16 14:12:51 +00:00
feat: 添加内置浏览器导航功能
This commit is contained in:
parent
d048aa33f7
commit
bb83875c99
94
electron/electron.js
vendored
94
electron/electron.js
vendored
@ -910,6 +910,7 @@ function createWebTabWindow(args) {
|
|||||||
event: 'stop-loading',
|
event: 'stop-loading',
|
||||||
id: browserView.webContents.id,
|
id: browserView.webContents.id,
|
||||||
}).then(_ => { })
|
}).then(_ => { })
|
||||||
|
|
||||||
// 加载完成暗黑模式下把窗口背景色改成白色,避免透明网站背景色穿透
|
// 加载完成暗黑模式下把窗口背景色改成白色,避免透明网站背景色穿透
|
||||||
if (nativeTheme.shouldUseDarkColors) {
|
if (nativeTheme.shouldUseDarkColors) {
|
||||||
browserView.setBackgroundColor('#FFFFFF')
|
browserView.setBackgroundColor('#FFFFFF')
|
||||||
@ -1320,6 +1321,99 @@ ipcMain.on('webTabDestroyAll', (event) => {
|
|||||||
event.returnValue = "ok"
|
event.returnValue = "ok"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内置浏览器 - 后退
|
||||||
|
*/
|
||||||
|
ipcMain.on('webTabGoBack', (event) => {
|
||||||
|
const item = currentWebTab()
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (item.view.webContents.canGoBack()) {
|
||||||
|
item.view.webContents.goBack()
|
||||||
|
// 导航后更新状态
|
||||||
|
setTimeout(() => {
|
||||||
|
utils.onDispatchEvent(webTabWindow.webContents, {
|
||||||
|
event: 'navigation-state',
|
||||||
|
id: item.id,
|
||||||
|
canGoBack: item.view.webContents.canGoBack(),
|
||||||
|
canGoForward: item.view.webContents.canGoForward()
|
||||||
|
}).then(_ => { })
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
event.returnValue = "ok"
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内置浏览器 - 前进
|
||||||
|
*/
|
||||||
|
ipcMain.on('webTabGoForward', (event) => {
|
||||||
|
const item = currentWebTab()
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (item.view.webContents.canGoForward()) {
|
||||||
|
item.view.webContents.goForward()
|
||||||
|
// 导航后更新状态
|
||||||
|
setTimeout(() => {
|
||||||
|
utils.onDispatchEvent(webTabWindow.webContents, {
|
||||||
|
event: 'navigation-state',
|
||||||
|
id: item.id,
|
||||||
|
canGoBack: item.view.webContents.canGoBack(),
|
||||||
|
canGoForward: item.view.webContents.canGoForward()
|
||||||
|
}).then(_ => { })
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
event.returnValue = "ok"
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内置浏览器 - 刷新
|
||||||
|
*/
|
||||||
|
ipcMain.on('webTabReload', (event) => {
|
||||||
|
const item = currentWebTab()
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
item.view.webContents.reload()
|
||||||
|
// 刷新完成后会触发 did-stop-loading 事件,在那里会更新导航状态
|
||||||
|
event.returnValue = "ok"
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内置浏览器 - 停止加载
|
||||||
|
*/
|
||||||
|
ipcMain.on('webTabStop', (event) => {
|
||||||
|
const item = currentWebTab()
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
item.view.webContents.stop()
|
||||||
|
event.returnValue = "ok"
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内置浏览器 - 获取导航状态
|
||||||
|
*/
|
||||||
|
ipcMain.on('webTabGetNavigationState', (event) => {
|
||||||
|
const item = currentWebTab()
|
||||||
|
if (!item) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const canGoBack = item.view.webContents.canGoBack()
|
||||||
|
const canGoForward = item.view.webContents.canGoForward()
|
||||||
|
|
||||||
|
utils.onDispatchEvent(webTabWindow.webContents, {
|
||||||
|
event: 'navigation-state',
|
||||||
|
id: item.id,
|
||||||
|
canGoBack,
|
||||||
|
canGoForward
|
||||||
|
}).then(_ => { })
|
||||||
|
|
||||||
|
event.returnValue = "ok"
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 隐藏窗口(mac、win隐藏,其他关闭)
|
* 隐藏窗口(mac、win隐藏,其他关闭)
|
||||||
*/
|
*/
|
||||||
|
|||||||
90
electron/render/tabs/assets/css/style.css
vendored
90
electron/render/tabs/assets/css/style.css
vendored
@ -2,7 +2,7 @@
|
|||||||
--tab-font-family: -apple-system, 'Segoe UI', roboto, oxygen-sans, ubuntu, cantarell, 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
--tab-font-family: -apple-system, 'Segoe UI', roboto, oxygen-sans, ubuntu, cantarell, 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
||||||
--tab-font-size: 12px;
|
--tab-font-size: 12px;
|
||||||
--tab-transition: background-color 200ms ease-out, color 200ms ease-out;
|
--tab-transition: background-color 200ms ease-out, color 200ms ease-out;
|
||||||
--tab-cursor: pointer; /* 设置鼠标指针为手型 */
|
--tab-cursor: pointer;
|
||||||
--tab-color: #7f8792;
|
--tab-color: #7f8792;
|
||||||
--tab-background: #EFF0F4;
|
--tab-background: #EFF0F4;
|
||||||
--tab-active-color: #222529;
|
--tab-active-color: #222529;
|
||||||
@ -15,7 +15,8 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
@ -39,8 +40,43 @@ html, body {
|
|||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul {
|
/* 导航按钮 */
|
||||||
|
.nav-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 12px;
|
||||||
|
-webkit-app-region: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-controls div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-controls svg {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
color: var(--tab-active-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-controls .disabled {
|
||||||
|
cursor: not-allowed !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-controls .disabled svg {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签 */
|
||||||
|
.nav-tabs {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -48,18 +84,17 @@ html, body {
|
|||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul::-webkit-scrollbar {
|
.nav-tabs::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul li {
|
.nav-tabs li {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: calc(100% - 5px);
|
height: calc(100% - 5px);
|
||||||
padding: 7px 8px;
|
padding: 7px 8px;
|
||||||
margin: 0 8px 0 0;
|
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
max-width: 240px;
|
max-width: 240px;
|
||||||
scroll-margin: 12px;
|
scroll-margin: 12px;
|
||||||
@ -70,24 +105,23 @@ html, body {
|
|||||||
-webkit-app-region: none;
|
-webkit-app-region: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul li:first-child {
|
.nav-tabs li:first-child {
|
||||||
margin-left: 8px;
|
|
||||||
border-left: none;
|
border-left: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.nav ul li.active {
|
.nav-tabs li.active {
|
||||||
color: var(--tab-active-color);
|
color: var(--tab-active-color);
|
||||||
background: var(--tab-active-background);
|
background: var(--tab-active-background);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul li.active .tab-icon.background {
|
.nav-tabs li.active .tab-icon.background {
|
||||||
background-image: url(../image/link_normal_selected_icon.png);
|
background-image: url(../image/link_normal_selected_icon.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.nav ul li:not(.active)::after {
|
.nav-tabs li:not(.active)::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
@ -96,22 +130,24 @@ html, body {
|
|||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul li:not(.active):last-child::after {
|
.nav-tabs li:not(.active):last-child::after {
|
||||||
content: none;
|
content: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 浏览器打开 */
|
/* 浏览器打开 */
|
||||||
.browser {
|
.nav-browser {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 0 14px;
|
padding: 0 14px;
|
||||||
|
margin: 0 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: var(--tab-background);
|
background-color: var(--tab-background);
|
||||||
-webkit-app-region: none;
|
-webkit-app-region: none;
|
||||||
}
|
}
|
||||||
.browser span {
|
|
||||||
|
.nav-browser span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
@ -161,6 +197,7 @@ html, body {
|
|||||||
0% {
|
0% {
|
||||||
transform: scale(0.8) rotate(0deg);
|
transform: scale(0.8) rotate(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
transform: scale(0.8) rotate(360deg);
|
transform: scale(0.8) rotate(360deg);
|
||||||
}
|
}
|
||||||
@ -205,18 +242,17 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 不同平台样式 */
|
/* 不同平台样式 */
|
||||||
body.win32 .nav ul {
|
body.win32 .nav {
|
||||||
margin-left: 8px;
|
padding-left: 8px;
|
||||||
margin-right: 186px;
|
padding-right: 186px;
|
||||||
}
|
}
|
||||||
body.win32 .browser {
|
|
||||||
right: 140px;
|
body.darwin .nav {
|
||||||
|
padding-left: 76px;
|
||||||
}
|
}
|
||||||
body.darwin .nav ul {
|
|
||||||
margin-left: 76px;
|
body.darwin.full-screen .nav {
|
||||||
}
|
padding-left: 8px;
|
||||||
body.darwin.full-screen .nav ul {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 暗黑模式 */
|
/* 暗黑模式 */
|
||||||
@ -229,15 +265,15 @@ body.darwin.full-screen .nav ul {
|
|||||||
--tab-close-color: #E3E3E3;
|
--tab-close-color: #E3E3E3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav ul li.active .tab-icon.background {
|
.nav-tabs li.active .tab-icon.background {
|
||||||
background-image: url(../image/dark/link_normal_selected_icon.png);
|
background-image: url(../image/dark/link_normal_selected_icon.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.browser span {
|
.nav-browser span {
|
||||||
background-image: url(../image/dark/link_normal_selected_icon.png);
|
background-image: url(../image/dark/link_normal_selected_icon.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-icon.background {
|
.tab-icon.background {
|
||||||
background-image: url(../image/dark/link_normal_icon.png);
|
background-image: url(../image/dark/link_normal_icon.png);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,7 +9,19 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="app" class="app">
|
<div id="app" class="app">
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<ul>
|
<div class="nav-controls">
|
||||||
|
<div class="nav-back" :class="{disabled: !canGoBack}" @click="goBack">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
||||||
|
</div>
|
||||||
|
<div class="nav-forward" :class="{disabled: !canGoForward}" @click="goForward">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
||||||
|
</div>
|
||||||
|
<div class="nav-refresh" @click="loadingState ? stop() : refresh()">
|
||||||
|
<svg v-if="loadingState" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
||||||
|
<svg v-else xmlns="http://www.w3.org/2000/svg" style="transform:scale(0.99)" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="nav-tabs">
|
||||||
<li v-for="item in tabs" :data-id="item.id" :class="{active: activeId === item.id}" @click="onSwitch(item)">
|
<li v-for="item in tabs" :data-id="item.id" :class="{active: activeId === item.id}" @click="onSwitch(item)">
|
||||||
<div v-if="item.state === 'loading'" class="tab-icon loading">
|
<div v-if="item.state === 'loading'" class="tab-icon loading">
|
||||||
<div class="tab-icon-loading"></div>
|
<div class="tab-icon-loading"></div>
|
||||||
@ -19,9 +31,9 @@
|
|||||||
<div class="tab-close" @click.stop="onClose(item)"></div>
|
<div class="tab-close" @click.stop="onClose(item)"></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
<div v-if="canBrowser" class="nav-browser" @click="onBrowser">
|
||||||
<div v-if="canBrowser" class="browser" @click="onBrowser">
|
<span></span>
|
||||||
<span></span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -29,10 +41,20 @@
|
|||||||
const App = {
|
const App = {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
// 当前激活的标签页ID
|
||||||
activeId: 0,
|
activeId: 0,
|
||||||
|
|
||||||
|
// 标签页列表
|
||||||
tabs: [],
|
tabs: [],
|
||||||
|
|
||||||
|
// 停止定时器
|
||||||
stopTimer: null,
|
stopTimer: null,
|
||||||
|
|
||||||
|
// 是否可以后退
|
||||||
|
canGoBack: false,
|
||||||
|
|
||||||
|
// 是否可以前进
|
||||||
|
canGoForward: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
@ -42,6 +64,7 @@
|
|||||||
window.__onDispatchEvent = (detail) => {
|
window.__onDispatchEvent = (detail) => {
|
||||||
const {id, event} = detail
|
const {id, event} = detail
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
// 创建标签页
|
||||||
case 'create':
|
case 'create':
|
||||||
this.tabs.push(Object.assign({
|
this.tabs.push(Object.assign({
|
||||||
id,
|
id,
|
||||||
@ -52,6 +75,7 @@
|
|||||||
}, detail))
|
}, detail))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 关闭标签页
|
||||||
case 'close':
|
case 'close':
|
||||||
const closeIndex = this.tabs.findIndex(item => item.id === id)
|
const closeIndex = this.tabs.findIndex(item => item.id === id)
|
||||||
if (closeIndex > -1) {
|
if (closeIndex > -1) {
|
||||||
@ -59,11 +83,14 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 切换标签页
|
||||||
case 'switch':
|
case 'switch':
|
||||||
this.activeId = id
|
this.activeId = id
|
||||||
this.scrollTabActive()
|
this.scrollTabActive()
|
||||||
|
this.updateNavigationState()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 页面标题
|
||||||
case 'title':
|
case 'title':
|
||||||
if (["HitoseaTask", "DooTask", "about:blank"].includes(detail.title)) {
|
if (["HitoseaTask", "DooTask", "about:blank"].includes(detail.title)) {
|
||||||
return
|
return
|
||||||
@ -75,6 +102,7 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 页面图标
|
||||||
case 'favicon':
|
case 'favicon':
|
||||||
const faviconItem = this.tabs.find(item => item.id === id)
|
const faviconItem = this.tabs.find(item => item.id === id)
|
||||||
if (faviconItem) {
|
if (faviconItem) {
|
||||||
@ -88,6 +116,7 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 开始加载
|
||||||
case 'start-loading':
|
case 'start-loading':
|
||||||
const startItem = this.tabs.find(item => item.id === id)
|
const startItem = this.tabs.find(item => item.id === id)
|
||||||
if (startItem) {
|
if (startItem) {
|
||||||
@ -96,19 +125,33 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 停止加载
|
||||||
case 'stop-loading':
|
case 'stop-loading':
|
||||||
this.stopTimer = setTimeout(_ => {
|
this.stopTimer = setTimeout(_ => {
|
||||||
const stopItem = this.tabs.find(item => item.id === id)
|
const stopItem = this.tabs.find(item => item.id === id)
|
||||||
if (stopItem) {
|
if (stopItem) {
|
||||||
stopItem.state = 'loaded'
|
stopItem.state = 'loaded'
|
||||||
}
|
}
|
||||||
|
if (id === this.activeId) {
|
||||||
|
this.updateNavigationState()
|
||||||
|
}
|
||||||
}, 300)
|
}, 300)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 导航状态
|
||||||
|
case 'navigation-state':
|
||||||
|
if (id === this.activeId) {
|
||||||
|
this.canGoBack = detail.canGoBack
|
||||||
|
this.canGoForward = detail.canGoForward
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
// 进入全屏
|
||||||
case 'enter-full-screen':
|
case 'enter-full-screen':
|
||||||
document.body.classList.add('full-screen')
|
document.body.classList.add('full-screen')
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// 离开全屏
|
||||||
case 'leave-full-screen':
|
case 'leave-full-screen':
|
||||||
document.body.classList.remove('full-screen')
|
document.body.classList.remove('full-screen')
|
||||||
break
|
break
|
||||||
@ -119,41 +162,85 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
/**
|
||||||
|
* 获取当前激活的标签页
|
||||||
|
* @returns {object|null}
|
||||||
|
*/
|
||||||
activeItem() {
|
activeItem() {
|
||||||
if (this.tabs.length === 0) {
|
if (this.tabs.length === 0) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return this.tabs.find(item => item.id === this.activeId)
|
return this.tabs.find(item => item.id === this.activeId)
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 获取页面标题
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
pageTitle() {
|
pageTitle() {
|
||||||
return this.activeItem ? this.activeItem.title : 'Untitled'
|
return this.activeItem ? this.activeItem.title : 'Untitled'
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 是否可以打开浏览器
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
canBrowser() {
|
canBrowser() {
|
||||||
return !(this.activeItem && this.isLocalHost(this.activeItem.url))
|
return !(this.activeItem && this.isLocalHost(this.activeItem.url))
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取加载状态
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
loadingState() {
|
||||||
|
return this.activeItem ? this.activeItem.state === 'loading' : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
/**
|
||||||
|
* 监听页面标题
|
||||||
|
* @param title
|
||||||
|
*/
|
||||||
pageTitle(title) {
|
pageTitle(title) {
|
||||||
document.title = title;
|
document.title = title;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* 切换标签页
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
onSwitch(item) {
|
onSwitch(item) {
|
||||||
this.sendMessage('webTabActivate', item.id)
|
this.sendMessage('webTabActivate', item.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭标签页
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
onClose(item) {
|
onClose(item) {
|
||||||
this.sendMessage('webTabClose', item.id);
|
this.sendMessage('webTabClose', item.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开浏览器
|
||||||
|
*/
|
||||||
onBrowser() {
|
onBrowser() {
|
||||||
this.sendMessage('webTabExternal')
|
this.sendMessage('webTabExternal')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标签页图标样式
|
||||||
|
* @param item
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
iconStyle(item) {
|
iconStyle(item) {
|
||||||
return item.icon ? `background-image: url(${item.icon})` : ''
|
return item.icon ? `background-image: url(${item.icon})` : ''
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标签页标题
|
||||||
|
* @param item
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
tabTitle(item) {
|
tabTitle(item) {
|
||||||
if (item.title) {
|
if (item.title) {
|
||||||
return item.title
|
return item.title
|
||||||
@ -166,10 +253,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滚动到当前激活的标签页
|
||||||
|
*/
|
||||||
scrollTabActive() {
|
scrollTabActive() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
const child = document.querySelector(`.nav ul li[data-id=${this.activeId}]`)
|
const child = document.querySelector(`.nav-tabs li[data-id="${this.activeId}"]`)
|
||||||
if (child) {
|
if (child) {
|
||||||
child.scrollIntoView({behavior: 'smooth', block: 'nearest'})
|
child.scrollIntoView({behavior: 'smooth', block: 'nearest'})
|
||||||
}
|
}
|
||||||
@ -179,10 +269,52 @@
|
|||||||
}, 0)
|
}, 0)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
* @param event
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
sendMessage(event, args) {
|
sendMessage(event, args) {
|
||||||
electron?.sendMessage(event, args)
|
electron?.sendMessage(event, args)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后退
|
||||||
|
*/
|
||||||
|
goBack() {
|
||||||
|
if (!this.canGoBack) return
|
||||||
|
this.sendMessage('webTabGoBack')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前进
|
||||||
|
*/
|
||||||
|
goForward() {
|
||||||
|
if (!this.canGoForward) return
|
||||||
|
this.sendMessage('webTabGoForward')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止
|
||||||
|
*/
|
||||||
|
stop() {
|
||||||
|
this.sendMessage('webTabStop')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新
|
||||||
|
*/
|
||||||
|
refresh() {
|
||||||
|
this.sendMessage('webTabReload')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新导航状态
|
||||||
|
*/
|
||||||
|
updateNavigationState() {
|
||||||
|
this.sendMessage('webTabGetNavigationState')
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否是本地URL
|
* 判断是否是本地URL
|
||||||
* @param url
|
* @param url
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user