Skip to content

Commit

Permalink
Feat/inline url preview (#236)
Browse files Browse the repository at this point in the history
* #227: Move the HoverPopover spawning mechanism to the patched onLinkHover method

* omit the waitTime parameter of overPopover, set the time out in onLinkHover to 100ms

* fix: page preview enable and disable will cause core.json return {}

* fix: update

* fix: update

* fix: update

* feat: support live preview widget preview

* fix: update the fix of page preview, and revert the update to 0.9.5

* fix: conficts

* fix: conficts

* fix: conficts

* fix: conficts

* fix: conficts

* chore: remove unused code

* chore: bump version

* chore: bump version

---------

Co-authored-by: RyotaUshio <ushio@ms.k.u-tokyo.ac.jp>
  • Loading branch information
Quorafind and RyotaUshio authored Apr 22, 2024
1 parent 0bb7782 commit 7a95f43
Show file tree
Hide file tree
Showing 15 changed files with 1,251 additions and 40 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "surfing",
"name": "Surfing",
"version": "0.9.8",
"version": "0.9.9",
"minAppVersion": "1.4.0",
"description": "Surf the Net in Obsidian.",
"author": "Boninall & Windily-cloud",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "surfing",
"version": "0.9.8",
"version": "0.9.9",
"description": "Use surfing to surf the net in Obsidian.",
"main": "main.js",
"scripts": {
Expand Down
21 changes: 21 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -867,3 +867,24 @@ div[data-type^="surfing-tab-tree"] ul li {
.popover.hover-editor .popover-content:has(div[data-type^="surfing-view"]) {
width: 100%;
}

.cm-browser-widget {
border: 1px solid var(--background-modifier-border);
}

.cm-browser-widget .wb-browser-inline {
height: max(4vw, 400px);
}

.cm-browser-widget .wb-show-original-code {
position: absolute;
right: var(--size-4-2);
top: var(--size-4-2);
visibility: hidden;
}

.cm-browser-widget:hover .wb-show-original-code {
visibility: visible;
}


81 changes: 60 additions & 21 deletions src/component/InNodeWebView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { InPageHeaderBar } from "./InPageHeaderBar";
import { clipboard, remote } from "electron";
import { SurfingView } from "../surfingView";
import { t } from "../translations/helper";
import { moment } from "obsidian";
import { ExtraButtonComponent, moment } from "obsidian";
import { getUrl } from "../utils/url";
import SurfingPlugin from "../surfingIndex";

Expand All @@ -17,22 +17,53 @@ export class InNodeWebView {
private currentUrl: string;
private plugin: SurfingPlugin;

constructor(node: any, plugin: SurfingPlugin, canvas?: any) {
private type: 'canvas' | 'inline';

private editor: any;
private widget: any;

constructor(node: any, plugin: SurfingPlugin, type: 'canvas' | 'inline', canvas?: any) {
this.contentEl = node.contentEl;
this.node = node;
this.canvas = canvas;


console.log(this.node);
if (this.type === 'inline') {
this.editor = this.node?.editor;
this.widget = this.node?.widget;
}

this.plugin = plugin;
this.type = type;
}

onload() {
this.contentEl.empty();

this.appendSearchBar();
this.type === 'canvas' && this.appendSearchBar();
this.type === 'inline' && this.appendShowOriginalCode();
this.appendWebView();

this.contentEl.addClass("wb-view-content");
this.contentEl.toggleClass("wb-view-content", true);
this.type === 'inline' && this.contentEl.toggleClass('wb-browser-inline', true);
}

appendShowOriginalCode() {
const btnEl = this.contentEl.createEl('div');
btnEl.addClass('wb-show-original-code');
new ExtraButtonComponent(btnEl).setIcon('code-2').setTooltip(t('Show original url'));
// .onClick(() => {
// // Dispatch selection event to the codemirror editor based on widget start and end position.
// const {start, end} = this.widget;
// this.editor.dispatch({
// selection: EditorSelection.create([
// EditorSelection.range(start, end - 1),
// // EditorSelection.range(6, 7),
// EditorSelection.cursor(start)
// ], 0)
// });
// });
}

appendSearchBar() {
Expand All @@ -53,7 +84,7 @@ export class InNodeWebView {
if (oldData.url === this.currentUrl) return;
oldData.url = this.currentUrl;
this.node.setData(oldData);
this.node.canvas.requestSave();
this.node.canvas?.requestSave();

this.node.render();
});
Expand Down Expand Up @@ -277,26 +308,34 @@ export class InNodeWebView {
});

this.webviewEl.addEventListener("will-navigate", (event: any) => {
const oldData = this.node.getData();
oldData.url = event.url;
this.node.setData(oldData);
this.node.canvas.requestSave();
if (this.type === 'canvas') {
const oldData = this.node.getData();
oldData.url = event.url;
this.node.setData(oldData);
this.node.canvas?.requestSave();
} else {
this.node.url = event.url;
}
});

this.webviewEl.addEventListener("did-navigate-in-page", (event: any) => {
const oldData = this.node.getData();

if (event.url.contains("contacts.google.com/widget") || (this.node.canvas.isDragging && oldData.url === event.url)) {
// @ts-ignore
const webContents = remote.webContents.fromId(this.webviewEl.getWebContentsId());
webContents.stop();
return;
if (this.type === 'canvas') {
const oldData = this.node.getData();

if (event.url.contains("contacts.google.com/widget") || (this.node.canvas?.isDragging && oldData.url === event.url)) {
// @ts-ignore
const webContents = remote.webContents.fromId(this.webviewEl.getWebContentsId());
webContents.stop();
return;
}
if (oldData.url === event.url) return;
oldData.url = event.url;
oldData.alwaysKeepLoaded = true;
this.node.setData(oldData);
this.node.canvas?.requestSave();
} else {
this.node.url = event.url;
}
if (oldData.url === event.url) return;
oldData.url = event.url;
oldData.alwaysKeepLoaded = true;
this.node.setData(oldData);
this.node.canvas.requestSave();
});

this.webviewEl.addEventListener('destroyed', () => {
Expand Down
3 changes: 2 additions & 1 deletion src/surfingFileView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ export class SurfingFileView extends FileView {

constructor(leaf: WorkspaceLeaf) {
super(leaf);
this.allowNoFile = false;
}

async onLoadFile(file: TFile): Promise<void> {
const adapter = this.app.vault.adapter as FileSystemAdapter;
const urlString = "file:///" + (adapter.getBasePath() + "/" + file.path).toString().replace(/\s/g, "%20");
SurfingView.spawnWebBrowserView(true, { url: urlString });
SurfingView.spawnWebBrowserView(true, {url: urlString});
if (this.leaf) this.leaf.detach();
}

Expand Down
120 changes: 113 additions & 7 deletions src/surfingIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import { loadJson, saveJson } from "./utils/json";
import { hashCode, nonElectronGetPageTitle } from "./component/BookmarkManager/utils";
import { TabTreeView, WEB_BROWSER_TAB_TREE_ID } from "./component/TabTreeView/TabTreeView";
import './App.css';
import { EditorView } from "@codemirror/view";
import { Range } from '@codemirror/state';
import { Decoration, EditorView, WidgetType } from "@codemirror/view";
import { PopoverWebView } from "./component/PopoverWebView";
import { LastOpenedFiles } from "./component/LastOpenedFiles";

Expand All @@ -42,6 +43,8 @@ export default class SurfingPlugin extends Plugin {
private applyURLDebounceTimer = 0;
private urlOpened = false;

private patchInlineUrl = false;

async onload() {
await this.loadSettings();
this.checkWebBrowser();
Expand Down Expand Up @@ -82,6 +85,7 @@ export default class SurfingPlugin extends Plugin {
this.patchEmptyView();
this.patchMarkdownPreviewRenderer();
this.patchProperty();
this.settings.supportLivePreviewInlineUrl && this.patchInlinePreview();


if (requireApiVersion("1.1.0") && this.settings.useWebview) {
Expand Down Expand Up @@ -620,12 +624,13 @@ export default class SurfingPlugin extends Plugin {
return function (hoverParent: HoverParent, targetEl: HTMLElement | null, linktext: string, sourcePath: string, state: any, ...args: any[]) {
if (linktext.startsWith('http://') || linktext.startsWith('https://')) {
let { hoverPopover } = hoverParent;

if (hoverPopover && hoverPopover.state !== (PopoverState as any).Hidden && hoverPopover.targetEl === targetEl) {
return;
}
hoverPopover = new HoverPopover(hoverParent, targetEl);
hoverPopover.hoverEl.addClass('surfing-hover-popover');
setTimeout(() => {
if (hoverPopover!.state !== (PopoverState as any).Hidden) {
const parentEl = hoverPopover!.hoverEl.createDiv('surfing-hover-popover-container');
Expand All @@ -635,17 +640,17 @@ export default class SurfingPlugin extends Plugin {
}, 100);
return;
}

return old.call(this, hoverParent, targetEl, linktext, sourcePath, state, ...args);
}
};
}
}));

// Re-register the 'hover-link' & 'link-hover' workspace events handlers
if (!pagePreview.enabled) return;
pagePreview.disable();
pagePreview.enable();

this.register(() => {
if (!pagePreview.enabled) return;
pagePreview.disable();
Expand Down Expand Up @@ -845,6 +850,8 @@ export default class SurfingPlugin extends Plugin {

const renderer = property.rendered;

if (!renderer?.constructor) return false;

this.register(
around(renderer.constructor.prototype, {
render: (next: any) =>
Expand Down Expand Up @@ -923,6 +930,105 @@ export default class SurfingPlugin extends Plugin {
});
}

private patchWidget(widget: WidgetType) {
this.patchInlineUrl = true;
console.log(widget);

const jA = /^(?:https?:\/\/)?(?:www\.|m\.)?(?:youtube\.com|youtu\.be)(?:\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(?:\??(?:t|start)=([0-9]+))?(?:\S+)?$/
, WA = /^(?:https?:\/\/)?(?:mobile\.)?twitter\.com\/.+\/(\d+)/;
const imageReg = /^https?:\/\/.*\/.*\.(png|gif|webp|jpeg|jpg)($|\?.*$)/gmi;

const checkUrl = (url: any) => {
if (!url || typeof url !== 'string') {
return null;
}

let match = url.match(jA);
if (match) {
let youtubeUrl = `https://www.youtube.com/embed/${match[1]}`;
if (match[2]) {
youtubeUrl += `?start=${match[2]}`;
}
return youtubeUrl;
}

match = url.match(WA);
if (match) {
const isDarkTheme = document.body.classList.contains('theme-dark');
return `https://platform.twitter.com/embed/Tweet.html?dnt=true&theme=${isDarkTheme ? 'dark' : 'light'}&id=${match[1]}`;
}

return null;
};

const proto = widget.constructor.prototype;
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;

this.register(around(proto, {
initDOM: (next: any) =>
function (arg: any) {
if (imageReg.test(this.url)) {
console.log('image widget');
return next.call(this, arg);
} else if (checkUrl(this.url)) {
return next.call(this, arg);
} else {
const containerEl = createEl('div', {
cls: 'cm-browser-widget',
});
const widgetEl = containerEl.createDiv({
cls: 'wb-browser-widget',
});
const urlComponent = {
contentEl: widgetEl,
url: this.url,
editor: arg,
widget: this
};
this.hookClickHandler(arg, containerEl);
new InNodeWebView(urlComponent, self, 'inline').onload();

return containerEl;
}
// console.log(this.hookClickHandler);
// return next.call(this, arg);
}
}));
}

private patchInlinePreview() {
const patchDecoration = (plugin: SurfingPlugin) => {
const uninstaller = around(Decoration, {
set(old) {
return function (of: Range<Decoration> | readonly Range<Decoration>[], sort?: boolean) {
if (Array.isArray(of)) {
if (!plugin.patchInlineUrl) {
const ranges: Range<Decoration>[] = [];
for (const range of of) {
if (!plugin.patchInlineUrl) {
if (range.value.widget && range.value.widget.url) {
plugin.patchWidget(range.value.widget);
}
}
}
return old.call(this, ranges, sort);
} else {
return old.call(this, of, sort);
}
} else {
return old.call(this, of, sort);
}
};
},
});

plugin.register(uninstaller);
};

patchDecoration(this);
}

private patchEmptyView() {

const patchEmptyView = () => {
Expand Down Expand Up @@ -1006,7 +1112,7 @@ export default class SurfingPlugin extends Plugin {
// TODO: Move this with surfing view's constructor to prevent multiple htmlelement
if (this.canvas.isDragging) return;

new InNodeWebView(this, self, this?.canvas).onload();
new InNodeWebView(this, self, 'canvas', this?.canvas).onload();
};
},
});
Expand Down
Loading

0 comments on commit 7a95f43

Please sign in to comment.