mirror of
https://github.com/primedigitaltech/azon_seeker.git
synced 2026-01-19 13:13:22 +08:00
Register AppContext & Format style cell
This commit is contained in:
parent
105bfadfa3
commit
da5e76aae7
4
shim.d.ts
vendored
4
shim.d.ts
vendored
@ -17,7 +17,3 @@ declare module 'webext-bridge' {
|
||||
>;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
type AppContext = 'options' | 'sidepanel';
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ if (import.meta.hot) {
|
||||
import('./contentScriptHMR');
|
||||
}
|
||||
|
||||
Object.assign(self, { appContext: 'background' });
|
||||
|
||||
// remove or turn this off if you don't use side panel
|
||||
const USE_SIDE_PANEL = true;
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ defineProps<{ model: AmazonDetailItem }>();
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.review-item-footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
@ -62,7 +62,7 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.link-text {
|
||||
cursor: default;
|
||||
font-family: v-mono;
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.icon {
|
||||
display: block;
|
||||
color: #333;
|
||||
|
||||
@ -18,7 +18,7 @@ defineProps<{
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.image-link-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -155,7 +155,7 @@ const handleExport = () => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.review-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
export function useAppContext() {
|
||||
const appContext = document.location.pathname.split('/')[2] as AppContext;
|
||||
return { appContext };
|
||||
}
|
||||
@ -6,7 +6,6 @@ import { storage } from 'webextension-polyfill';
|
||||
import type { RemovableRef, StorageLikeAsync, UseStorageAsyncOptions } from '@vueuse/core';
|
||||
import type { Ref } from 'vue-demi';
|
||||
import type { Storage } from 'webextension-polyfill';
|
||||
import { useAppContext } from './useAppContext';
|
||||
|
||||
export type WebExtensionStorageOptions<T> = UseStorageAsyncOptions<T>;
|
||||
|
||||
@ -121,8 +120,7 @@ export function useWebExtensionStorage<T>(
|
||||
return;
|
||||
}
|
||||
if (typeof listenToStorageChanges === 'string') {
|
||||
const { appContext: context } = useAppContext();
|
||||
if (listenToStorageChanges !== context) {
|
||||
if (listenToStorageChanges !== appContext) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// Firefox `browser.tabs.executeScript()` requires scripts return a primitive value
|
||||
(() => {
|
||||
Object.assign(self, { appContext: 'content script' });
|
||||
import('./html-to-image');
|
||||
})();
|
||||
|
||||
4
src/global.d.ts
vendored
4
src/global.d.ts
vendored
@ -9,6 +9,10 @@ declare module '*.vue' {
|
||||
export default component;
|
||||
}
|
||||
|
||||
declare type AppContext = 'options' | 'sidepanel' | 'background' | 'content script';
|
||||
|
||||
declare const appContext: AppContext;
|
||||
|
||||
declare interface Chrome {
|
||||
sidePanel?: {
|
||||
setPanelBehavior: (options: { openPanelOnActionClick: boolean }) => void;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { App } from 'vue';
|
||||
import { useAppContext } from '~/composables/useAppContext';
|
||||
import { router } from '~/router';
|
||||
|
||||
/**
|
||||
@ -7,11 +6,9 @@ import { router } from '~/router';
|
||||
* @param app Vue app
|
||||
*/
|
||||
export function setupApp(app: App) {
|
||||
const { appContext: context } = useAppContext();
|
||||
|
||||
// Inject a globally available `$app` object in template
|
||||
app.config.globalProperties.$app = {
|
||||
context,
|
||||
context: appContext,
|
||||
};
|
||||
|
||||
// Provide access to `app` in script setup with `const app = inject('app')`
|
||||
|
||||
@ -2,6 +2,9 @@ import App from './App.vue';
|
||||
import { setupApp } from '~/logic/common-setup';
|
||||
import '../styles';
|
||||
|
||||
// This is the options page of the extension.
|
||||
Object.assign(self, { appContext: 'options' });
|
||||
|
||||
const app = createApp(App);
|
||||
setupApp(app);
|
||||
app.mount('#app');
|
||||
|
||||
@ -370,7 +370,7 @@ const handleClearData = async () => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.result-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@ -5,10 +5,9 @@ import {
|
||||
createMemoryHistory,
|
||||
RouteRecordRaw,
|
||||
} from 'vue-router';
|
||||
import { useAppContext } from '~/composables/useAppContext';
|
||||
import { site } from '~/logic/storages/global';
|
||||
|
||||
const routeObj: Record<AppContext, RouteRecordRaw[]> = {
|
||||
const routeObj: Record<'sidepanel' | 'options', RouteRecordRaw[]> = {
|
||||
options: [
|
||||
{ path: '/', redirect: `/${site.value}` },
|
||||
{ path: '/amazon', component: () => import('~/options/views/AmazonResultTable.vue') },
|
||||
@ -23,12 +22,17 @@ const routeObj: Record<AppContext, RouteRecordRaw[]> = {
|
||||
|
||||
export const router: Plugin = {
|
||||
install(app) {
|
||||
const { appContext: context } = useAppContext();
|
||||
const routes = routeObj[context];
|
||||
const router = createRouter({
|
||||
history: context === 'sidepanel' ? createMemoryHistory() : createWebHashHistory(),
|
||||
routes,
|
||||
});
|
||||
app.use(router);
|
||||
switch (appContext) {
|
||||
case 'sidepanel':
|
||||
case 'options':
|
||||
const routes = routeObj[appContext];
|
||||
const router = createRouter({
|
||||
history: appContext === 'sidepanel' ? createMemoryHistory() : createWebHashHistory(),
|
||||
routes,
|
||||
});
|
||||
app.use(router);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -2,6 +2,9 @@ import App from './App.vue';
|
||||
import { setupApp } from '~/logic/common-setup';
|
||||
import '../styles';
|
||||
|
||||
// This is the sidepanel page of the extension.
|
||||
Object.assign(self, { appContext: 'sidepanel' });
|
||||
|
||||
const app = createApp(App);
|
||||
setupApp(app);
|
||||
app.mount('#app');
|
||||
|
||||
@ -111,7 +111,7 @@ const updateReviews = (params: { asin: string; reviews: AmazonReview[] }) => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.review-page-entry {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@ -128,7 +128,7 @@ const handleInterrupt = () => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.search-page-entry {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
@ -81,7 +81,7 @@ const handleInterrupt = () => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.homedepot-sidepanel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { createEndpointRuntime } from './internal/endpoint-runtime';
|
||||
import { createStreamWirings } from './internal/stream';
|
||||
import { createPersistentPort } from './internal/persistent-port';
|
||||
import browser from 'webextension-polyfill';
|
||||
|
||||
// Chrome API types for sidepanel
|
||||
declare global {
|
||||
@ -23,7 +22,8 @@ declare global {
|
||||
getOptions: (options: { tabId?: number }) => Promise<{ path?: string }>;
|
||||
};
|
||||
}
|
||||
var chrome: Chrome | undefined;
|
||||
|
||||
var chrome: Chrome;
|
||||
}
|
||||
|
||||
const port = createPersistentPort('sidepanel');
|
||||
@ -31,71 +31,6 @@ const endpointRuntime = createEndpointRuntime('sidepanel', (message) => port.pos
|
||||
|
||||
port.onMessage(endpointRuntime.handleMessage);
|
||||
|
||||
/**
|
||||
* Set up Chrome's sidepanel API for Manifest V3 extensions
|
||||
*
|
||||
* This function initializes the Chrome sidepanel API and configures its behavior.
|
||||
* Use this in your sidepanel entry point to ensure the sidepanel works correctly.
|
||||
*
|
||||
* Example usage in your sidepanel script:
|
||||
*
|
||||
* ```ts
|
||||
* import { setupSidepanel, sendMessage } from 'webext-bridge/sidepanel'
|
||||
*
|
||||
* // Initialize the sidepanel
|
||||
* setupSidepanel({ defaultPath: 'sidepanel.html' })
|
||||
*
|
||||
* // Send a message to background
|
||||
* sendMessage('get-data', { key: 'value' }, 'background')
|
||||
* .then(response => console.log(response))
|
||||
*
|
||||
* // Listen for messages from other contexts
|
||||
* onMessage('update-sidebar', (message) => {
|
||||
* console.log(message.data)
|
||||
* // Update sidebar UI
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param options Configuration options for the sidepanel
|
||||
* @param options.defaultPath Default HTML path for the sidepanel
|
||||
*/
|
||||
export function setupSidepanel(options: { defaultPath?: string } = {}) {
|
||||
if (typeof chrome !== 'undefined' && chrome.sidePanel) {
|
||||
// Chrome specific sidepanel API
|
||||
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
|
||||
|
||||
if (options.defaultPath) {
|
||||
chrome.sidePanel.setOptions({ path: options.defaultPath });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册侧边栏显示事件的回调函数
|
||||
* @param callback 当侧边栏显示时要执行的回调函数
|
||||
* @returns 用于移除事件监听器的函数
|
||||
*/
|
||||
export function onSidepanelShown(callback: () => void): () => void {
|
||||
if (typeof chrome !== 'undefined' && chrome.sidePanel && chrome.sidePanel.onShown) {
|
||||
chrome.sidePanel.onShown.addListener(callback);
|
||||
return () => chrome.sidePanel.onShown.removeListener(callback);
|
||||
}
|
||||
return () => {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册侧边栏隐藏事件的回调函数
|
||||
* @param callback 当侧边栏隐藏时要执行的回调函数
|
||||
* @returns 用于移除事件监听器的函数
|
||||
*/
|
||||
export function onSidepanelHidden(callback: () => void): () => void {
|
||||
if (typeof chrome !== 'undefined' && chrome.sidePanel && chrome.sidePanel.onHidden) {
|
||||
chrome.sidePanel.onHidden.addListener(callback);
|
||||
return () => chrome.sidePanel.onHidden.removeListener(callback);
|
||||
}
|
||||
return () => {};
|
||||
}
|
||||
|
||||
export function isSidepanelSupported(): boolean {
|
||||
return !!chrome.sidePanel;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user