fix: workspace window

This commit is contained in:
windingwind 2024-04-06 21:42:09 +08:00
parent 30fc3c8e86
commit 3a42791729
15 changed files with 254 additions and 47 deletions

View File

@ -0,0 +1,61 @@
bn-related-box {
display: flex;
flex-direction: column;
gap: 2px;
}
bn-related-box[hidden] {
display: none;
}
bn-related-box[readonly] .add {
display: none;
}
bn-related-box .body {
display: flex;
flex-direction: column;
padding-inline-start: 12px;
}
bn-related-box .body .row {
display: flex;
gap: 4px;
align-items: flex-start;
}
[zoteroUIDensity="comfortable"] bn-related-box .body .row {
padding-block: 2px;
}
bn-related-box .body .row .box {
display: flex;
align-items: flex-start;
gap: 4px;
padding-inline-start: 4px;
overflow: hidden;
border-radius: 5px;
flex: 1;
}
bn-related-box .body .row .box:not([disabled]):hover {
background-color: var(--fill-quinary);
}
bn-related-box .body .row .box:not([disabled]):active {
background-color: var(--fill-quarternary);
}
bn-related-box .body .row .box .icon {
height: calc(1.3333333333 * var(--zotero-font-size));
}
bn-related-box .body .row .box .label {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 10;
width: 0;
flex: 1;
overflow: hidden;
}
bn-related-box .body .row .box .icon,
bn-related-box .body .row .box .label {
padding-block: 2px;
}
bn-related-box .body .row toolbarbutton {
margin-inline-start: auto;
visibility: hidden;
}
bn-related-box .body .row:is(:hover, :focus-within) toolbarbutton {
visibility: visible;
}

View File

