add: hover to show note link preview
This commit is contained in:
parent
ef1bbe1d73
commit
13e172a96c
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"typescript.tsdk": "node_modules/typescript/lib"
|
"typescript.tsdk": "node_modules/typescript/lib"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,22 @@
|
||||||
native="true"
|
native="true"
|
||||||
preference="__prefsPrefix__.workspace.outline.keepLinks"
|
preference="__prefsPrefix__.workspace.outline.keepLinks"
|
||||||
/>
|
/>
|
||||||
<checkbox
|
<hbox align="center">
|
||||||
data-l10n-id="editor-noteLinkPreview"
|
<html:label
|
||||||
native="true"
|
data-l10n-id="editor-noteLinkPreviewType"
|
||||||
preference="__prefsPrefix__.editor.noteLinkPreview"
|
for="__addonRef__-editor-noteLinkPreviewType"
|
||||||
/>
|
></html:label>
|
||||||
|
<radiogroup
|
||||||
|
id="__addonRef__-editor-noteLinkPreviewType"
|
||||||
|
preference="__prefsPrefix__.editor.noteLinkPreviewType"
|
||||||
|
orient="horizontal"
|
||||||
|
oncommand="Zotero.__addonInstance__.api.utils.requireRestart();"
|
||||||
|
>
|
||||||
|
<radio data-l10n-id="editor-noteLinkPreview-hover" value="hover" />
|
||||||
|
<radio data-l10n-id="editor-noteLinkPreview-ctrl" value="ctrl" />
|
||||||
|
<radio data-l10n-id="editor-noteLinkPreview-disable" value="disable" />
|
||||||
|
</radiogroup>
|
||||||
|
</hbox>
|
||||||
</groupbox>
|
</groupbox>
|
||||||
<groupbox>
|
<groupbox>
|
||||||
<label><html:h2 data-l10n-id="sync-title"></html:h2></label>
|
<label><html:h2 data-l10n-id="sync-title"></html:h2></label>
|
||||||
|
|
@ -59,6 +70,7 @@
|
||||||
placeholder="-1 for disable"
|
placeholder="-1 for disable"
|
||||||
id="__addonRef__-sync-period"
|
id="__addonRef__-sync-period"
|
||||||
preference="__prefsPrefix__.syncPeriodSeconds"
|
preference="__prefsPrefix__.syncPeriodSeconds"
|
||||||
|
onchange="Zotero.__addonInstance__.api.utils.requireRestart();"
|
||||||
></html:input>
|
></html:input>
|
||||||
</hbox>
|
</hbox>
|
||||||
<hbox align="center">
|
<hbox align="center">
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,25 @@
|
||||||
color: var(--fill-primary);
|
color: var(--fill-primary);
|
||||||
}
|
}
|
||||||
.snippet.syntax {
|
.snippet.syntax {
|
||||||
background-color: color-mix(in srgb, var(--accent-yellow) 50%, transparent 50%);
|
background-color: color-mix(
|
||||||
|
in srgb,
|
||||||
|
var(--accent-yellow) 50%,
|
||||||
|
transparent 50%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.snippet.expression {
|
.snippet.expression {
|
||||||
background-color: color-mix(in srgb, var(--accent-green) 50%, transparent 50%);
|
background-color: color-mix(
|
||||||
|
in srgb,
|
||||||
|
var(--accent-green) 50%,
|
||||||
|
transparent 50%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.snippet.variable {
|
.snippet.variable {
|
||||||
background-color: color-mix(in srgb, var(--accent-azure) 50%, transparent 50%);
|
background-color: color-mix(
|
||||||
|
in srgb,
|
||||||
|
var(--accent-azure) 50%,
|
||||||
|
transparent 50%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
.snippet:hover {
|
.snippet:hover {
|
||||||
background-color: var(--fill-quinary);
|
background-color: var(--fill-quinary);
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,16 @@ editor-title = Note Editor
|
||||||
editor-expandLevel-label = Outline expand to heading level
|
editor-expandLevel-label = Outline expand to heading level
|
||||||
editor-keepLinks =
|
editor-keepLinks =
|
||||||
.label = Show note links in outline
|
.label = Show note links in outline
|
||||||
editor-noteLinkPreview =
|
editor-noteLinkPreviewType = Show preview for note link when:
|
||||||
.label = Show note link preview on hover
|
editor-noteLinkPreview-hover =
|
||||||
|
.label = Hover
|
||||||
|
editor-noteLinkPreview-ctrl =
|
||||||
|
.label = Press { PLATFORM() ->
|
||||||
|
[macos] ⌘
|
||||||
|
*[other] Ctrl
|
||||||
|
}
|
||||||
|
editor-noteLinkPreview-disable =
|
||||||
|
.label = Never
|
||||||
|
|
||||||
sync-title = Sync
|
sync-title = Sync
|
||||||
sync-period-label = Auto-sync period (seconds)
|
sync-period-label = Auto-sync period (seconds)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,16 @@ editor-title = Editor delle note
|
||||||
editor-expandLevel-label = Espansione dello schema al livello delle intestazioni
|
editor-expandLevel-label = Espansione dello schema al livello delle intestazioni
|
||||||
editor-keepLinks =
|
editor-keepLinks =
|
||||||
.label = Mostra i collegamenti delle note nello schema
|
.label = Mostra i collegamenti delle note nello schema
|
||||||
editor-noteLinkPreview =
|
editor-noteLinkPreviewType = Show preview for note link when:
|
||||||
.label = Mostra l'anteprima del link alla nota al passaggio del mouse
|
editor-noteLinkPreview-hover =
|
||||||
|
.label = Hover
|
||||||
|
editor-noteLinkPreview-ctrl =
|
||||||
|
.label = Press { PLATFORM() ->
|
||||||
|
[macos] ⌘
|
||||||
|
*[other] Ctrl
|
||||||
|
}
|
||||||
|
editor-noteLinkPreview-disable =
|
||||||
|
.label = Never
|
||||||
|
|
||||||
sync-title = Sincronizzazione
|
sync-title = Sincronizzazione
|
||||||
sync-period-label = Intervallo della sincronizzazione automatica (secondi)
|
sync-period-label = Intervallo della sincronizzazione automatica (secondi)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,16 @@ editor-title = Note Editor
|
||||||
editor-expandLevel-label = Outline расширить до уровня заголовка
|
editor-expandLevel-label = Outline расширить до уровня заголовка
|
||||||
editor-keepLinks =
|
editor-keepLinks =
|
||||||
.label = Сохранить ссылки
|
.label = Сохранить ссылки
|
||||||
editor-noteLinkPreview =
|
editor-noteLinkPreviewType = Show preview for note link when:
|
||||||
.label = Show note link preview on hover
|
editor-noteLinkPreview-hover =
|
||||||
|
.label = Hover
|
||||||
|
editor-noteLinkPreview-ctrl =
|
||||||
|
.label = Press { PLATFORM() ->
|
||||||
|
[macos] ⌘
|
||||||
|
*[other] Ctrl
|
||||||
|
}
|
||||||
|
editor-noteLinkPreview-disable =
|
||||||
|
.label = Never
|
||||||
|
|
||||||
sync-title = Синк
|
sync-title = Синк
|
||||||
sync-period-label = Авто-синк период (сек)
|
sync-period-label = Авто-синк период (сек)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,16 @@ editor-title = Not Düzenleyici
|
||||||
editor-expandLevel-label = Anahatta gösterilecek başlık düzeyleri
|
editor-expandLevel-label = Anahatta gösterilecek başlık düzeyleri
|
||||||
editor-keepLinks =
|
editor-keepLinks =
|
||||||
.label = Not bağlantılarını anahatta göster
|
.label = Not bağlantılarını anahatta göster
|
||||||
editor-noteLinkPreview =
|
editor-noteLinkPreviewType = Show preview for note link when:
|
||||||
.label = İmleci bağlantının üzerine getirdiğinde ön izlemeyi göster
|
editor-noteLinkPreview-hover =
|
||||||
|
.label = Hover
|
||||||
|
editor-noteLinkPreview-ctrl =
|
||||||
|
.label = Press { PLATFORM() ->
|
||||||
|
[macos] ⌘
|
||||||
|
*[other] Ctrl
|
||||||
|
}
|
||||||
|
editor-noteLinkPreview-disable =
|
||||||
|
.label = Never
|
||||||
|
|
||||||
sync-title = Eşitle
|
sync-title = Eşitle
|
||||||
sync-period-label = Otomatik Eşitleme Sıklığı (saniye)
|
sync-period-label = Otomatik Eşitleme Sıklığı (saniye)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,16 @@ editor-title = 笔记编辑器
|
||||||
editor-expandLevel-label = 大纲展开至标题层级
|
editor-expandLevel-label = 大纲展开至标题层级
|
||||||
editor-keepLinks =
|
editor-keepLinks =
|
||||||
.label = 在大纲中显示笔记链接
|
.label = 在大纲中显示笔记链接
|
||||||
editor-noteLinkPreview =
|
editor-noteLinkPreviewType = 笔记链接预览触发方式:
|
||||||
.label = 鼠标悬停时显示笔记链接预览
|
editor-noteLinkPreview-hover =
|
||||||
|
.label = 鼠标悬停
|
||||||
|
editor-noteLinkPreview-ctrl =
|
||||||
|
.label = 按下 { PLATFORM() ->
|
||||||
|
[macos] ⌘
|
||||||
|
*[other] Ctrl
|
||||||
|
}
|
||||||
|
editor-noteLinkPreview-disable =
|
||||||
|
.label = 从不
|
||||||
|
|
||||||
sync-title = 同步
|
sync-title = 同步
|
||||||
sync-period-label = 自动同步周期 (秒)
|
sync-period-label = 自动同步周期 (秒)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ pref("__prefsPrefix__.exportNote", false);
|
||||||
pref("__prefsPrefix__.workspace.outline.expandLevel", 2);
|
pref("__prefsPrefix__.workspace.outline.expandLevel", 2);
|
||||||
pref("__prefsPrefix__.workspace.outline.keepLinks", true);
|
pref("__prefsPrefix__.workspace.outline.keepLinks", true);
|
||||||
|
|
||||||
pref("__prefsPrefix__.editor.noteLinkPreview", true);
|
pref("__prefsPrefix__.editor.noteLinkPreviewType", "hover");
|
||||||
|
|
||||||
pref("__prefsPrefix__.openNote.takeover", true);
|
pref("__prefsPrefix__.openNote.takeover", true);
|
||||||
pref("__prefsPrefix__.openNote.defaultAsWindow", false);
|
pref("__prefsPrefix__.openNote.defaultAsWindow", false);
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ import {
|
||||||
} from "./utils/relation";
|
} from "./utils/relation";
|
||||||
import { getWorkspaceByTabID, getWorkspaceByUID } from "./utils/workspace";
|
import { getWorkspaceByTabID, getWorkspaceByUID } from "./utils/workspace";
|
||||||
import { getString } from "./utils/locale";
|
import { getString } from "./utils/locale";
|
||||||
|
import { showRestartHint } from "./utils/hint";
|
||||||
|
|
||||||
const workspace = {
|
const workspace = {
|
||||||
getWorkspaceByTabID,
|
getWorkspaceByTabID,
|
||||||
|
|
@ -181,6 +182,7 @@ const relation = {
|
||||||
|
|
||||||
const utils = {
|
const utils = {
|
||||||
getString,
|
getString,
|
||||||
|
requireRestart: showRestartHint,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ interface LinkPreviewOptions {
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
openURL: (url: string) => void;
|
openURL: (url: string) => void;
|
||||||
|
|
||||||
|
requireCtrl: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LinkPreviewState {
|
class LinkPreviewState {
|
||||||
|
|
@ -67,7 +69,7 @@ class LinkPreviewState {
|
||||||
this.node = target;
|
this.node = target;
|
||||||
this.currentLink = href;
|
this.currentLink = href;
|
||||||
this.hasHover = true;
|
this.hasHover = true;
|
||||||
this.tryOpenPopup();
|
this.tryOpenPopupByHover();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +81,24 @@ class LinkPreviewState {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tryOpenPopup() {
|
handleKeydown = async (event: KeyboardEvent) => {
|
||||||
|
if (!this.options.requireCtrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.hasHover || !this.currentLink) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const isMac =
|
||||||
|
typeof navigator != "undefined" ? /Mac/.test(navigator.platform) : false;
|
||||||
|
if ((isMac && event.metaKey) || (!isMac && event.ctrlKey)) {
|
||||||
|
this.tryTogglePopupByKey();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tryOpenPopupByHover() {
|
||||||
|
if (this.options.requireCtrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const href = this.currentLink!;
|
const href = this.currentLink!;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.currentLink === href) {
|
if (this.currentLink === href) {
|
||||||
|
|
@ -88,6 +107,14 @@ class LinkPreviewState {
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tryTogglePopupByKey() {
|
||||||
|
if (this._hasPopup()) {
|
||||||
|
this._closePopup();
|
||||||
|
} else {
|
||||||
|
this._openPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_openPopup() {
|
_openPopup() {
|
||||||
console.log("Enter Link Preview", this.currentLink, this.options);
|
console.log("Enter Link Preview", this.currentLink, this.options);
|
||||||
document.querySelectorAll(".link-preview").forEach((el) => el.remove());
|
document.querySelectorAll(".link-preview").forEach((el) => el.remove());
|
||||||
|
|
@ -158,6 +185,10 @@ class LinkPreviewState {
|
||||||
document.querySelectorAll(".link-preview").forEach((el) => el.remove());
|
document.querySelectorAll(".link-preview").forEach((el) => el.remove());
|
||||||
this.popup = null;
|
this.popup = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hasPopup() {
|
||||||
|
return !!document.querySelector(".link-preview");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initLinkPreviewPlugin(options: LinkPreviewOptions) {
|
function initLinkPreviewPlugin(options: LinkPreviewOptions) {
|
||||||
|
|
@ -185,6 +216,10 @@ function initLinkPreviewPlugin(options: LinkPreviewOptions) {
|
||||||
pluginState.update(view.state);
|
pluginState.update(view.state);
|
||||||
pluginState.handleMouseMove(event);
|
pluginState.handleMouseMove(event);
|
||||||
},
|
},
|
||||||
|
keydown: (view, event) => {
|
||||||
|
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||||
|
pluginState.handleKeydown(event);
|
||||||
|
},
|
||||||
wheel: (view, event) => {
|
wheel: (view, event) => {
|
||||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||||
pluginState.popup?.layoutPopup(pluginState);
|
pluginState.popup?.layoutPopup(pluginState);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,11 @@ import { showSyncDiff } from "./modules/sync/diffWindow";
|
||||||
import { showSyncInfo } from "./modules/sync/infoWindow";
|
import { showSyncInfo } from "./modules/sync/infoWindow";
|
||||||
import { showSyncManager } from "./modules/sync/managerWindow";
|
import { showSyncManager } from "./modules/sync/managerWindow";
|
||||||
import { showTemplateEditor } from "./modules/template/editorWindow";
|
import { showTemplateEditor } from "./modules/template/editorWindow";
|
||||||
import { createNoteFromTemplate, createNoteFromMD, createNote } from "./modules/createNote";
|
import {
|
||||||
|
createNoteFromTemplate,
|
||||||
|
createNoteFromMD,
|
||||||
|
createNote,
|
||||||
|
} from "./modules/createNote";
|
||||||
import { createZToolkit } from "./utils/ztoolkit";
|
import { createZToolkit } from "./utils/ztoolkit";
|
||||||
import { waitUtilAsync } from "./utils/wait";
|
import { waitUtilAsync } from "./utils/wait";
|
||||||
import { initSyncList } from "./modules/sync/api";
|
import { initSyncList } from "./modules/sync/api";
|
||||||
|
|
|
||||||
|
|
@ -442,7 +442,8 @@ function getTextBetweenLines(
|
||||||
}
|
}
|
||||||
|
|
||||||
function initLinkPreview(editor: Zotero.EditorInstance) {
|
function initLinkPreview(editor: Zotero.EditorInstance) {
|
||||||
if (!getPref("editor.noteLinkPreview")) {
|
const previewType = getPref("editor.noteLinkPreviewType") as string;
|
||||||
|
if (!["hover", "ctrl"].includes(previewType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const EditorAPI = getEditorAPI(editor);
|
const EditorAPI = getEditorAPI(editor);
|
||||||
|
|
@ -469,6 +470,7 @@ function initLinkPreview(editor: Zotero.EditorInstance) {
|
||||||
openURL: (url: string) => {
|
openURL: (url: string) => {
|
||||||
Zotero.getActiveZoteroPane().loadURI(url);
|
Zotero.getActiveZoteroPane().loadURI(url);
|
||||||
},
|
},
|
||||||
|
requireCtrl: previewType === "ctrl",
|
||||||
},
|
},
|
||||||
editor._iframeWindow,
|
editor._iframeWindow,
|
||||||
{ wrapReflectors: true, cloneFunctions: true },
|
{ wrapReflectors: true, cloneFunctions: true },
|
||||||
|
|
|
||||||
|
|
@ -42,4 +42,27 @@ async function showHintWithLink(
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { showHint, showHintWithLink };
|
function showRestartHint() {
|
||||||
|
const ps = Services.prompt;
|
||||||
|
const buttonFlags =
|
||||||
|
ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING +
|
||||||
|
ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING;
|
||||||
|
const index = ps.confirmEx(
|
||||||
|
// @ts-ignore
|
||||||
|
null,
|
||||||
|
Zotero.getString("general.restartRequired"),
|
||||||
|
Zotero.getString("general.restartRequiredForChange", Zotero.appName),
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString("general.restartNow"),
|
||||||
|
Zotero.getString("general.restartLater"),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
Zotero.Utilities.Internal.quit(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { showHint, showHintWithLink, showRestartHint };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue