17 |
18 | ## Setting Screen
19 |
20 | To add a new gate using the setting screen, follow these simple steps:
21 |
22 | 1. Open the settings
23 | 2. Navigate to the `Open Gate` tab.
24 | 3. Click on the `Add Gate` button.
25 | 4. Enter the desired URL and title for the website you wish to embed.
26 | 5. Your new gate will now appear in the left sidebar of Obsidian. Click on its icon to view the embedded website within Obsidian.
27 |
28 |
29 |
30 |
31 |
32 |
33 | ## Gate Options
34 |
35 | Please refer to the [Gate Options](gate-options.md) documentation for more information on customizing your gates.
36 |
37 | ## Custom icon
38 |
39 | The app will automatically generate an icon for your gate based on the site's favicon. However, you can also set a custom icon for your gate. You can fill svg code in the icon field to set a custom icon. Remember to remove the `width` and `height` attributes from the svg code.
40 |
--------------------------------------------------------------------------------
/docs/assets/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenvanduocit/obsidian-open-gate/068f703988c911b845b7756a8543c48747978694/docs/assets/img.png
--------------------------------------------------------------------------------
/docs/assets/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenvanduocit/obsidian-open-gate/068f703988c911b845b7756a8543c48747978694/docs/assets/img_1.png
--------------------------------------------------------------------------------
/docs/assets/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenvanduocit/obsidian-open-gate/068f703988c911b845b7756a8543c48747978694/docs/assets/img_2.png
--------------------------------------------------------------------------------
/docs/custom-css.md:
--------------------------------------------------------------------------------
1 | # Custom CSS
2 |
3 | Every website has its own style, and you can customize the appearance of embedded websites in Open Gate by adding custom CSS. This can help match the embedded content with your Obsidian theme or make it more readable.
4 |
5 | ## How to Add Custom CSS
6 |
7 | You can add custom CSS in two ways:
8 |
9 | 1. Through the Gate Settings:
10 | - Open Gate Settings
11 | - Edit a gate
12 | - Enable Advanced Options
13 | - Add your CSS in the CSS field
14 |
15 | 2. In Markdown Code Blocks:
16 |
17 | If you use [inline embedded](inline-embedded.md), you can add custom CSS in the code block like this:
18 |
19 | ~~~
20 | ```gate
21 | url: https://example.com
22 | css: |
23 | html { font-size: 20px; }
24 | ```
25 | ~~~
26 |
27 | ## Useful Snippets
28 |
29 | ### Dark Mode
30 | Convert light websites to dark mode:
31 | ```css
32 | html {
33 | filter: invert(90%) hue-rotate(180deg)!important;
34 | }
35 | ```
36 |
37 | ### Readability Improvements
38 | Make text more readable:
39 | ```css
40 | html {
41 | font-size: 20px;
42 | }
43 |
44 | body {
45 | line-height: 1.6;
46 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
47 | }
48 | ```
49 |
50 | ### Hide Elements
51 | Remove unwanted elements:
52 | ```css
53 | .advertisement,
54 | .cookie-banner,
55 | .popup-overlay {
56 | display: none !important;
57 | }
58 | ```
59 |
60 | ### Custom Scrollbar
61 | Style the scrollbar:
62 | ```css
63 | ::-webkit-scrollbar {
64 | width: 8px;
65 | }
66 |
67 | ::-webkit-scrollbar-track {
68 | background: var(--background-primary);
69 | }
70 |
71 | ::-webkit-scrollbar-thumb {
72 | background: var(--text-muted);
73 | border-radius: 4px;
74 | }
75 | ```
76 |
77 | ## Tips
78 | - Use `!important` when your styles aren't being applied due to specificity conflicts
79 | - Test CSS changes incrementally to avoid breaking the layout
80 | - Use browser dev tools to inspect elements and find the right selectors
81 | - Consider using Obsidian CSS variables for better theme compatibility
82 |
83 | ## Resources
84 | - [MDN CSS Reference](https://developer.mozilla.org/en-US/docs/Web/CSS)
85 | - [CSS Tricks](https://css-tricks.com/)
86 | - Share your snippets in our [GitHub Discussions](https://github.com/nguyenvanduocit/obsidian-open-gate/discussions/categories/snippets)
--------------------------------------------------------------------------------
/docs/custom-javascript.md:
--------------------------------------------------------------------------------
1 | # Custom JavaScript
2 |
3 | The same with custom CSS, not much to say here, if you want to custom JS, it's mean you know what you are doing.
4 |
5 | But be careful, custom JS is very powerful, it can allow you to change the behavior of the website, or even leak your data. So only do it if you know what you are doing.
6 |
7 | In some use cases, I use custom JS to remove the annoying cookie banner, ads, popup, ....
8 |
9 | The best case is allows another plugin to interact with the embedded website.
10 |
--------------------------------------------------------------------------------
/docs/gate-link.md:
--------------------------------------------------------------------------------
1 | # Gate Link
2 |
3 | This feature allows you to create a link that opens a URL within the gate view of Obsidian, rather than navigating away in an external browser
4 |
5 | ## Usage
6 |
7 | ```md
8 | [Open Google Gate](obsidian://opengate?title=google&url=https%3A%2F%2Fdocs.google.com%2Fdocument%2Fd%2Fabc123%2Fedit)
9 | ```
10 |
11 | Please notice that the URL must be encoded. You can use [this tool](https://www.urlencoder.org/) to encode your URL.
12 |
13 | You may want to read [Gate Options](gate-options.md) to learn more about the options you can use. Of course, the are no space for custom css or javascript in the gate view.
14 |
15 | ## Editor context menu
16 |
17 | We know that encoding URLs can be a hassle, so we've added a context menu option to make it easier. Just right-click on the link, and select `Insert Gate Link`.
18 |
19 | A popup will appear, asking for the title and URL of the gate. The URL will be automatically encoded for you.
20 |
21 | 
22 |
23 | ## Convert to gate link
24 |
25 | If you right-click on a normal link, you will see an option to convert it to a gate link. The URL will be automatically encoded for you.
26 |
27 | ## Reuse gates
28 |
29 | Once again, to simplify the reuse of gates configured in the settings, the plugin automatically matches the title or URL with existing gates. If a match is found, the options from the gate configured in the settings are merged with the options specified in the note.
30 |
--------------------------------------------------------------------------------
/docs/gate-options.md:
--------------------------------------------------------------------------------
1 | # Gate Options
2 |
3 | If you can read code, here is what we have under the hood. The `GateFrameOption` type is used to define the options for a gate frame.
4 |
5 | <<< @/../src/GateOptions.d.ts
6 |
7 | ## User Agent
8 |
9 | Usually, you won't need to change the user agent. However, in some case, the website you are trying to embed may require a specific user agent to work correctly. For example, some websites may block requests from bots or crawlers. In this case, you can set the user agent to a common browser user agent to bypass this restriction.
10 |
11 | Currently, default value is:
12 |
13 | <<< @/../src/fns/getDefaultUserAgent.ts {2}
14 |
15 | ## profileKey
16 |
17 | This property is intriguing as it allows you to embed multiple emails in your vault using the `profileKey` for differentiation. The `profileKey` acts as a namespace, enabling gates with the same `profileKey` to share storage space. This facilitates using a single sign-on (SSO) to log into a website and maintaining the same session across all gates sharing that `profileKey`.
18 |
19 | In other words, `profileKey` is like profile on Chrome.
20 |
21 | ## zoomFactor
22 |
23 | The `zoomFactor` in the `GateFrameOption` determines the magnification level of the content within a "Gate" frame in Obsidian. A value of 1 means 100% zoom (normal size), 0.5 means the content is reduced to 50% of its normal size, and a value of 2 means the content is enlarged to 200% of its normal size.
24 |
25 | ## Css & Js Injection
26 |
27 | `css` and `js` allows you to customize the appearance and functionality of embedded websites.
28 |
29 | ### Example
30 |
31 | - Use CSS to modify styles for a consistent look with Obsidian.
32 | - Example: `html { font-family: 'Arial', sans-serif; }` changes the font.
33 | - Use JS to add interactivity or modify web content.
34 | - Example: `document.body.style.backgroundColor = "lightblue";` changes the background color.
35 |
36 | ### Warning
37 |
38 | - Incorrect CSS/JS may break the appearance/functionality of the gate.
39 | - Be cautious with JS that interacts with external websites to avoid security risks.
40 |
41 | You may want to read [Gate Options](gate-options.md) to learn more about the options you can use. Of course, the are no space for custom css or javascript in the gate view.
42 |
--------------------------------------------------------------------------------
/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # Getting Started
6 |
7 | To begin using the Obsidian Open Gate plugin, follow these simple steps to install it:
8 |
9 | 1. Direct Install: Navigate to the [Direct Install Link](https://obsidian.md/plugins?id=open-gate). This will take you to the plugin's page in the Obsidian app. Follow the instructions to install.
10 | 2. Once installed, access the plugin settings in Obsidian to configure it according to your preferences.
11 | 3. To start embedding websites, open the command palette (`Ctrl+P` on Windows/Linux, `Cmd+P` on macOS) and type `Create new gate`. Enter the desired URL and title for the website you wish to embed.
12 | 4. Your new gate will now appear in the left sidebar of Obsidian. Click on its icon to view the embedded website within Obsidian.
13 |
14 | You may notice that there are several options available for customizing your gates. We will deep dive into these features in the next section. For now, feel free to explore the plugin and experiment with embedding different websites to enhance your note-taking experience.
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 |
4 | hero:
5 | name: "Open Gate"
6 | text: "Embed any website in to Obsidian"
7 | tagline: "Anything you need, right where you need it"
8 | actions:
9 | - theme: brand
10 | text: Direct Install
11 | link: https://obsidian.md/plugins?id=open-gate
12 | - theme: alt
13 | text: Tutorial
14 | link: /introduction
15 |
16 | image:
17 | src: /logo.webp
18 | alt: VitePress
19 |
20 | features:
21 | - title: Embed Any Website
22 | icon: 🖼️
23 | details: Create "Gates" that display websites directly in Obsidian's interface
24 | - title: Flexible Options
25 | icon: 📄
26 | details: Open websites in dedicated views or embed them inline within your notes
27 | - title: Profile Management
28 | icon: 🔗
29 | details: Utilize profile keys to share storage between different gates, similar to Chrome profiles
30 | - title: Customizable Experience
31 | icon: 🎨
32 | details: Inject custom CSS and JavaScript to tailor the appearance and functionality of embedded websites
33 | ---
34 |
35 |
78 |
79 | ## Contributers
80 |
81 | Thanks to all the people who have contributed!
82 |
83 |
84 |
85 |
86 |
87 |
88 |
112 |
--------------------------------------------------------------------------------
/docs/inline-embedded.md:
--------------------------------------------------------------------------------
1 | # Inline Embedded
2 |
3 | You can embed a view directly in a note:
4 |
5 | ~~~md
6 | ```gate
7 | url: https://12bit.vn
8 | height: 300
9 | zoomFactor: 1
10 | css: |
11 | html { filter: invert(90%) hue-rotate(180deg)!important; }
12 | ```
13 | ~~~
14 |
15 | Here is the result:
16 |
17 | 
18 |
19 | You can use any property from the [Gate Options](gate-options.md) documentation.
20 |
21 | ## Reuse gates
22 |
23 | To simplify the reuse of gates configured in the settings, the plugin automatically matches the title or URL with existing gates. If a match is found, the options from the gate configured in the settings are merged with the options specified in the note.
24 |
25 | For instance, if there is a gate titled `12bit` configured in the settings, you can easily reuse it by only specifying the `title` and any additional option like `height` in your note as shown below:
26 |
27 | ~~~md
28 | ```gate
29 | title: 12bit
30 | height: 300
31 | ```
32 | ~~~
33 |
34 | This will open the `12bit` gate with a height of `300px`.
35 |
--------------------------------------------------------------------------------
/docs/introduction.md:
--------------------------------------------------------------------------------
1 | # What is Open Gate?
2 |
3 | **Obsidian Open Gate** seamlessly integrates web browsing into your Obsidian note-taking experience. Embed any website as a "Gate" within the Obsidian interface or directly within notes. Customize the layout, inject custom CSS, and access Gates quickly via hotkeys or a command palette. Whether you're researching, studying, or just browsing, Obsidian Open Gate keeps everything you need in one place, enhancing your productivity and streamlining your workflow.
4 |
5 | ## How does it work?
6 |
7 | Under the hood, Obsidian Open Gate uses webview (mobile) and iframe (desktop) technologies to display websites within the app.
8 |
9 | ## Why use Open Gate?
10 |
11 | - **Improved productivity:** Reduces context switching, allowing you to focus on your tasks.
12 | - **Interactive notes:** Embeds websites directly into notes, making them more engaging and interactive.
13 | - **Real-time updates:** Provides live updates from embedded websites.
14 | - **Enhanced aesthetics:** Brings life to websites by incorporating images, audio, and other elements.
15 |
16 | ## Usage cases
17 |
18 | Obsidian Open Gate transforms Obsidian into a more versatile workspace by embedding various web applications directly within. Here are 10 use cases:
19 |
20 | 1. **Calendar Management**: Embed your Google Calendar or other web-based calendars to stay organized and manage appointments directly in Obsidian.
21 | 2. **Collaborative Workspace**: Integrate Notion or other collaborative tools to work on shared projects and documents with colleagues or friends.
22 | 3. **Real-Time Document Editing**: Embed Google Docs or Microsoft Word Online to seamlessly edit documents and collaborate with others in real time.
23 | 4. **Interactive Learning**: Insert YouTube videos or other interactive web content to enhance your notes or learning materials.
24 | 5. **Project Management**: Embed Trello or Asana boards to manage tasks, track progress, and collaborate on projects.
25 | 6. **Financial Tracking**: Integrate Google Sheets or Excel Online to monitor financial data, create budgets, and track expenses.
26 | 7. **Interactive Whiteboarding**: Embed Miro or other online whiteboards for brainstorming, mind mapping, and collaborative idea generation.
27 | 8. **Content Curation**: Insert Pinterest or Pocket to collect and organize your favorite articles, images, or other online content.
28 | 9. **Research and Analysis**: Embed Google Scholar or JSTOR to access academic databases and research materials.
29 | 10. **Social Media Integration**: Connect with Twitter or LinkedIn to stay updated on industry trends or engage with professional networks.
30 |
31 | ## Why I created Open Gate?
32 |
33 | I created Open Gate because other plugins I tried were either too complicated or lacked features I needed. My goal was to simplify the user experience and include only essential functionalities. I use Open Gate daily and continuously update it to ensure it meets user needs effectively.
34 |
--------------------------------------------------------------------------------
/docs/public/logo-small.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenvanduocit/obsidian-open-gate/068f703988c911b845b7756a8543c48747978694/docs/public/logo-small.webp
--------------------------------------------------------------------------------
/docs/public/logo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenvanduocit/obsidian-open-gate/068f703988c911b845b7756a8543c48747978694/docs/public/logo.webp
--------------------------------------------------------------------------------
/docs/quick-switch.md:
--------------------------------------------------------------------------------
1 | # Quick switch
2 |
3 | You dont want every gates to show up in the left sidebar.
4 |
5 | You will turn off the "Ribbon" options of the gates. Then how to access them quickly? We have two ways to do that.
6 |
7 | ## Command Palette
8 |
9 | 1. Open the command palette (`Ctrl+P` on Windows/Linux, `Cmd+P` on macOS).
10 | 2. Type `Open gate` and you will see the list of gates.
11 | 3. Select the gate you want to open.
12 | 4. Press `Enter`.
13 |
14 | ## Hotkey
15 |
16 | By default, the hotkey to open the last gate is `Ctrl+Shift+G` on Windows/Linux, `Cmd+Shift+G` on macOS (You can change it in the settings.), a popup will show up with the list of gates. Click on the gate you want to open.
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/release.md:
--------------------------------------------------------------------------------
1 | # Hướng dẫn Release Phiên Bản Mới
2 |
3 | Tài liệu này hướng dẫn chi tiết quy trình release một phiên bản mới của plugin Open Gate. Vui lòng tuân thủ từng bước để đảm bảo process release diễn ra suôn sẻ.
4 |
5 | ## Các bước release
6 |
7 | ### 1. Cập nhật code và kiểm tra trạng thái
8 |
9 | ```bash
10 | # Fetch tất cả các thay đổi mới nhất từ repository
11 | git fetch --all
12 |
13 | # Kiểm tra trạng thái hiện tại của repository
14 | git status
15 | ```
16 |
17 | Đảm bảo working tree của bạn sạch sẽ (clean) trước khi bắt đầu quy trình release.
18 |
19 | ### 2. Kiểm tra phiên bản hiện tại
20 |
21 | ```bash
22 | # Xem các tag gần đây để xác định phiên bản hiện tại
23 | git tag -l --sort=-v:refname | head -5
24 | ```
25 |
26 | ### 3. Xem các commit gần đây
27 |
28 | ```bash
29 | # Xem 5 commit gần nhất để hiểu những thay đổi sẽ được bao gồm trong phiên bản mới
30 | git log -5 --pretty=format:"%h - %s (%cr)" | cat
31 | ```
32 |
33 | ### 4. Cập nhật phiên bản trong các file
34 |
35 | Cần cập nhật số phiên bản trong 3 file:
36 |
37 | 1. `manifest.json`
38 | 2. `package.json`
39 | 3. `versions.json`
40 |
41 | Ví dụ, để cập nhật từ phiên bản 1.11.8 lên 1.11.9:
42 |
43 | #### Cập nhật manifest.json
44 | ```json
45 | {
46 | "id": "open-gate",
47 | "name": "Open Gate",
48 | "version": "1.11.9", // Cập nhật phiên bản tại đây
49 | "minAppVersion": "0.15.0",
50 | // ...
51 | }
52 | ```
53 |
54 | #### Cập nhật package.json
55 | ```json
56 | {
57 | "name": "obsidian-open-gate",
58 | "version": "1.11.9", // Cập nhật phiên bản tại đây
59 | // ...
60 | }
61 | ```
62 |
63 | #### Cập nhật versions.json
64 | ```json
65 | {
66 | // ... các phiên bản trước ...
67 | "1.11.8": "0.15.0",
68 | "1.11.9": "0.15.0" // Thêm phiên bản mới và minAppVersion
69 | }
70 | ```
71 |
72 | ### 5. Commit các thay đổi
73 |
74 | ```bash
75 | # Add các file đã thay đổi
76 | git add manifest.json package.json versions.json
77 |
78 | # Commit với thông điệp mô tả rõ ràng
79 | git commit -m "chore: release version 1.11.9"
80 | ```
81 |
82 | ### 6. Tạo tag cho phiên bản mới
83 |
84 | ```bash
85 | # Tạo annotated tag với message
86 | git tag -a "1.11.9" -m "Release version 1.11.9"
87 |
88 | # Kiểm tra lại tag vừa tạo
89 | git tag -l --sort=-v:refname | head -3
90 | ```
91 |
92 | ### 7. Push commit và tag lên repository
93 |
94 | ```bash
95 | # Push commit lên nhánh chính (thường là main)
96 | git push
97 |
98 | # Push tag lên repository
99 | git push --tags
100 | ```
101 |
102 | ## Lưu ý
103 |
104 | - Luôn đảm bảo bạn đã test kỹ tất cả các tính năng trước khi thực hiện release
105 | - Tuân thủ quy tắc semantic versioning (SemVer):
106 | - MAJOR: thay đổi không tương thích với API cũ
107 | - MINOR: thêm tính năng mới nhưng vẫn tương thích ngược
108 | - PATCH: sửa lỗi, cải thiện hiệu suất mà không thay đổi API
109 | - Nếu có nhiều thay đổi lớn, cân nhắc cập nhật changelog trong README hoặc tạo file CHANGELOG.md
110 |
111 | ## Quy trình sau khi release
112 |
113 | Sau khi release thành công, bạn nên:
114 |
115 | 1. Kiểm tra repository trên GitHub để xác nhận tag mới đã xuất hiện
116 | 2. Xác minh rằng phiên bản mới được hiển thị trong Obsidian Community Plugins
117 | 3. Nếu có bất kỳ vấn đề nào, phản hồi nhanh chóng và cân nhắc việc release hotfix nếu cần thiết
--------------------------------------------------------------------------------
/esbuild.config.mjs:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild'
2 | import process from 'process'
3 | import builtins from 'builtin-modules'
4 |
5 | const banner = `/*
6 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
7 | if you want to view the source, please visit the github repository of this plugin
8 | */
9 | `
10 |
11 | const prod = process.argv[2] === 'production'
12 |
13 | esbuild
14 | .build({
15 | banner: {
16 | js: banner
17 | },
18 | entryPoints: ['src/main.ts'],
19 | bundle: true,
20 | external: [
21 | 'obsidian',
22 | 'electron',
23 | '@codemirror/autocomplete',
24 | '@codemirror/collab',
25 | '@codemirror/commands',
26 | '@codemirror/language',
27 | '@codemirror/lint',
28 | '@codemirror/search',
29 | '@codemirror/state',
30 | '@codemirror/view',
31 | '@lezer/common',
32 | '@lezer/highlight',
33 | '@lezer/lr',
34 | ...builtins
35 | ],
36 | format: 'cjs',
37 | watch: !prod,
38 | target: 'es2018',
39 | logLevel: 'info',
40 | sourcemap: prod ? false : 'inline',
41 | treeShaking: true,
42 | outfile: 'main.js'
43 | })
44 | .catch(() => process.exit(1))
45 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "open-gate",
3 | "name": "Open Gate",
4 | "version": "1.11.10",
5 | "minAppVersion": "0.15.0",
6 | "description": "Embed any website to Obsidian, you have anything you need in one place. You can browse website and take notes at the same time. e.g. Ask ChatGPT and copy the answer directly to your note.",
7 | "author": "duocnv",
8 | "authorUrl": "https://twitter.com/duocdev",
9 | "fundingUrl": {
10 | "Buy Me a Coffee": "https://paypal.me/duocnguyen",
11 | "Follow me": "https://twitter.com/duocdev"
12 | }
13 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "obsidian-open-gate",
3 | "version": "1.11.10",
4 | "description": "Embedding any website to Obsidian, from now all, you have anything you need in one place.",
5 | "main": "main.js",
6 | "scripts": {
7 | "dev": "node esbuild.config.mjs",
8 | "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
9 | "version": "node version-bump.mjs && git add manifest.json versions.json",
10 | "format": "prettier --write .",
11 | "docs:dev": "vitepress dev docs",
12 | "docs:build": "vitepress build docs",
13 | "docs:preview": "vitepress preview docs"
14 | },
15 | "keywords": [],
16 | "author": "",
17 | "license": "MIT",
18 | "devDependencies": {
19 | "@codemirror/view": "^6.35.0",
20 | "@types/chrome": "^0.0.203",
21 | "@types/node": "^16.18.121",
22 | "@typescript-eslint/eslint-plugin": "5.29.0",
23 | "@typescript-eslint/parser": "5.29.0",
24 | "builtin-modules": "3.3.0",
25 | "electron": "^23.3.13",
26 | "esbuild": "0.14.47",
27 | "obsidian": "latest",
28 | "prettier": "^2.8.8",
29 | "quicklink": "^2.3.0",
30 | "tslib": "2.4.0",
31 | "typescript": "4.7.4",
32 | "vitepress": "^1.5.0"
33 | },
34 | "dependencies": {
35 | "yaml": "^2.6.1"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/GateOptions.d.ts:
--------------------------------------------------------------------------------
1 | export type GateFrameOptionType = 'left' | 'center' | 'right'
2 |
3 | export type GateFrameOption = {
4 | id: string
5 | icon: string // SVG code or icon id from lucide.dev
6 | title: string // Gate frame title
7 | url: string // Gate frame URL
8 | profileKey?: string // Similar to a Chrome profile
9 | hasRibbon?: boolean // If true, icon appears in the left sidebar
10 | position?: GateFrameOptionType // 'left', 'center', or 'right'
11 | userAgent?: string // User agent for the gate frame
12 | zoomFactor?: number // Zoom factor (0.5 = 50%, 1.0 = 100%, 2.0 = 200%, etc.)
13 | css?: string // Custom CSS for the gate frame
14 | js?: string // Custom JavaScript for the gate frame
15 | }
16 |
--------------------------------------------------------------------------------
/src/GateView.ts:
--------------------------------------------------------------------------------
1 | import { ItemView, WorkspaceLeaf, Menu } from 'obsidian'
2 | import { createWebviewTag } from './fns/createWebviewTag'
3 | import { Platform } from 'obsidian'
4 | import { createIframe } from './fns/createIframe'
5 | import { clipboard } from 'electron'
6 | import WebviewTag = Electron.WebviewTag
7 | import { GateFrameOption } from './GateOptions'
8 | import { callbackify } from 'util'
9 |
10 | export class GateView extends ItemView {
11 | private readonly options: GateFrameOption
12 | private frame: WebviewTag | HTMLIFrameElement
13 | private readonly useIframe: boolean = false
14 | private frameReadyCallbacks: Function[]
15 | private isFrameReady: boolean = false
16 | private frameDoc: Document
17 |
18 | constructor(leaf: WorkspaceLeaf, options: GateFrameOption) {
19 | super(leaf)
20 | this.navigation = false
21 | this.options = options
22 | this.useIframe = Platform.isMobileApp
23 | this.frameReadyCallbacks = []
24 | }
25 |
26 | addActions(): void {
27 | this.addAction('refresh-ccw', 'Reload', () => {
28 | if (this.frame instanceof HTMLIFrameElement) {
29 | this.frame.contentWindow?.location.reload()
30 | } else {
31 | this.frame.reload()
32 | }
33 | })
34 |
35 | this.addAction('home', 'Home page', () => {
36 | if (this.frame instanceof HTMLIFrameElement) {
37 | this.frame.src = this.options?.url ?? 'about:blank'
38 | } else {
39 | this.frame.loadURL(this.options?.url ?? 'about:blank')
40 | }
41 | })
42 | }
43 |
44 | isWebviewFrame(): boolean {
45 | return this.frame! instanceof HTMLIFrameElement
46 | }
47 |
48 | onload(): void {
49 | super.onload()
50 | this.addActions()
51 |
52 | this.contentEl.empty()
53 | this.contentEl.addClass('open-gate-view')
54 |
55 | this.frameDoc = this.contentEl.doc
56 | this.createFrame()
57 | }
58 |
59 | private createFrame(): void {
60 | const onReady = () => {
61 | if(!this.isFrameReady){
62 | this.isFrameReady = true
63 | this.frameReadyCallbacks.forEach((callback) => callback())
64 | }
65 | }
66 |
67 | if(this.useIframe){
68 | this.frame = createIframe(this.options, onReady)
69 | }else{
70 | this.frame = createWebviewTag(this.options, onReady, this.frameDoc)
71 |
72 | this.frame.addEventListener('destroyed', () => {
73 |
74 | if(this.frameDoc != this.contentEl.doc){
75 | if(this.frame){
76 | this.frame.remove()
77 | }
78 | this.frameDoc = this.contentEl.doc
79 | this.createFrame()
80 | }
81 | })
82 | }
83 |
84 | this.contentEl.appendChild(this.frame as unknown as HTMLElement)
85 | }
86 |
87 |
88 |
89 | onunload(): void {
90 |
91 | if(this.frame){
92 | this.frame.remove()
93 | }
94 | super.onunload()
95 |
96 | }
97 |
98 | onPaneMenu(menu: Menu, source: string): void {
99 | super.onPaneMenu(menu, source)
100 | menu.addItem((item) => {
101 | item.setTitle('Reload')
102 | item.setIcon('refresh-ccw')
103 | item.onClick(() => {
104 | if (this.frame instanceof HTMLIFrameElement) {
105 | this.frame.contentWindow?.location.reload()
106 | } else {
107 | this.frame.reload()
108 | }
109 | })
110 | })
111 | menu.addItem((item) => {
112 | item.setTitle('Home page')
113 | item.setIcon('home')
114 | item.onClick(async () => {
115 | if (this.frame instanceof HTMLIFrameElement) {
116 | this.frame.src = this.options?.url ?? 'about:blank'
117 | } else {
118 | await this.frame.loadURL(this.options?.url ?? 'about:blank')
119 | }
120 | })
121 | })
122 | menu.addItem((item) => {
123 | item.setTitle('Toggle DevTools')
124 | item.setIcon('file-cog')
125 | item.onClick(() => {
126 | if (this.frame instanceof HTMLIFrameElement) {
127 | return
128 | }
129 |
130 | if (this.frame.isDevToolsOpened()) {
131 | this.frame.closeDevTools()
132 | } else {
133 | this.frame.openDevTools()
134 | }
135 | })
136 | })
137 |
138 | menu.addItem((item) => {
139 | item.setTitle('Copy Page URL')
140 | item.setIcon('clipboard-copy')
141 | item.onClick(() => {
142 | if (this.frame instanceof HTMLIFrameElement) {
143 | clipboard.writeText(this.frame.src)
144 | return
145 | }
146 |
147 | clipboard.writeText(this.frame.getURL())
148 | })
149 | })
150 |
151 | // Open in Default Browser
152 | menu.addItem((item) => {
153 | item.setTitle('Open in browser')
154 | item.setIcon('globe')
155 | item.onClick(() => {
156 | if (this.frame instanceof HTMLIFrameElement) {
157 | window.open(this.frame.src)
158 | return
159 | }
160 |
161 | window.open(this.frame.getURL())
162 | })
163 | })
164 | }
165 |
166 | getViewType(): string {
167 | return this.options?.id ?? 'gate'
168 | }
169 |
170 | getDisplayText(): string {
171 | return this.options?.title ?? 'Gate'
172 | }
173 |
174 | getIcon(): string {
175 | if (this.options?.icon.startsWith('