diff --git a/src/component/searchBox.ts b/src/component/searchBox.ts new file mode 100644 index 0000000..6d128d4 --- /dev/null +++ b/src/component/searchBox.ts @@ -0,0 +1,122 @@ +import { setIcon, WorkspaceLeaf } from "obsidian"; +import AnotherWebBrowserPlugin from "../anotherWebBrowserIndex"; + +export class searchBox { + plugin: AnotherWebBrowserPlugin; + leaf: WorkspaceLeaf; + webContents: any; + closeButtonEl: HTMLElement; + backwardButtonEl: HTMLElement; + forwardButtonEl: HTMLElement; + inputEl: HTMLInputElement; + searchBoxEl: HTMLElement; + clicked: boolean; + + constructor(leaf: WorkspaceLeaf, webContents: any, plugin: AnotherWebBrowserPlugin) { + this.leaf = leaf; + this.webContents = webContents; + this.plugin = plugin; + + this.onload(); + } + + onload() { + const containerEl = this.leaf.view.contentEl; + this.searchBoxEl = containerEl.createEl("div", { + cls: "web-browser-search-box" + }); + this.inputEl = this.searchBoxEl.createEl("input", { + type: "text", + placeholder: "", + cls: "web-browser-search-input" + }); + const searchButtonGroupEl = this.searchBoxEl.createEl("div", { + cls: "web-browser-search-button-group" + }); + this.backwardButtonEl = searchButtonGroupEl.createEl("div", { + cls: "web-browser-search-button search-forward" + }); + this.forwardButtonEl = searchButtonGroupEl.createEl("div", { + cls: "web-browser-search-button search-backward" + }); + this.closeButtonEl = searchButtonGroupEl.createEl("div", { + cls: "web-browser-search-button search-close" + }); + + this.closeButtonEl.addEventListener("click", this.unload.bind(this)); + this.backwardButtonEl.addEventListener("click", this.backward.bind(this)); + this.forwardButtonEl.addEventListener("click", this.forward.bind(this)); + this.inputEl.addEventListener("keyup", this.search.bind(this)) + this.inputEl.addEventListener("keyup", this.exist.bind(this)) + + setIcon(this.closeButtonEl, "x", 8); + setIcon(this.backwardButtonEl, "arrow-up", 8); + setIcon(this.forwardButtonEl, "arrow-down", 8); + + this.inputEl.focus(); + } + + search(event: KeyboardEvent) { + event.preventDefault(); + if (this.inputEl.value === "") return; + + if (event.key === "Enter" && !event.shiftKey) { + this.forward(); + } + if (event.key === "Enter" && event.shiftKey) { + this.backward(); + } + } + + exist(event: KeyboardEvent) { + event.preventDefault(); + if (event.key === "Esc") { + this.unload(); + } + } + + backward() { + if (this.inputEl.value === "") return; + + if (!this.clicked) { + this.webContents.findInPage(this.inputEl.value, { + forward: false, + findNext: true + }); + } else { + this.webContents.findInPage(this.inputEl.value, { + forward: false, + findNext: false + }); + } + this.clicked = true; + } + + forward() { + if (this.inputEl.value === "") return; + if (!this.clicked) { + this.webContents.findInPage(this.inputEl.value, { + forward: true, + findNext: true + }); + } else { + this.webContents.findInPage(this.inputEl.value, { + forward: true, + findNext: false + }); + } + this.clicked = true; + } + + unload() { + this.webContents.stopFindInPage('clearSelection') + + this.closeButtonEl.removeEventListener("click", this.unload); + this.backwardButtonEl.removeEventListener("click", this.backward); + this.forwardButtonEl.removeEventListener("click", this.forward); + this.inputEl.removeEventListener('keyup', this.search); + this.inputEl.removeEventListener('keyup', this.exist); + + this.searchBoxEl.detach(); + } +} diff --git a/src/types/obsidian.d.ts b/src/types/obsidian.d.ts index d9477c8..207a150 100644 --- a/src/types/obsidian.d.ts +++ b/src/types/obsidian.d.ts @@ -25,6 +25,11 @@ declare module "obsidian" { tabHeaderInnerTitleEl: HTMLDivElement activeTime: number rebuildView: () => void; + + } + + export interface View { + contentEl: HTMLElement, } export interface MenuItem { diff --git a/src/web_browser_view.ts b/src/web_browser_view.ts index a8d9024..f574cde 100644 --- a/src/web_browser_view.ts +++ b/src/web_browser_view.ts @@ -6,11 +6,13 @@ import { FunctionHooks } from "./hooks"; import AnotherWebBrowserPlugin, { SEARCH_ENGINES } from "./anotherWebBrowserIndex"; import { moment } from "obsidian"; import { t } from "./translations/helper"; +import { searchBox } from "./component/searchBox"; export const WEB_BROWSER_VIEW_ID = "another-web-browser-view"; export class WebBrowserView extends ItemView { plugin: AnotherWebBrowserPlugin; + searchBox: searchBox; private currentUrl: string; private currentTitle = "New tab"; @@ -165,7 +167,6 @@ export class WebBrowserView extends ItemView { console.error('Failed to get background color: ', err); } - webContents.on("context-menu", (event: any, params: any) => { event.preventDefault(); @@ -280,6 +281,10 @@ export class WebBrowserView extends ItemView { }, 0) }, 10, true) + // webContents.on('found-in-page', (event: any, result: any) => { + // if (result.finalUpdate) webContents.stopFindInPage('clearSelection') + // }) + // For getting keyboard event from webview webContents.on('before-input-event', (event: any, input: any) => { if (input.type !== 'keyDown') { @@ -301,6 +306,10 @@ export class WebBrowserView extends ItemView { // If so, prevent default and execute the hotkey // If not, send the event to the webview activeDocument.body.dispatchEvent(emulatedKeyboardEvent); + + if (emulatedKeyboardEvent.ctrlKey && emulatedKeyboardEvent.key === 'f') { + this.searchBox = new searchBox(this.leaf, webContents, this.plugin); + } }); // TODO: Do we need to show a link that cursor hovering? @@ -413,6 +422,7 @@ export class WebBrowserView extends ItemView { if (updateWebView) { this.frame.setAttribute("src", url); } + this.searchBox?.unload(); app.workspace.requestSaveLayout(); } diff --git a/styles.css b/styles.css index cd1dcb3..77f7ebd 100644 --- a/styles.css +++ b/styles.css @@ -1,20 +1,57 @@ .web-browser-view-content { - padding: 0 !important; - overflow: hidden !important; + padding: 0 !important; + overflow: hidden !important; } .web-browser-frame { - width: 100%; - height: 100%; - border: none; - background-color: white; - background-clip: content-box; + width: 100%; + height: 100%; + border: none; + background-color: white; + background-clip: content-box; } .web-browser-header-bar::after { - background: transparent !important; + background: transparent !important; } .web-browser-search-bar { - width: 100%; + width: 100%; +} + +.web-browser-search-box { + display: flex; + flex-direction: row; + position: absolute; + z-index: 20; + top: 35px; + right: 200px; + width: 200px; + height: 44px; + background-color: var(--color-base-20); + padding: 7px; + border: var(--input-border-width) solid var(--background-modifier-border); +} + +.web-browser-search-input { + width: 60%; + height: 100%; +} + +.web-browser-search-button-group { + width: 40%; + height: 100%; + display: flex; + flex-direction: row; +} + +.web-browser-search-button { + display: flex; + align-items: center; + + width: 100%; + height: var(--input-height); + border: var(--input-border-width) solid var(--background-modifier-border); + background-color: var(--background-modifier-form-field); + margin-left: 4px; }