From 5ef0c88470940687de88e822b16f581eaf4f2530 Mon Sep 17 00:00:00 2001 From: BCS <120721474+BCS1037@users.noreply.github.com> Date: Wed, 13 May 2026 17:17:20 +0800 Subject: [PATCH] chore(release): v0.0.5 --- .github/workflows/release.yml | 47 +++++++++++++++++++++++++++++++++++ CHANGELOG.md | 12 +++++++++ main.js | 4 +-- manifest.json | 4 +-- package.json | 2 +- src/BookmarkPanel.ts | 2 +- src/BrowserPanel.ts | 41 ++++++++++++++---------------- src/main.ts | 10 ++++---- src/settings.ts | 2 -- versions.json | 3 ++- 10 files changed, 91 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f28e1f1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,47 @@ +name: Release Obsidian plugin + +on: + push: + tags: + - "*" + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + attestations: write + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Build plugin + run: | + npm install + npm run build + + - name: Attest main.js + uses: actions/attest-build-provenance@v2 + with: + subject-path: main.js + + - name: Attest styles.css + uses: actions/attest-build-provenance@v2 + with: + subject-path: styles.css + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: | + main.js + manifest.json + styles.css + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ce703e..25fa2c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. +## [0.0.5] - 2026-05-13 + +### Fixed +- **Submission Compliance**: Addressed multiple warnings and errors flagged by the Obsidian community review process. +- Updated `minAppVersion` to `1.7.2` to support `Workspace.revealLeaf`. +- Fixed popout window compatibility by migrating `document` to `activeDocument` and `window` to `activeWindow`. +- Improved type safety across files by removing `any` usage in `src/BookmarkPanel.ts` and `src/BrowserPanel.ts`. +- Removed "General" heading from the settings tab. +- Replaced `document.createElement('webview')` with `createEl('webview')` for proper initialization. +- Re-named the command palette entry to "Open" to prevent redundant prefixing. +- Added a GitHub Actions workflow to generate artifact attestations for `main.js` and `styles.css`. + ## [0.0.4] - 2026-04-21 ### Fixed diff --git a/main.js b/main.js index 2042865..d721159 100644 --- a/main.js +++ b/main.js @@ -3,5 +3,5 @@ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ -var C=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var O=(a,e)=>{for(var t in e)C(a,t,{get:e[t],enumerable:!0})},A=(a,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of M(e))!_.call(a,o)&&o!==t&&C(a,o,{get:()=>e[o],enumerable:!(r=F(e,o))||r.enumerable});return a};var N=a=>A(C({},"__esModule",{value:!0}),a);var U={};O(U,{default:()=>T});module.exports=N(U);var S=require("obsidian");var L={bookmarks:[],folders:[],defaultUrl:"https://www.google.com",showBookmarkPanel:!0,interceptLinks:!1},c="side-bookmark-view";function x(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}var f=class{constructor(e){this.listeners=[];this.plugin=e,this.data={...L}}async load(){let e=await this.plugin.loadData();e&&(this.data={...L,...e})}async save(){await this.plugin.saveData(this.data)}onChange(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}notify(){for(let e of this.listeners)e()}get defaultUrl(){return this.data.defaultUrl}set defaultUrl(e){this.data.defaultUrl=e}get showBookmarkPanel(){return this.data.showBookmarkPanel}set showBookmarkPanel(e){this.data.showBookmarkPanel=e}get interceptLinks(){return this.data.interceptLinks}set interceptLinks(e){this.data.interceptLinks=e}get bookmarks(){return this.data.bookmarks}get folders(){return this.data.folders}async addBookmark(e,t,r=null){let o=this.data.bookmarks.filter(l=>l.folderId===r),s=o.length>0?Math.max(...o.map(l=>l.order)):-1,i={id:x(),type:"bookmark",title:e,url:t,folderId:r,order:s+1};return this.data.bookmarks.push(i),await this.save(),this.notify(),i}async removeBookmark(e){this.data.bookmarks=this.data.bookmarks.filter(t=>t.id!==e),await this.save(),this.notify()}async updateBookmark(e,t){let r=this.data.bookmarks.find(o=>o.id===e);r&&(Object.assign(r,t),await this.save(),this.notify())}async moveBookmark(e,t){await this.updateBookmark(e,{folderId:t})}async addFolder(e,t=null){let r=this.data.folders.filter(i=>i.parentId===t),o=r.length>0?Math.max(...r.map(i=>i.order)):-1,s={id:x(),type:"folder",name:e,parentId:t,collapsed:!1,order:o+1};return this.data.folders.push(s),await this.save(),this.notify(),s}async removeFolder(e){let t=this.getDescendantFolderIds(e),r=[e,...t];this.data.bookmarks=this.data.bookmarks.filter(o=>{var s;return!r.includes((s=o.folderId)!=null?s:"")}),this.data.folders=this.data.folders.filter(o=>!r.includes(o.id)),await this.save(),this.notify()}async updateFolder(e,t){let r=this.data.folders.find(o=>o.id===e);r&&(Object.assign(r,t),await this.save(),this.notify())}async toggleFolder(e){let t=this.data.folders.find(r=>r.id===e);t&&(t.collapsed=!t.collapsed,await this.save(),this.notify())}getBookmarksByFolder(e){return this.data.bookmarks.filter(t=>t.folderId===e).sort((t,r)=>t.order-r.order)}getSubFolders(e){return this.data.folders.filter(t=>t.parentId===e).sort((t,r)=>t.order-r.order)}getFolder(e){return this.data.folders.find(t=>t.id===e)}getBookmark(e){return this.data.bookmarks.find(t=>t.id===e)}getTreeItems(e){let t=this.getSubFolders(e),r=this.getBookmarksByFolder(e);return[...t,...r].sort((s,i)=>s.order-i.order)}hasBookmarkWithUrl(e){return this.data.bookmarks.some(t=>t.url===e)}getDescendantFolderIds(e){let t=this.data.folders.filter(o=>o.parentId===e),r=[];for(let o of t)r.push(o.id),r.push(...this.getDescendantFolderIds(o.id));return r}};var D=require("obsidian");var u=require("obsidian"),w=class{constructor(e){this.webviewEl=null;this.currentUrl="";this.currentTitle="";this.onAddBookmark=null;this.containerEl=e.createDiv({cls:"sb-browser-panel"}),this.navBarEl=this.containerEl.createDiv({cls:"sb-nav-bar"});let t=this.navBarEl.createDiv({cls:"sb-nav-buttons"});this.backBtn=t.createDiv({cls:"sb-nav-btn",attr:{"aria-label":"\u540E\u9000"}}),(0,u.setIcon)(this.backBtn,"arrow-left"),this.backBtn.addEventListener("click",()=>this.goBack()),this.forwardBtn=t.createDiv({cls:"sb-nav-btn",attr:{"aria-label":"\u524D\u8FDB"}}),(0,u.setIcon)(this.forwardBtn,"arrow-right"),this.forwardBtn.addEventListener("click",()=>this.goForward()),this.refreshBtn=t.createDiv({cls:"sb-nav-btn",attr:{"aria-label":"\u5237\u65B0"}}),(0,u.setIcon)(this.refreshBtn,"refresh-cw"),this.refreshBtn.addEventListener("click",()=>this.reload()),this.urlInput=this.navBarEl.createEl("input",{cls:"sb-url-input",attr:{type:"text",placeholder:"\u8F93\u5165\u7F51\u5740...",spellcheck:"false"}}),this.urlInput.addEventListener("keydown",r=>{r.key==="Enter"&&this.navigateToInput()}),this.urlInput.addEventListener("focus",()=>{this.urlInput.select()}),this.bookmarkBtn=this.navBarEl.createDiv({cls:"sb-nav-btn sb-bookmark-btn",attr:{"aria-label":"\u6DFB\u52A0\u4E66\u7B7E"}}),(0,u.setIcon)(this.bookmarkBtn,"star"),this.bookmarkBtn.addEventListener("click",()=>{this.onAddBookmark&&this.currentUrl&&this.onAddBookmark(this.currentTitle||this.currentUrl,this.currentUrl)}),this.webviewContainer=this.containerEl.createDiv({cls:"sb-webview-container"})}navigate(e){let t=e.trim();t&&(/^https?:\/\//i.test(t)||(t="https://"+t),this.currentUrl=t,this.urlInput.value=t,this.createOrUpdateWebview(t))}goBack(){if(this.webviewEl){let e=this.webviewEl;typeof e.goBack=="function"&&e.goBack()}}goForward(){if(this.webviewEl){let e=this.webviewEl;typeof e.goForward=="function"&&e.goForward()}}reload(){if(this.webviewEl){let e=this.webviewEl;typeof e.reload=="function"&&e.reload()}}getUrl(){return this.currentUrl}getTitle(){return this.currentTitle}destroy(){this.webviewEl&&(this.webviewEl.remove(),this.webviewEl=null),this.containerEl.remove()}navigateToInput(){let e=this.urlInput.value.trim();e&&this.navigate(e)}createOrUpdateWebview(e){this.webviewEl&&this.webviewEl.remove();let t=document.createElement("webview");t.setAttribute("src",e),t.setAttribute("allowpopups",""),t.addClass("sb-webview"),t.addEventListener("did-navigate",r=>{let o=r;typeof o.url=="string"&&(this.currentUrl=o.url,this.urlInput.value=o.url)}),t.addEventListener("did-navigate-in-page",r=>{let o=r;typeof o.url=="string"&&(this.currentUrl=o.url,this.urlInput.value=o.url)}),t.addEventListener("page-title-updated",r=>{let o=r;typeof o.title=="string"&&(this.currentTitle=o.title)}),t.addEventListener("dom-ready",()=>{let r=t;typeof r.getURL=="function"&&(this.currentUrl=r.getURL(),this.urlInput.value=this.currentUrl),typeof r.getTitle=="function"&&(this.currentTitle=r.getTitle())}),t.addEventListener("new-window",r=>{let o=r;typeof o.url=="string"&&this.navigate(o.url)}),this.webviewContainer.empty(),this.webviewContainer.appendChild(t),this.webviewEl=t}};var d=require("obsidian");var n=require("obsidian"),k=class extends n.Modal{constructor(e,t,r="",o="",s=null,i){super(e),this.store=t,this.title=r,this.url=o,this.folderId=s,this.onSave=i!=null?i:null}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"\u6DFB\u52A0\u4E66\u7B7E"}),new n.Setting(e).setName("\u6807\u9898").addText(t=>t.setPlaceholder("\u8F93\u5165\u4E66\u7B7E\u6807\u9898").setValue(this.title).onChange(r=>{this.title=r})),new n.Setting(e).setName("\u7F51\u5740").addText(t=>t.setPlaceholder("https://example.com").setValue(this.url).onChange(r=>{this.url=r})),new n.Setting(e).setName("\u6587\u4EF6\u5939").addDropdown(t=>{var r;t.addOption("__root__","\uFF08\u65E0\u6587\u4EF6\u5939\uFF09");for(let o of this.store.folders)t.addOption(o.id,this.getFolderPath(o));t.setValue((r=this.folderId)!=null?r:"__root__"),t.onChange(o=>{this.folderId=o==="__root__"?null:o})}),new n.Setting(e).addButton(t=>t.setButtonText("\u4FDD\u5B58").setCta().onClick(async()=>{if(!this.url.trim())return;this.title.trim()||(this.title=this.url);let r=this.url.trim();/^https?:\/\//i.test(r)||(r="https://"+r),this.onSave?this.onSave(this.title.trim(),r,this.folderId):await this.store.addBookmark(this.title.trim(),r,this.folderId),this.close()})).addButton(t=>t.setButtonText("\u53D6\u6D88").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}getFolderPath(e){let t=[e.name],r=e;for(;r!=null&&r.parentId;)r=this.store.getFolder(r.parentId),r&&t.unshift(r.name);return t.join(" / ")}},b=class extends n.Modal{constructor(e,t,r,o,s,i){super(e),this.store=t,this.bookmarkId=r,this.title=o,this.url=s,this.folderId=i}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"\u7F16\u8F91\u4E66\u7B7E"}),new n.Setting(e).setName("\u6807\u9898").addText(t=>t.setPlaceholder("\u8F93\u5165\u4E66\u7B7E\u6807\u9898").setValue(this.title).onChange(r=>{this.title=r})),new n.Setting(e).setName("\u7F51\u5740").addText(t=>t.setPlaceholder("https://example.com").setValue(this.url).onChange(r=>{this.url=r})),new n.Setting(e).setName("\u6587\u4EF6\u5939").addDropdown(t=>{var r;t.addOption("__root__","\uFF08\u65E0\u6587\u4EF6\u5939\uFF09");for(let o of this.store.folders)t.addOption(o.id,this.getFolderPath(o));t.setValue((r=this.folderId)!=null?r:"__root__"),t.onChange(o=>{this.folderId=o==="__root__"?null:o})}),new n.Setting(e).addButton(t=>t.setButtonText("\u4FDD\u5B58").setCta().onClick(async()=>{if(!this.url.trim())return;this.title.trim()||(this.title=this.url);let r=this.url.trim();/^https?:\/\//i.test(r)||(r="https://"+r),await this.store.updateBookmark(this.bookmarkId,{title:this.title.trim(),url:r,folderId:this.folderId}),this.close()})).addButton(t=>t.setButtonText("\u53D6\u6D88").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}getFolderPath(e){let t=[e.name],r=e;for(;r!=null&&r.parentId;)r=this.store.getFolder(r.parentId),r&&t.unshift(r.name);return t.join(" / ")}},v=class extends n.Modal{constructor(e,t,r=null){super(e),this.store=t,this.folderName="",this.parentId=r}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"\u65B0\u5EFA\u6587\u4EF6\u5939"}),new n.Setting(e).setName("\u6587\u4EF6\u5939\u540D\u79F0").addText(t=>t.setPlaceholder("\u8F93\u5165\u6587\u4EF6\u5939\u540D\u79F0").setValue(this.folderName).onChange(r=>{this.folderName=r})),new n.Setting(e).setName("\u7236\u6587\u4EF6\u5939").addDropdown(t=>{var r;t.addOption("__root__","\uFF08\u6839\u7EA7\u522B\uFF09");for(let o of this.store.folders)t.addOption(o.id,this.getFolderPath(o));t.setValue((r=this.parentId)!=null?r:"__root__"),t.onChange(o=>{this.parentId=o==="__root__"?null:o})}),new n.Setting(e).addButton(t=>t.setButtonText("\u521B\u5EFA").setCta().onClick(async()=>{this.folderName.trim()&&(await this.store.addFolder(this.folderName.trim(),this.parentId),this.close())})).addButton(t=>t.setButtonText("\u53D6\u6D88").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}getFolderPath(e){let t=[e.name],r=e;for(;r!=null&&r.parentId;)r=this.store.getFolder(r.parentId),r&&t.unshift(r.name);return t.join(" / ")}},B=class extends n.Modal{constructor(e,t,r,o){super(e),this.store=t,this.folderId=r,this.folderName=o}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"\u7F16\u8F91\u6587\u4EF6\u5939"}),new n.Setting(e).setName("\u6587\u4EF6\u5939\u540D\u79F0").addText(t=>t.setPlaceholder("\u8F93\u5165\u6587\u4EF6\u5939\u540D\u79F0").setValue(this.folderName).onChange(r=>{this.folderName=r})),new n.Setting(e).addButton(t=>t.setButtonText("\u4FDD\u5B58").setCta().onClick(async()=>{this.folderName.trim()&&(await this.store.updateFolder(this.folderId,{name:this.folderName.trim()}),this.close())})).addButton(t=>t.setButtonText("\u53D6\u6D88").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}},g=class extends n.Modal{constructor(e,t,r){super(e),this.message=t,this.onConfirm=r}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"\u786E\u8BA4\u5220\u9664"}),e.createEl("p",{text:this.message}),new n.Setting(e).addButton(t=>t.setButtonText("\u5220\u9664").setWarning().onClick(async()=>{await this.onConfirm(),this.close()})).addButton(t=>t.setButtonText("\u53D6\u6D88").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}};var E=class{constructor(e,t,r){this.collapsed=!1;this.unsubscribe=null;this.onNavigate=null;this.app=e,this.store=r,this.containerEl=t.createDiv({cls:"sb-bookmark-panel"}),this.headerEl=this.containerEl.createDiv({cls:"sb-bookmark-header"});let o=this.headerEl.createDiv({cls:"sb-bookmark-header-left"}),s=o.createDiv({cls:"sb-collapse-icon"});(0,d.setIcon)(s,"chevron-down"),o.createSpan({text:"\u4E66\u7B7E",cls:"sb-bookmark-title"}),o.addEventListener("click",()=>{this.toggleCollapse()});let l=this.headerEl.createDiv({cls:"sb-bookmark-header-right"}).createDiv({cls:"sb-add-btn-group"}),m=l.createDiv({cls:"sb-header-btn",attr:{"aria-label":"\u6DFB\u52A0\u4E66\u7B7E"}});(0,d.setIcon)(m,"plus"),m.addEventListener("click",P=>{P.stopPropagation(),new k(this.app,this.store).open()});let h=l.createDiv({cls:"sb-header-btn",attr:{"aria-label":"\u65B0\u5EFA\u6587\u4EF6\u5939"}});(0,d.setIcon)(h,"folder-plus"),h.addEventListener("click",P=>{P.stopPropagation(),new v(this.app,this.store).open()}),this.listEl=this.containerEl.createDiv({cls:"sb-bookmark-list"}),this.unsubscribe=this.store.onChange(()=>{this.renderList()}),this.renderList()}toggleCollapse(){this.collapsed=!this.collapsed,this.containerEl.toggleClass("sb-collapsed",this.collapsed);let e=this.headerEl.querySelector(".sb-collapse-icon");e&&(e.empty(),(0,d.setIcon)(e,this.collapsed?"chevron-right":"chevron-down"))}destroy(){this.unsubscribe&&this.unsubscribe(),this.containerEl.remove()}renderList(){if(this.listEl.empty(),this.store.getTreeItems(null).length===0){let t=this.listEl.createDiv({cls:"sb-empty-state"}),r=t.createDiv({cls:"sb-empty-icon"});(0,d.setIcon)(r,"bookmark"),t.createDiv({text:"\u6682\u65E0\u4E66\u7B7E",cls:"sb-empty-text"}),t.createDiv({text:"\u70B9\u51FB + \u6309\u94AE\u6216 \u2B50 \u6309\u94AE\u6DFB\u52A0\u4E66\u7B7E",cls:"sb-empty-hint"});return}this.renderTreeLevel(this.listEl,null,0)}renderTreeLevel(e,t,r){let o=this.store.getTreeItems(t);for(let s of o)s.type==="folder"?this.renderFolder(e,s,r):this.renderBookmark(e,s,r)}renderFolder(e,t,r){let o=e.createDiv({cls:"sb-tree-item sb-folder-item",attr:{"data-id":t.id,"data-type":"folder",draggable:"true"}});o.style.paddingLeft=`${r*16+4}px`;let s=o.createDiv({cls:"sb-tree-item-row"}),i=s.createDiv({cls:"sb-folder-collapse"});(0,d.setIcon)(i,t.collapsed?"chevron-right":"chevron-down");let l=s.createDiv({cls:"sb-item-icon"});(0,d.setIcon)(l,t.collapsed?"folder":"folder-open"),s.createSpan({text:t.name,cls:"sb-item-label"});let m=this.store.getBookmarksByFolder(t.id).length+this.store.getSubFolders(t.id).length;if(m>0&&s.createSpan({text:`${m}`,cls:"sb-count-badge"}),s.addEventListener("click",()=>{this.store.toggleFolder(t.id)}),s.addEventListener("contextmenu",h=>{h.preventDefault(),h.stopPropagation(),this.showFolderContextMenu(h,t)}),this.setupDragEvents(o,t),!t.collapsed){let h=e.createDiv({cls:"sb-folder-children"});this.renderTreeLevel(h,t.id,r+1)}}renderBookmark(e,t,r){let o=e.createDiv({cls:"sb-tree-item sb-bookmark-item",attr:{"data-id":t.id,"data-type":"bookmark",draggable:"true"}});o.style.paddingLeft=`${r*16+24}px`;let s=o.createDiv({cls:"sb-tree-item-row"}),i=s.createDiv({cls:"sb-item-icon"});(0,d.setIcon)(i,"globe"),s.createSpan({text:t.title,cls:"sb-item-label"}),s.addEventListener("click",()=>{this.onNavigate&&this.onNavigate(t.url)}),s.addEventListener("contextmenu",l=>{l.preventDefault(),l.stopPropagation(),this.showBookmarkContextMenu(l,t)}),this.setupDragEvents(o,t)}showBookmarkContextMenu(e,t){let r=new d.Menu;r.addItem(o=>{o.setTitle("\u6253\u5F00"),o.setIcon("external-link"),o.onClick(()=>{this.onNavigate&&this.onNavigate(t.url)})}),r.addSeparator(),r.addItem(o=>{o.setTitle("\u7F16\u8F91"),o.setIcon("pencil"),o.onClick(()=>{new b(this.app,this.store,t.id,t.title,t.url,t.folderId).open()})}),r.addItem(o=>{o.setTitle("\u79FB\u52A8\u5230..."),o.setIcon("folder-input"),o.onClick(()=>{this.showMoveMenu(e,t)})}),r.addSeparator(),r.addItem(o=>{o.setTitle("\u5220\u9664"),o.setIcon("trash-2"),o.onClick(()=>{new g(this.app,`\u786E\u5B9A\u8981\u5220\u9664\u4E66\u7B7E"${t.title}"\u5417\uFF1F`,async()=>{await this.store.removeBookmark(t.id)}).open()})}),r.showAtMouseEvent(e)}showFolderContextMenu(e,t){let r=new d.Menu;r.addItem(o=>{o.setTitle("\u6DFB\u52A0\u4E66\u7B7E\u5230\u6B64\u6587\u4EF6\u5939"),o.setIcon("plus"),o.onClick(()=>{new k(this.app,this.store,"","",t.id).open()})}),r.addItem(o=>{o.setTitle("\u6DFB\u52A0\u5B50\u6587\u4EF6\u5939"),o.setIcon("folder-plus"),o.onClick(()=>{new v(this.app,this.store,t.id).open()})}),r.addSeparator(),r.addItem(o=>{o.setTitle("\u91CD\u547D\u540D"),o.setIcon("pencil"),o.onClick(()=>{new B(this.app,this.store,t.id,t.name).open()})}),r.addSeparator(),r.addItem(o=>{o.setTitle("\u5220\u9664\u6587\u4EF6\u5939"),o.setIcon("trash-2"),o.onClick(()=>{let s=this.store.getBookmarksByFolder(t.id).length,i=this.store.getSubFolders(t.id).length,l=`\u786E\u5B9A\u8981\u5220\u9664\u6587\u4EF6\u5939"${t.name}"\u5417\uFF1F`;(s>0||i>0)&&(l+=` -\u5176\u4E2D\u5305\u542B ${s} \u4E2A\u4E66\u7B7E\u548C ${i} \u4E2A\u5B50\u6587\u4EF6\u5939\uFF0C\u5C06\u4E00\u5E76\u5220\u9664\u3002`),new g(this.app,l,async()=>{await this.store.removeFolder(t.id)}).open()})}),r.showAtMouseEvent(e)}showMoveMenu(e,t){let r=new d.Menu;t.folderId!==null&&(r.addItem(o=>{o.setTitle("\uFF08\u6839\u7EA7\u522B\uFF09"),o.setIcon("corner-left-up"),o.onClick(async()=>{await this.store.moveBookmark(t.id,null)})}),r.addSeparator());for(let o of this.store.folders)o.id!==t.folderId&&r.addItem(s=>{s.setTitle(o.name),s.setIcon("folder"),s.onClick(async()=>{await this.store.moveBookmark(t.id,o.id)})});r.showAtMouseEvent(e)}setupDragEvents(e,t){e.addEventListener("dragstart",r=>{r.dataTransfer&&(r.dataTransfer.setData("text/plain",JSON.stringify({id:t.id,type:t.type})),r.dataTransfer.effectAllowed="move"),e.addClass("sb-dragging")}),e.addEventListener("dragend",()=>{e.removeClass("sb-dragging"),this.listEl.querySelectorAll(".sb-drop-target").forEach(r=>r.removeClass("sb-drop-target"))}),e.addEventListener("dragover",r=>{r.preventDefault(),r.dataTransfer&&(r.dataTransfer.dropEffect="move"),e.addClass("sb-drop-target")}),e.addEventListener("dragleave",()=>{e.removeClass("sb-drop-target")}),e.addEventListener("drop",r=>{if(r.preventDefault(),e.removeClass("sb-drop-target"),!!r.dataTransfer)try{let o=JSON.parse(r.dataTransfer.getData("text/plain"));if(!o.id||!o.type)return;o.type==="bookmark"&&t.type==="folder"&&this.store.moveBookmark(o.id,t.id)}catch(o){}})}};var y=class extends D.ItemView{constructor(t,r){super(t);this.browserPanel=null;this.bookmarkPanel=null;this.plugin=r}getViewType(){return c}getDisplayText(){return"Side bookmark"}getIcon(){return"bookmark"}onOpen(){let t=this.contentEl;t.empty(),t.addClass("sb-container"),this.browserPanel=new w(t),this.browserPanel.onAddBookmark=(o,s)=>{new k(this.app,this.plugin.store,o,s,null,(i,l,m)=>{this.plugin.store.addBookmark(i,l,m)}).open()};let r=this.plugin.store.defaultUrl;return r&&this.browserPanel.navigate(r),this.bookmarkPanel=new E(this.app,t,this.plugin.store),this.bookmarkPanel.onNavigate=o=>{this.browserPanel&&this.browserPanel.navigate(o)},this.plugin.store.showBookmarkPanel||this.bookmarkPanel.toggleCollapse(),Promise.resolve()}onClose(){return this.browserPanel&&(this.browserPanel.destroy(),this.browserPanel=null),this.bookmarkPanel&&(this.bookmarkPanel.destroy(),this.bookmarkPanel=null),Promise.resolve()}navigateTo(t){this.browserPanel&&this.browserPanel.navigate(t)}};var p=require("obsidian"),I=class extends p.PluginSettingTab{constructor(e,t){super(e,t),this.plugin=t}display(){let{containerEl:e}=this;e.empty(),new p.Setting(e).setName("\u8BBE\u7F6E").setHeading(),new p.Setting(e).setName("\u9ED8\u8BA4\u9996\u9875").setDesc("\u6253\u5F00\u63D2\u4EF6\u65F6\u9ED8\u8BA4\u52A0\u8F7D\u7684\u7F51\u5740").addText(r=>r.setPlaceholder("https://www.google.com").setValue(this.plugin.store.defaultUrl).onChange(async o=>{this.plugin.store.defaultUrl=o,await this.plugin.store.save()})),new p.Setting(e).setName("\u9ED8\u8BA4\u663E\u793A\u4E66\u7B7E\u9762\u677F").setDesc("\u6253\u5F00\u63D2\u4EF6\u65F6\u662F\u5426\u9ED8\u8BA4\u5C55\u5F00\u4E66\u7B7E\u5217\u8868\u9762\u677F").addToggle(r=>r.setValue(this.plugin.store.showBookmarkPanel).onChange(async o=>{this.plugin.store.showBookmarkPanel=o,await this.plugin.store.save()})),new p.Setting(e).setName("\u62E6\u622A\u7B14\u8BB0\u94FE\u63A5").setDesc("\u5F00\u542F\u540E\uFF0C\u5355\u51FB\u7B14\u8BB0\u4E2D\u7684\u5916\u90E8\u94FE\u63A5\uFF08http/https\uFF09\u5C06\u81EA\u52A8\u5728\u5185\u7F6E\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\uFF0C\u800C\u975E\u4F7F\u7528\u7CFB\u7EDF\u6D4F\u89C8\u5668\u3002\u6309\u4F4F Cmd/Ctrl \u5355\u51FB\u53EF\u4E34\u65F6\u7ED5\u8FC7\uFF0C\u4ECD\u4F7F\u7528\u7CFB\u7EDF\u6D4F\u89C8\u5668\u6253\u5F00\u3002").addToggle(r=>r.setValue(this.plugin.store.interceptLinks).onChange(async o=>{this.plugin.store.interceptLinks=o,await this.plugin.store.save()})),new p.Setting(e).setName("\u7EDF\u8BA1").setHeading();let t=e.createDiv({cls:"sb-settings-stats"});t.createEl("p",{text:`\u4E66\u7B7E\u6570\u91CF: ${this.plugin.store.bookmarks.length}`}),t.createEl("p",{text:`\u6587\u4EF6\u5939\u6570\u91CF: ${this.plugin.store.folders.length}`})}};var T=class extends S.Plugin{constructor(){super(...arguments);this.modifierKeyPressed=!1}async onload(){this.store=new f(this),await this.store.load(),this.registerView(c,t=>new y(t,this)),this.addRibbonIcon("bookmark","Side bookmark",()=>{this.activateView()}),this.addCommand({id:"open",name:"\u6253\u5F00\u4FA7\u8FB9\u680F\u4E66\u7B7E",callback:()=>{this.activateView()}}),this.addSettingTab(new I(this.app,this)),this.registerDomEvent(document,"click",this.handleLinkClick.bind(this),!0),this.registerDomEvent(document,"keydown",t=>{(t.key==="Meta"||t.key==="Control"||t.metaKey||t.ctrlKey)&&(this.modifierKeyPressed=!0)}),this.registerDomEvent(document,"keyup",t=>{(t.key==="Meta"||t.key==="Control"||!t.metaKey&&!t.ctrlKey)&&(this.modifierKeyPressed=!1)}),this.registerDomEvent(window,"blur",()=>{this.modifierKeyPressed=!1}),this.originalWindowOpen=window.open,window.open=(t,r,o)=>{if(this.store.interceptLinks&&t&&!this.modifierKeyPressed){let s=t.toString();if(/^https?:\/\//i.test(s))return this.openUrlInSideBookmark(s),null}return this.originalWindowOpen.call(window,t,r,o)}}onunload(){this.originalWindowOpen&&(window.open=this.originalWindowOpen)}handleLinkClick(t){if(!this.store.interceptLinks)return;let o=t.target.closest("a");if(!o)return;let s=o.getAttribute("href")||o.href;!s||!/^https?:\/\//i.test(s)||t.metaKey||t.ctrlKey||o.closest(".sb-browser-panel")||o.closest("webview")||(t.preventDefault(),t.stopPropagation(),this.openUrlInSideBookmark(s))}async openUrlInSideBookmark(t){let{workspace:r}=this.app,o=r.getLeavesOfType(c);if(o.length===0)await this.activateView(),o=r.getLeavesOfType(c);else{let i=o[0];i&&r.revealLeaf(i)}let s=o[0];if(s){let i=s.view;typeof i.navigateTo=="function"&&i.navigateTo(t)}}async activateView(){let{workspace:t}=this.app,r=t.getLeavesOfType(c);if(r.length>0)t.revealLeaf(r[0]);else{let o=t.getRightLeaf(!1);o&&(await o.setViewState({type:c,active:!0}),t.revealLeaf(o))}}}; +var L=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var A=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},N=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of M(e))!_.call(n,r)&&r!==t&&L(n,r,{get:()=>e[r],enumerable:!(o=S(e,r))||o.enumerable});return n};var O=n=>N(L({},"__esModule",{value:!0}),n);var U={};A(U,{default:()=>T});module.exports=O(U);var F=require("obsidian");var P={bookmarks:[],folders:[],defaultUrl:"https://www.google.com",showBookmarkPanel:!0,interceptLinks:!1},c="side-bookmark-view";function x(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}var f=class{constructor(e){this.listeners=[];this.plugin=e,this.data={...P}}async load(){let e=await this.plugin.loadData();e&&(this.data={...P,...e})}async save(){await this.plugin.saveData(this.data)}onChange(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}notify(){for(let e of this.listeners)e()}get defaultUrl(){return this.data.defaultUrl}set defaultUrl(e){this.data.defaultUrl=e}get showBookmarkPanel(){return this.data.showBookmarkPanel}set showBookmarkPanel(e){this.data.showBookmarkPanel=e}get interceptLinks(){return this.data.interceptLinks}set interceptLinks(e){this.data.interceptLinks=e}get bookmarks(){return this.data.bookmarks}get folders(){return this.data.folders}async addBookmark(e,t,o=null){let r=this.data.bookmarks.filter(l=>l.folderId===o),s=r.length>0?Math.max(...r.map(l=>l.order)):-1,i={id:x(),type:"bookmark",title:e,url:t,folderId:o,order:s+1};return this.data.bookmarks.push(i),await this.save(),this.notify(),i}async removeBookmark(e){this.data.bookmarks=this.data.bookmarks.filter(t=>t.id!==e),await this.save(),this.notify()}async updateBookmark(e,t){let o=this.data.bookmarks.find(r=>r.id===e);o&&(Object.assign(o,t),await this.save(),this.notify())}async moveBookmark(e,t){await this.updateBookmark(e,{folderId:t})}async addFolder(e,t=null){let o=this.data.folders.filter(i=>i.parentId===t),r=o.length>0?Math.max(...o.map(i=>i.order)):-1,s={id:x(),type:"folder",name:e,parentId:t,collapsed:!1,order:r+1};return this.data.folders.push(s),await this.save(),this.notify(),s}async removeFolder(e){let t=this.getDescendantFolderIds(e),o=[e,...t];this.data.bookmarks=this.data.bookmarks.filter(r=>{var s;return!o.includes((s=r.folderId)!=null?s:"")}),this.data.folders=this.data.folders.filter(r=>!o.includes(r.id)),await this.save(),this.notify()}async updateFolder(e,t){let o=this.data.folders.find(r=>r.id===e);o&&(Object.assign(o,t),await this.save(),this.notify())}async toggleFolder(e){let t=this.data.folders.find(o=>o.id===e);t&&(t.collapsed=!t.collapsed,await this.save(),this.notify())}getBookmarksByFolder(e){return this.data.bookmarks.filter(t=>t.folderId===e).sort((t,o)=>t.order-o.order)}getSubFolders(e){return this.data.folders.filter(t=>t.parentId===e).sort((t,o)=>t.order-o.order)}getFolder(e){return this.data.folders.find(t=>t.id===e)}getBookmark(e){return this.data.bookmarks.find(t=>t.id===e)}getTreeItems(e){let t=this.getSubFolders(e),o=this.getBookmarksByFolder(e);return[...t,...o].sort((s,i)=>s.order-i.order)}hasBookmarkWithUrl(e){return this.data.bookmarks.some(t=>t.url===e)}getDescendantFolderIds(e){let t=this.data.folders.filter(r=>r.parentId===e),o=[];for(let r of t)o.push(r.id),o.push(...this.getDescendantFolderIds(r.id));return o}};var D=require("obsidian");var u=require("obsidian"),b=class{constructor(e){this.webviewEl=null;this.currentUrl="";this.currentTitle="";this.onAddBookmark=null;this.containerEl=e.createDiv({cls:"sb-browser-panel"}),this.navBarEl=this.containerEl.createDiv({cls:"sb-nav-bar"});let t=this.navBarEl.createDiv({cls:"sb-nav-buttons"});this.backBtn=t.createDiv({cls:"sb-nav-btn",attr:{"aria-label":"Back"}}),(0,u.setIcon)(this.backBtn,"arrow-left"),this.backBtn.addEventListener("click",()=>this.goBack()),this.forwardBtn=t.createDiv({cls:"sb-nav-btn",attr:{"aria-label":"Forward"}}),(0,u.setIcon)(this.forwardBtn,"arrow-right"),this.forwardBtn.addEventListener("click",()=>this.goForward()),this.refreshBtn=t.createDiv({cls:"sb-nav-btn",attr:{"aria-label":"Reload"}}),(0,u.setIcon)(this.refreshBtn,"refresh-cw"),this.refreshBtn.addEventListener("click",()=>this.reload()),this.urlInput=this.navBarEl.createEl("input",{cls:"sb-url-input",attr:{type:"text",placeholder:"Enter URL...",spellcheck:"false"}}),this.urlInput.addEventListener("keydown",o=>{o.key==="Enter"&&this.navigateToInput()}),this.urlInput.addEventListener("focus",()=>{this.urlInput.select()}),this.bookmarkBtn=this.navBarEl.createDiv({cls:"sb-nav-btn sb-bookmark-btn",attr:{"aria-label":"Add bookmark"}}),(0,u.setIcon)(this.bookmarkBtn,"star"),this.bookmarkBtn.addEventListener("click",()=>{this.onAddBookmark&&this.currentUrl&&this.onAddBookmark(this.currentTitle||this.currentUrl,this.currentUrl)}),this.webviewContainer=this.containerEl.createDiv({cls:"sb-webview-container"})}navigate(e){let t=e.trim();t&&(/^https?:\/\//i.test(t)||(t="https://"+t),this.currentUrl=t,this.urlInput.value=t,this.createOrUpdateWebview(t))}goBack(){var e;if(this.webviewEl){let t=this.webviewEl;(e=t.goBack)==null||e.call(t)}}goForward(){var e;if(this.webviewEl){let t=this.webviewEl;(e=t.goForward)==null||e.call(t)}}reload(){var e;if(this.webviewEl){let t=this.webviewEl;(e=t.reload)==null||e.call(t)}}getUrl(){return this.currentUrl}getTitle(){return this.currentTitle}destroy(){this.webviewEl&&(this.webviewEl.remove(),this.webviewEl=null),this.containerEl.remove()}navigateToInput(){let e=this.urlInput.value.trim();e&&this.navigate(e)}createOrUpdateWebview(e){this.webviewContainer.empty();let t=this.webviewContainer.createEl("webview",{attr:{src:e,allowpopups:""},cls:"sb-webview"});t.addEventListener("did-navigate",o=>{let r=o;typeof r.url=="string"&&(this.currentUrl=r.url,this.urlInput.value=r.url)}),t.addEventListener("did-navigate-in-page",o=>{let r=o;typeof r.url=="string"&&(this.currentUrl=r.url,this.urlInput.value=r.url)}),t.addEventListener("page-title-updated",o=>{let r=o;typeof r.title=="string"&&(this.currentTitle=r.title)}),t.addEventListener("dom-ready",()=>{let o=t;o.getURL&&(this.currentUrl=o.getURL(),this.urlInput.value=this.currentUrl),o.getTitle&&(this.currentTitle=o.getTitle())}),t.addEventListener("new-window",o=>{let r=o;typeof r.url=="string"&&this.navigate(r.url)}),this.webviewEl=t}};var d=require("obsidian");var a=require("obsidian"),m=class extends a.Modal{constructor(e,t,o="",r="",s=null,i){super(e),this.store=t,this.title=o,this.url=r,this.folderId=s,this.onSave=i!=null?i:null}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"Add bookmark"}),new a.Setting(e).setName("Title").addText(t=>t.setPlaceholder("Enter bookmark title").setValue(this.title).onChange(o=>{this.title=o})),new a.Setting(e).setName("URL").addText(t=>t.setPlaceholder("https://example.com").setValue(this.url).onChange(o=>{this.url=o})),new a.Setting(e).setName("Folder").addDropdown(t=>{var o;t.addOption("__root__","(No folder)");for(let r of this.store.folders)t.addOption(r.id,this.getFolderPath(r));t.setValue((o=this.folderId)!=null?o:"__root__"),t.onChange(r=>{this.folderId=r==="__root__"?null:r})}),new a.Setting(e).addButton(t=>t.setButtonText("Save").setCta().onClick(async()=>{if(!this.url.trim())return;this.title.trim()||(this.title=this.url);let o=this.url.trim();/^https?:\/\//i.test(o)||(o="https://"+o),this.onSave?this.onSave(this.title.trim(),o,this.folderId):await this.store.addBookmark(this.title.trim(),o,this.folderId),this.close()})).addButton(t=>t.setButtonText("Cancel").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}getFolderPath(e){let t=[e.name],o=e;for(;o!=null&&o.parentId;)o=this.store.getFolder(o.parentId),o&&t.unshift(o.name);return t.join(" / ")}},w=class extends a.Modal{constructor(e,t,o,r,s,i){super(e),this.store=t,this.bookmarkId=o,this.title=r,this.url=s,this.folderId=i}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"Edit bookmark"}),new a.Setting(e).setName("Title").addText(t=>t.setPlaceholder("Enter bookmark title").setValue(this.title).onChange(o=>{this.title=o})),new a.Setting(e).setName("URL").addText(t=>t.setPlaceholder("https://example.com").setValue(this.url).onChange(o=>{this.url=o})),new a.Setting(e).setName("Folder").addDropdown(t=>{var o;t.addOption("__root__","(No folder)");for(let r of this.store.folders)t.addOption(r.id,this.getFolderPath(r));t.setValue((o=this.folderId)!=null?o:"__root__"),t.onChange(r=>{this.folderId=r==="__root__"?null:r})}),new a.Setting(e).addButton(t=>t.setButtonText("Save").setCta().onClick(async()=>{if(!this.url.trim())return;this.title.trim()||(this.title=this.url);let o=this.url.trim();/^https?:\/\//i.test(o)||(o="https://"+o),await this.store.updateBookmark(this.bookmarkId,{title:this.title.trim(),url:o,folderId:this.folderId}),this.close()})).addButton(t=>t.setButtonText("Cancel").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}getFolderPath(e){let t=[e.name],o=e;for(;o!=null&&o.parentId;)o=this.store.getFolder(o.parentId),o&&t.unshift(o.name);return t.join(" / ")}},v=class extends a.Modal{constructor(e,t,o=null){super(e),this.store=t,this.folderName="",this.parentId=o}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"New folder"}),new a.Setting(e).setName("Folder name").addText(t=>t.setPlaceholder("Enter folder name").setValue(this.folderName).onChange(o=>{this.folderName=o})),new a.Setting(e).setName("Parent folder").addDropdown(t=>{var o;t.addOption("__root__","(Root level)");for(let r of this.store.folders)t.addOption(r.id,this.getFolderPath(r));t.setValue((o=this.parentId)!=null?o:"__root__"),t.onChange(r=>{this.parentId=r==="__root__"?null:r})}),new a.Setting(e).addButton(t=>t.setButtonText("Create").setCta().onClick(async()=>{this.folderName.trim()&&(await this.store.addFolder(this.folderName.trim(),this.parentId),this.close())})).addButton(t=>t.setButtonText("Cancel").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}getFolderPath(e){let t=[e.name],o=e;for(;o!=null&&o.parentId;)o=this.store.getFolder(o.parentId),o&&t.unshift(o.name);return t.join(" / ")}},B=class extends a.Modal{constructor(e,t,o,r){super(e),this.store=t,this.folderId=o,this.folderName=r}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"Edit folder"}),new a.Setting(e).setName("Folder name").addText(t=>t.setPlaceholder("Enter folder name").setValue(this.folderName).onChange(o=>{this.folderName=o})),new a.Setting(e).addButton(t=>t.setButtonText("Save").setCta().onClick(async()=>{this.folderName.trim()&&(await this.store.updateFolder(this.folderId,{name:this.folderName.trim()}),this.close())})).addButton(t=>t.setButtonText("Cancel").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}},g=class extends a.Modal{constructor(e,t,o){super(e),this.message=t,this.onConfirm=o}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("side-bookmark-modal"),e.createEl("h3",{text:"Confirm delete"}),e.createEl("p",{text:this.message}),new a.Setting(e).addButton(t=>t.setButtonText("Delete").setWarning().onClick(async()=>{await this.onConfirm(),this.close()})).addButton(t=>t.setButtonText("Cancel").onClick(()=>this.close()))}onClose(){let{contentEl:e}=this;e.empty()}};var E=class{constructor(e,t,o){this.collapsed=!1;this.unsubscribe=null;this.onNavigate=null;this.app=e,this.store=o,this.containerEl=t.createDiv({cls:"sb-bookmark-panel"}),this.headerEl=this.containerEl.createDiv({cls:"sb-bookmark-header"});let r=this.headerEl.createDiv({cls:"sb-bookmark-header-left"}),s=r.createDiv({cls:"sb-collapse-icon"});(0,d.setIcon)(s,"chevron-down"),r.createSpan({text:"Bookmarks",cls:"sb-bookmark-title"}),r.addEventListener("click",()=>{this.toggleCollapse()});let l=this.headerEl.createDiv({cls:"sb-bookmark-header-right"}).createDiv({cls:"sb-add-btn-group"}),p=l.createDiv({cls:"sb-header-btn",attr:{"aria-label":"Add bookmark"}});(0,d.setIcon)(p,"plus"),p.addEventListener("click",C=>{C.stopPropagation(),new m(this.app,this.store).open()});let h=l.createDiv({cls:"sb-header-btn",attr:{"aria-label":"New folder"}});(0,d.setIcon)(h,"folder-plus"),h.addEventListener("click",C=>{C.stopPropagation(),new v(this.app,this.store).open()}),this.listEl=this.containerEl.createDiv({cls:"sb-bookmark-list"}),this.unsubscribe=this.store.onChange(()=>{this.renderList()}),this.renderList()}toggleCollapse(){this.collapsed=!this.collapsed,this.containerEl.toggleClass("sb-collapsed",this.collapsed);let e=this.headerEl.querySelector(".sb-collapse-icon");e&&(e.empty(),(0,d.setIcon)(e,this.collapsed?"chevron-right":"chevron-down"))}destroy(){this.unsubscribe&&this.unsubscribe(),this.containerEl.remove()}renderList(){if(this.listEl.empty(),this.store.getTreeItems(null).length===0){let t=this.listEl.createDiv({cls:"sb-empty-state"}),o=t.createDiv({cls:"sb-empty-icon"});(0,d.setIcon)(o,"bookmark"),t.createDiv({text:"No bookmarks",cls:"sb-empty-text"}),t.createDiv({text:"Click the + button or \u2B50 icon to add a bookmark",cls:"sb-empty-hint"});return}this.renderTreeLevel(this.listEl,null,0)}renderTreeLevel(e,t,o){let r=this.store.getTreeItems(t);for(let s of r)s.type==="folder"?this.renderFolder(e,s,o):this.renderBookmark(e,s,o)}renderFolder(e,t,o){let r=e.createDiv({cls:"sb-tree-item sb-folder-item",attr:{"data-id":t.id,"data-type":"folder",draggable:"true"}});r.style.paddingLeft=`${o*16+4}px`;let s=r.createDiv({cls:"sb-tree-item-row"}),i=s.createDiv({cls:"sb-folder-collapse"});(0,d.setIcon)(i,t.collapsed?"chevron-right":"chevron-down");let l=s.createDiv({cls:"sb-item-icon"});(0,d.setIcon)(l,t.collapsed?"folder":"folder-open"),s.createSpan({text:t.name,cls:"sb-item-label"});let p=this.store.getBookmarksByFolder(t.id).length+this.store.getSubFolders(t.id).length;if(p>0&&s.createSpan({text:`${p}`,cls:"sb-count-badge"}),s.addEventListener("click",()=>{this.store.toggleFolder(t.id)}),s.addEventListener("contextmenu",h=>{h.preventDefault(),h.stopPropagation(),this.showFolderContextMenu(h,t)}),this.setupDragEvents(r,t),!t.collapsed){let h=e.createDiv({cls:"sb-folder-children"});this.renderTreeLevel(h,t.id,o+1)}}renderBookmark(e,t,o){let r=e.createDiv({cls:"sb-tree-item sb-bookmark-item",attr:{"data-id":t.id,"data-type":"bookmark",draggable:"true"}});r.style.paddingLeft=`${o*16+24}px`;let s=r.createDiv({cls:"sb-tree-item-row"}),i=s.createDiv({cls:"sb-item-icon"});(0,d.setIcon)(i,"globe"),s.createSpan({text:t.title,cls:"sb-item-label"}),s.addEventListener("click",()=>{this.onNavigate&&this.onNavigate(t.url)}),s.addEventListener("contextmenu",l=>{l.preventDefault(),l.stopPropagation(),this.showBookmarkContextMenu(l,t)}),this.setupDragEvents(r,t)}showBookmarkContextMenu(e,t){let o=new d.Menu;o.addItem(r=>{r.setTitle("Open"),r.setIcon("external-link"),r.onClick(()=>{this.onNavigate&&this.onNavigate(t.url)})}),o.addSeparator(),o.addItem(r=>{r.setTitle("Edit"),r.setIcon("pencil"),r.onClick(()=>{new w(this.app,this.store,t.id,t.title,t.url,t.folderId).open()})}),o.addItem(r=>{r.setTitle("Move to..."),r.setIcon("folder-input"),r.onClick(()=>{this.showMoveMenu(e,t)})}),o.addSeparator(),o.addItem(r=>{r.setTitle("Delete"),r.setIcon("trash-2"),r.onClick(()=>{new g(this.app,`Are you sure you want to delete bookmark "${t.title}"?`,async()=>{await this.store.removeBookmark(t.id)}).open()})}),o.showAtMouseEvent(e)}showFolderContextMenu(e,t){let o=new d.Menu;o.addItem(r=>{r.setTitle("Add bookmark to this folder"),r.setIcon("plus"),r.onClick(()=>{new m(this.app,this.store,"","",t.id).open()})}),o.addItem(r=>{r.setTitle("Add sub-folder"),r.setIcon("folder-plus"),r.onClick(()=>{new v(this.app,this.store,t.id).open()})}),o.addSeparator(),o.addItem(r=>{r.setTitle("Rename"),r.setIcon("pencil"),r.onClick(()=>{new B(this.app,this.store,t.id,t.name).open()})}),o.addSeparator(),o.addItem(r=>{r.setTitle("Delete folder"),r.setIcon("trash-2"),r.onClick(()=>{let s=this.store.getBookmarksByFolder(t.id).length,i=this.store.getSubFolders(t.id).length,l=`Are you sure you want to delete folder "${t.name}"?`;(s>0||i>0)&&(l+=` +It contains ${s} bookmarks and ${i} folders, which will all be deleted.`),new g(this.app,l,async()=>{await this.store.removeFolder(t.id)}).open()})}),o.showAtMouseEvent(e)}showMoveMenu(e,t){let o=new d.Menu;t.folderId!==null&&(o.addItem(r=>{r.setTitle("(Root level)"),r.setIcon("corner-left-up"),r.onClick(async()=>{await this.store.moveBookmark(t.id,null)})}),o.addSeparator());for(let r of this.store.folders)r.id!==t.folderId&&o.addItem(s=>{s.setTitle(r.name),s.setIcon("folder"),s.onClick(async()=>{await this.store.moveBookmark(t.id,r.id)})});o.showAtMouseEvent(e)}setupDragEvents(e,t){e.addEventListener("dragstart",o=>{o.dataTransfer&&(o.dataTransfer.setData("text/plain",JSON.stringify({id:t.id,type:t.type})),o.dataTransfer.effectAllowed="move"),e.addClass("sb-dragging")}),e.addEventListener("dragend",()=>{e.removeClass("sb-dragging"),this.listEl.querySelectorAll(".sb-drop-target").forEach(o=>o.removeClass("sb-drop-target"))}),e.addEventListener("dragover",o=>{o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect="move"),e.addClass("sb-drop-target")}),e.addEventListener("dragleave",()=>{e.removeClass("sb-drop-target")}),e.addEventListener("drop",o=>{if(o.preventDefault(),e.removeClass("sb-drop-target"),!!o.dataTransfer)try{let r=JSON.parse(o.dataTransfer.getData("text/plain"));if(!r.id||!r.type)return;r.type==="bookmark"&&t.type==="folder"&&this.store.moveBookmark(r.id,t.id)}catch(r){}})}};var y=class extends D.ItemView{constructor(t,o){super(t);this.browserPanel=null;this.bookmarkPanel=null;this.plugin=o}getViewType(){return c}getDisplayText(){return"Side bookmark"}getIcon(){return"bookmark"}onOpen(){let t=this.contentEl;t.empty(),t.addClass("sb-container"),this.browserPanel=new b(t),this.browserPanel.onAddBookmark=(r,s)=>{new m(this.app,this.plugin.store,r,s,null,(i,l,p)=>{this.plugin.store.addBookmark(i,l,p)}).open()};let o=this.plugin.store.defaultUrl;return o&&this.browserPanel.navigate(o),this.bookmarkPanel=new E(this.app,t,this.plugin.store),this.bookmarkPanel.onNavigate=r=>{this.browserPanel&&this.browserPanel.navigate(r)},this.plugin.store.showBookmarkPanel||this.bookmarkPanel.toggleCollapse(),Promise.resolve()}onClose(){return this.browserPanel&&(this.browserPanel.destroy(),this.browserPanel=null),this.bookmarkPanel&&(this.bookmarkPanel.destroy(),this.bookmarkPanel=null),Promise.resolve()}navigateTo(t){this.browserPanel&&this.browserPanel.navigate(t)}};var k=require("obsidian"),I=class extends k.PluginSettingTab{constructor(e,t){super(e,t),this.plugin=t}display(){let{containerEl:e}=this;e.empty(),new k.Setting(e).setName("Default homepage").setDesc("The URL to load when the plugin opens.").addText(o=>o.setPlaceholder("https://www.google.com").setValue(this.plugin.store.defaultUrl).onChange(async r=>{this.plugin.store.defaultUrl=r,await this.plugin.store.save()})),new k.Setting(e).setName("Show bookmark panel by default").setDesc("Expand the bookmark list panel automatically when the plugin opens.").addToggle(o=>o.setValue(this.plugin.store.showBookmarkPanel).onChange(async r=>{this.plugin.store.showBookmarkPanel=r,await this.plugin.store.save()})),new k.Setting(e).setName("Intercept note links").setDesc("When enabled, clicking external links (http/https) in notes opens them in the built-in browser instead of the system browser. Hold Cmd/Ctrl while clicking to bypass and use the system browser.").addToggle(o=>o.setValue(this.plugin.store.interceptLinks).onChange(async r=>{this.plugin.store.interceptLinks=r,await this.plugin.store.save()})),new k.Setting(e).setName("Statistics").setHeading();let t=e.createDiv({cls:"sb-settings-stats"});t.createEl("p",{text:`Bookmarks: ${this.plugin.store.bookmarks.length}`}),t.createEl("p",{text:`Folders: ${this.plugin.store.folders.length}`})}};var T=class extends F.Plugin{constructor(){super(...arguments);this.modifierKeyPressed=!1}async onload(){this.store=new f(this),await this.store.load(),this.registerView(c,t=>new y(t,this)),this.addRibbonIcon("bookmark","Side bookmark",()=>{this.activateView()}),this.addCommand({id:"open",name:"Open",callback:()=>{this.activateView()}}),this.addSettingTab(new I(this.app,this)),this.registerDomEvent(activeDocument,"click",this.handleLinkClick.bind(this),!0),this.registerDomEvent(activeDocument,"keydown",t=>{(t.key==="Meta"||t.key==="Control"||t.metaKey||t.ctrlKey)&&(this.modifierKeyPressed=!0)}),this.registerDomEvent(activeDocument,"keyup",t=>{(t.key==="Meta"||t.key==="Control"||!t.metaKey&&!t.ctrlKey)&&(this.modifierKeyPressed=!1)}),this.registerDomEvent(activeWindow,"blur",()=>{this.modifierKeyPressed=!1}),this.originalWindowOpen=window.open,window.open=(t,o,r)=>{if(this.store.interceptLinks&&t&&!this.modifierKeyPressed){let s=t.toString();if(/^https?:\/\//i.test(s))return this.openUrlInSideBookmark(s),null}return this.originalWindowOpen.call(window,t,o,r)}}onunload(){this.originalWindowOpen&&(window.open=this.originalWindowOpen)}handleLinkClick(t){if(!this.store.interceptLinks)return;let r=t.target.closest("a");if(!r)return;let s=r.getAttribute("href")||r.href;!s||!/^https?:\/\//i.test(s)||t.metaKey||t.ctrlKey||r.closest(".sb-browser-panel")||r.closest("webview")||(t.preventDefault(),t.stopPropagation(),this.openUrlInSideBookmark(s))}async openUrlInSideBookmark(t){let{workspace:o}=this.app,r=o.getLeavesOfType(c);if(r.length===0)await this.activateView(),r=o.getLeavesOfType(c);else{let i=r[0];i&&o.revealLeaf(i)}let s=r[0];if(s){let i=s.view;typeof i.navigateTo=="function"&&i.navigateTo(t)}}async activateView(){let{workspace:t}=this.app,o=t.getLeavesOfType(c);if(o.length>0)t.revealLeaf(o[0]);else{let r=t.getRightLeaf(!1);r&&(await r.setViewState({type:c,active:!0}),t.revealLeaf(r))}}}; diff --git a/manifest.json b/manifest.json index 60657aa..7d48a69 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "id": "side-bookmark", "name": "Side Bookmark", - "version": "0.0.4", - "minAppVersion": "0.15.0", + "version": "0.0.5", + "minAppVersion": "1.7.2", "description": "A sidebar bookmark browser. Browse websites and manage bookmarks right in the sidebar.", "author": "bcs1037", "isDesktopOnly": true diff --git a/package.json b/package.json index 986f163..9009280 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "side-bookmark", - "version": "0.0.4", + "version": "0.0.5", "description": "A sidebar bookmark browser plugin for Obsidian", "main": "main.js", "type": "module", diff --git a/src/BookmarkPanel.ts b/src/BookmarkPanel.ts index c28ce23..6e2158e 100644 --- a/src/BookmarkPanel.ts +++ b/src/BookmarkPanel.ts @@ -402,7 +402,7 @@ export class BookmarkPanel { if (!e.dataTransfer) return; try { - const data = JSON.parse(e.dataTransfer.getData('text/plain')); + const data = JSON.parse(e.dataTransfer.getData('text/plain')) as { id?: string, type?: string }; if (!data.id || !data.type) return; // If dropping a bookmark onto a folder, move it diff --git a/src/BrowserPanel.ts b/src/BrowserPanel.ts index c70f17c..10e22dd 100644 --- a/src/BrowserPanel.ts +++ b/src/BrowserPanel.ts @@ -92,24 +92,24 @@ export class BrowserPanel { /** Go back in browser history */ goBack(): void { if (this.webviewEl) { - const wv = this.webviewEl as unknown as Record; - if (typeof wv.goBack === 'function') wv.goBack(); + const wv = this.webviewEl as unknown as { goBack?: () => void }; + wv.goBack?.(); } } /** Go forward in browser history */ goForward(): void { if (this.webviewEl) { - const wv = this.webviewEl as unknown as Record; - if (typeof wv.goForward === 'function') wv.goForward(); + const wv = this.webviewEl as unknown as { goForward?: () => void }; + wv.goForward?.(); } } /** Reload the current page */ reload(): void { if (this.webviewEl) { - const wv = this.webviewEl as unknown as Record; - if (typeof wv.reload === 'function') wv.reload(); + const wv = this.webviewEl as unknown as { reload?: () => void }; + wv.reload?.(); } } @@ -142,17 +142,16 @@ export class BrowserPanel { /** Create or update the webview element */ private createOrUpdateWebview(url: string): void { - // Remove existing webview - if (this.webviewEl) { - this.webviewEl.remove(); - } + this.webviewContainer.empty(); // Create a new webview element (Electron's webview tag) - const webview = document.createElement('webview'); - - webview.setAttribute('src', url); - webview.setAttribute('allowpopups', ''); - webview.addClass('sb-webview'); + const webview = this.webviewContainer.createEl('webview' as keyof HTMLElementTagNameMap, { + attr: { + src: url, + allowpopups: '' + }, + cls: 'sb-webview' + }); // Listen for navigation events webview.addEventListener('did-navigate', ((e: CustomEvent) => { @@ -180,13 +179,13 @@ export class BrowserPanel { webview.addEventListener('dom-ready', () => { // Update URL from webview's actual URL - const wv = webview as unknown as Record; - if (typeof wv.getURL === 'function') { - this.currentUrl = wv.getURL() as string; + const wv = webview as unknown as { getURL?: () => string, getTitle?: () => string }; + if (wv.getURL) { + this.currentUrl = wv.getURL(); this.urlInput.value = this.currentUrl; } - if (typeof wv.getTitle === 'function') { - this.currentTitle = wv.getTitle() as string; + if (wv.getTitle) { + this.currentTitle = wv.getTitle(); } }); @@ -198,8 +197,6 @@ export class BrowserPanel { } }) as EventListener); - this.webviewContainer.empty(); - this.webviewContainer.appendChild(webview); this.webviewEl = webview; } } diff --git a/src/main.ts b/src/main.ts index c56cb0c..b4cd983 100644 --- a/src/main.ts +++ b/src/main.ts @@ -32,7 +32,7 @@ export default class SideBookmarkPlugin extends Plugin { this.addCommand({ id: 'open', - name: 'Open side bookmark', + name: 'Open', callback: () => { void this.activateView(); }, @@ -42,20 +42,20 @@ export default class SideBookmarkPlugin extends Plugin { this.addSettingTab(new SideBookmarkSettingTab(this.app, this)); // Register global link interception (capture phase, runs before Obsidian's handlers) - this.registerDomEvent(document, 'click', this.handleLinkClick.bind(this), true); + this.registerDomEvent(activeDocument, 'click', this.handleLinkClick.bind(this), true); // Track modifier keys for window.open interception bypass - this.registerDomEvent(document, 'keydown', (e: KeyboardEvent) => { + this.registerDomEvent(activeDocument, 'keydown', (e: KeyboardEvent) => { if (e.key === 'Meta' || e.key === 'Control' || e.metaKey || e.ctrlKey) { this.modifierKeyPressed = true; } }); - this.registerDomEvent(document, 'keyup', (e: KeyboardEvent) => { + this.registerDomEvent(activeDocument, 'keyup', (e: KeyboardEvent) => { if (e.key === 'Meta' || e.key === 'Control' || (!e.metaKey && !e.ctrlKey)) { this.modifierKeyPressed = false; } }); - this.registerDomEvent(window, 'blur', () => { + this.registerDomEvent(activeWindow, 'blur', () => { this.modifierKeyPressed = false; }); diff --git a/src/settings.ts b/src/settings.ts index 0e94ebc..da3f077 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -18,8 +18,6 @@ export class SideBookmarkSettingTab extends PluginSettingTab { const { containerEl } = this; containerEl.empty(); - new Setting(containerEl).setName('General').setHeading(); - new Setting(containerEl) .setName('Default homepage') .setDesc('The URL to load when the plugin opens.') diff --git a/versions.json b/versions.json index b7e9153..5508d62 100644 --- a/versions.json +++ b/versions.json @@ -2,5 +2,6 @@ "0.0.1": "0.15.0", "0.0.2": "0.15.0", "0.0.3": "0.15.0", - "0.0.4": "0.15.0" + "0.0.4": "0.15.0", + "0.0.5": "1.7.2" }