@ -4,7 +4,7 @@
<!-- prettier-ignore -->
<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?>
<!-- prettier-ignore -->
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css" type="text/css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero.css" type="text/css"?>
<!-- prettier-ignore -->
<!DOCTYPE html>
<html
@ -20,41 +20,16 @@
<head>
<title data-l10n-id="title"></title>
<meta charset="utf-8" />
<script>
document.addEventListener("DOMContentLoaded", (ev) => {
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm",
);
Services.scriptloader.loadSubScript(
"chrome://zotero/content/include.js",
this,
);
Services.scriptloader.loadSubScript(
"resource://zotero/require.js",
this,
);
if (Zotero.platformMajorVersion >= 102) {
Services.scriptloader.loadSubScript(
"chrome://global/content/customElements.js",
this,
);
if (!customElements.get("note-editor")) {
Services.scriptloader.loadSubScript(
"chrome://zotero/content/elements/shadowAutocompleteInput.js",
this,
);
Services.scriptloader.loadSubScript(
"chrome://zotero/content/elements/noteEditor.js",
this,
);
}
}
window.arguments[0]._initPromise.resolve();
});
</script>
<script src="chrome://zotero/content/include.js"></script>
<script src="chrome://zotero/content/customElements.js"></script>
<script src="chrome://__addonRef__/content/scripts/customElements.js"></script>
<script src="chrome://__addonRef__/content/scripts/workspaceWindow.js"></script>
<xul:linkset>
<link rel="localization" href="browser/menubar.ftl" />
<link rel="localization" href="browser/browserSets.ftl" />
<link rel="localization" href="toolkit/global/textActions.ftl" />
<link rel="localization" href="zotero.ftl" />
</xul:linkset>
<style>
html,
body {
@ -76,6 +51,18 @@
<link rel="localization" href="__addonRef__-workspaceWindow.ftl" />
</head>
<body class="zotero-window">
<xul:commandset id="mainCommandSet">
<xul:command id="cmd_close" oncommand="window.close();" />
</xul:commandset>
<xul:keyset id="mainKeyset">
<xul:key
id="key_close"
data-l10n-id="close-shortcut"
command="cmd_close"
modifiers="accel"
reserved="true"
/>
</xul:keyset>
<div id="workspace-container"></div>
</body>
</html>

View File

@ -74,7 +74,8 @@ workspace-emptyWorkspaceGuideCreate = Create a new note
editor-toolbar-main = Workspace Note
editor-toolbar-settings-title = Workspace Settings
editor-toolbar-settings-openWorkspace = Open Note Workspace
editor-toolbar-settings-openAsTab = Open as tab
editor-toolbar-settings-openAsWindow = Open as window
editor-toolbar-settings-setWorkspace = Set as Workspace Note
editor-toolbar-settings-previewInWorkspace = Preview in Workspace
editor-toolbar-settings-showInLibrary = Show in Library

View File

@ -70,7 +70,8 @@ workspace-emptyWorkspaceGuideCreate = Crea una nuova nota
editor-toolbar-main = Nota di lavoro
editor-toolbar-settings-title = Impostazioni dello spazio di lavoro
editor-toolbar-settings-openWorkspace = Apri nota di lavoro
editor-toolbar-settings-openAsTab = Open as tab
editor-toolbar-settings-openAsWindow = Open as window
editor-toolbar-settings-setWorkspace = Imposta come nota di lavoro
editor-toolbar-settings-previewInWorkspace = Anteprima nello spazio di lavoro
editor-toolbar-settings-showInLibrary = Show in Library

View File

@ -74,7 +74,8 @@ workspace-emptyWorkspaceGuideCreate = Create a new note
editor-toolbar-main=Заметка рабочего пространства
editor-toolbar-settings-title=Настройки рабочего пространства
editor-toolbar-settings-openWorkspace=Открыть пространство заметок
editor-toolbar-settings-openAsTab = Open as tab
editor-toolbar-settings-openAsWindow = Open as window
editor-toolbar-settings-setWorkspace=Установить как Заметку раб. пространства
editor-toolbar-settings-previewInWorkspace=Предпросмотр в рабочем пространстве
editor-toolbar-settings-showInLibrary = Show in Library

View File

@ -74,7 +74,8 @@ workspace-emptyWorkspaceGuideCreate = Yeni bir not oluşturun
editor-toolbar-main = Çalışma Alanı Notu
editor-toolbar-settings-title = Çalışma Alanı Ayarları
editor-toolbar-settings-openWorkspace = Not Çalışma Alanıın
editor-toolbar-settings-openAsTab = Open as tab
editor-toolbar-settings-openAsWindow = Open as window
editor-toolbar-settings-setWorkspace = Çalışma Alanı Notu Olarak Ayarla
editor-toolbar-settings-previewInWorkspace = Çalışma Alanında Ön İzle Preview in Workspace
editor-toolbar-settings-showInLibrary = Show in Library

View File

@ -74,7 +74,8 @@ workspace-emptyWorkspaceGuideCreate = 创建新笔记
editor-toolbar-main=工作区笔记
editor-toolbar-settings-title=工作区选项
editor-toolbar-settings-openWorkspace=打开笔记工作区
editor-toolbar-settings-openAsTab = 在标签页中打开
editor-toolbar-settings-openAsWindow = 在窗口中打开
editor-toolbar-settings-setWorkspace=设为工作区笔记
editor-toolbar-settings-previewInWorkspace=在工作区预览
editor-toolbar-settings-showInLibrary = 在文库中显示

View File

@ -15,7 +15,7 @@ export class NoteDetails extends ItemDetails {
<html:div id="zotero-view-item" class="zotero-view-item" tabindex="0">
<tags-box id="zotero-editpane-tags" class="zotero-editpane-tags" data-pane="tags" />
<related-box id="zotero-editpane-related" class="zotero-editpane-related"
<bn-related-box id="zotero-editpane-related" class="zotero-editpane-related"
data-pane="related" />
</html:div>
</html:div>

103
src/elements/related.ts Normal file
View File

@ -0,0 +1,103 @@
// @ts-nocheck
import { config } from "../../package.json";
const RelatedBox = customElements.get("related-box")! as typeof XULElementBase;
const _require = window.require;
const { getCSSItemTypeIcon } = _require("components/icons");
export class NoteRelatedBox extends RelatedBox {
content = MozXULElement.parseXULToFragment(`
<linkset>
<html:link
rel="stylesheet"
href="chrome://${config.addonRef}/content/styles/related.css"
></html:link>
</linkset>
<collapsible-section
data-l10n-id="section-related"
data-pane="related"
extra-buttons="add"
>
<html:div class="body" />
</collapsible-section>`);
// Following code is from chrome/content/zotero/elements/relatedBox.js
render() {
if (!this.item) return;
if (this._isAlreadyRendered()) return;
const body = this.querySelector(".body");
body.replaceChildren();
if (this._item) {
const relatedKeys = this._item.relatedItems;
for (let i = 0; i < relatedKeys.length; i++) {
const key = relatedKeys[i];
const relatedItem = Zotero.Items.getByLibraryAndKey(
this._item.libraryID,
key,
);
if (!relatedItem) {
Zotero.debug(
`Related item ${this._item.libraryID}/${key} not found ` +
`for item ${this._item.libraryKey}`,
2,
);
continue;
}
const id = relatedItem.id;
const row = document.createElement("div");
row.className = "row";
const icon = getCSSItemTypeIcon(relatedItem.getItemTypeIconName());
const label = document.createElement("span");
label.className = "label";
label.append(relatedItem.getDisplayTitle());
const box = document.createElement("div");
box.addEventListener("click", () => this._handleShowItem(id));
box.setAttribute("tabindex", "0");
box.className = "box keyboard-clickable";
box.appendChild(icon);
box.appendChild(label);
row.append(box);
// Extra button to open note
if (relatedItem.isNote()) {
const note = document.createXULElement("toolbarbutton");
note.addEventListener("command", (event) => {
const position = event.shiftKey ? "window" : "workspace";
Zotero[config.addonRef].hooks.onOpenNote(id, position);
});
note.className = "zotero-clicky zotero-clicky-open-link";
note.setAttribute("tabindex", "0");
row.append(note);
}
if (this.editable) {
const remove = document.createXULElement("toolbarbutton");
remove.addEventListener("command", () => this._handleRemove(id));
remove.className = "zotero-clicky zotero-clicky-minus";
remove.setAttribute("tabindex", "0");
row.append(remove);
}
body.append(row);
}
this._updateCount();
}
}
_handleShowItem(id: number) {
const item = Zotero.Items.get(id);
if (!item) return;
if (!item.isNote()) {
// @ts-ignore
return super._handleShowItem(id);
}
// TODO: open in sidebar
Zotero[config.addonRef].hooks.onOpenNote(id, "workspace");
}
}

View File

@ -2,6 +2,7 @@ import { ContextPane } from "../elements/context";
import { NoteDetails } from "../elements/detailsPane";
import { NotePicker } from "../elements/notePicker";
import { OutlinePane } from "../elements/outlinePane";
import { NoteRelatedBox } from "../elements/related";
import { Workspace } from "../elements/workspace";
const elements = {
@ -10,6 +11,7 @@ const elements = {
"bn-details": NoteDetails as unknown as CustomElementConstructor,
"bn-workspace": Workspace,
"bn-note-picker": NotePicker,
"bn-related-box": NoteRelatedBox,
};
for (const [key, constructor] of Object.entries(elements)) {

View File

@ -0,0 +1,37 @@
window.addEventListener("DOMContentLoaded", () => {
const registeredKey = Zotero.Notifier.registerObserver({
notify(action, type, ids, extraData) {
if (action === "modify" && type === "item") {
const item = getItem();
if ((ids as number[]).includes(item.id)) {
updateTitle();
}
}
},
});
window.addEventListener(
"unload",
() => {
Zotero.Notifier.unregisterObserver(registeredKey);
},
{ once: true },
);
// @ts-ignore
window.arguments[0]._initPromise.resolve();
});
function updateTitle() {
const item = getItem();
if (item?.isNote()) {
document.title = item.getNoteTitle();
}
}
function getItem() {
// @ts-ignore
return document.querySelector("bn-workspace")?.item as Zotero.Item;
}
window.updateTitle = updateTitle;

View File

@ -146,7 +146,7 @@ async function onPrefsEvent(type: string, data: { [key: string]: any }) {
function onOpenNote(
noteId: number,
mode: "auto" | "preview" | "workspace" | "standalone" = "auto",
mode: "auto" | "preview" | "workspace" | "standalone" | "window" = "auto",
options: {
lineIndex?: number;
sectionName?: string;
@ -167,6 +167,9 @@ function onOpenNote(
case "workspace":
addon.hooks.onOpenWorkspace(noteItem, "tab");
break;
case "window":
addon.hooks.onOpenWorkspace(noteItem, "window");
break;
case "standalone":
ZoteroPane.openNoteWindow(noteId);
break;

View File

@ -67,12 +67,19 @@ async function getMenuData(editor: Zotero.EditorInstance) {
const currentSection = slice(getSectionAtCursor(editor) || "", 10);
const settingsMenuData: PopupData[] = [
{
id: makeId("settings-openWorkspace"),
text: getString("editor.toolbar.settings.openWorkspace"),
id: makeId("settings-openAsTab"),
text: getString("editor.toolbar.settings.openAsTab"),
callback: (e) => {
addon.hooks.onOpenWorkspace(noteItem, "tab");
},
},
{
id: makeId("settings-openAsWindow"),
text: getString("editor.toolbar.settings.openAsWindow"),
callback: (e) => {
addon.hooks.onOpenWorkspace(noteItem, "window");
},
},
{
id: makeId("settings-showInLibrary"),
text: getString("editor.toolbar.settings.showInLibrary"),

View File

@ -1,5 +1,3 @@
import { saveFreeMind as _saveFreeMind } from "../export/freemind";
export function initWorkspace(container: XUL.Box, item: Zotero.Item) {
if (!container) {
return;

View File

@ -16,4 +16,8 @@ export async function openWorkspaceWindow(item: Zotero.Item) {
"#workspace-container",
) as XUL.Box;
addon.hooks.onInitWorkspace(container, item);
win.focus();
// @ts-ignore
win.updateTitle();
}