Convert ItemPane{SectionElement,Container}Base to ES modules
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run

This commit is contained in:
Abe Jellinek 2026-05-14 12:06:29 -04:00 committed by Dan Stillman
parent c2a9ea2687
commit b7437faf55
20 changed files with 257 additions and 161 deletions

View file

@ -28,8 +28,6 @@
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js", this);
Services.scriptloader.loadSubScript("chrome://global/content/customElements.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/base.js", this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemPaneSection.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemPaneContainer.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemTreeMenuBar.js', this);
{
@ -63,6 +61,7 @@ Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemTreeMe
['zoterosearchcondition', 'chrome://zotero/content/elements/zoteroSearch.js'],
['zoterosearchtextbox', 'chrome://zotero/content/elements/zoteroSearch.js'],
['zoterosearchagefield', 'chrome://zotero/content/elements/zoteroSearch.js'],
['item-pane-custom-section', 'chrome://zotero/content/elements/itemPaneCustomSection.js'],
['item-pane-header', 'chrome://zotero/content/elements/itemPaneHeader.js'],
['editable-text', 'chrome://zotero/content/elements/editableText.js'],
['item-pane-sidenav', 'chrome://zotero/content/elements/itemPaneSidenav.js'],

View file

@ -26,6 +26,10 @@
"use strict";
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
ChromeUtils.importESModule("chrome://zotero/content/actors/ActorManager.mjs");
const SANDBOX_ALL_FLAGS = 0xFFFFF;

View file

@ -24,6 +24,11 @@
*/
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class AttachmentAnnotationsBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-attachments-annotations" data-pane="attachment-annotations">

View file

@ -28,6 +28,10 @@
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
let { canRenameFileFromParent, renameFileFromParent } = ChromeUtils.importESModule("chrome://zotero/content/renameFiles.mjs");
class AttachmentBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`

View file

@ -24,6 +24,11 @@
*/
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class PreviewRenderAbortError extends Error {
constructor() {
super("AttachmentPreview render aborted");

View file

@ -25,6 +25,11 @@
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class AttachmentPreviewBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-attachment-preview" data-pane="attachment-preview">

View file

@ -26,6 +26,11 @@
"use strict";
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class AttachmentsBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-attachments" data-pane="attachments" extra-buttons="add">

View file

@ -24,6 +24,11 @@
*/
{
const { ItemPaneContainerBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneContainerBase.mjs",
{ global: "current" }
);
let lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
mergeItems: "chrome://zotero/content/mergeItems.mjs",

View file

@ -26,6 +26,10 @@
"use strict";
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
const { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
const lazy = {};

View file

@ -24,6 +24,11 @@
*/
{
const { ItemPaneContainerBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneContainerBase.mjs",
{ global: "current" }
);
class ItemDetails extends ItemPaneContainerBase {
content = MozXULElement.parseXULToFragment(`
<hbox id="zotero-view-item-container" class="zotero-view-item-container" flex="1">

View file

@ -23,7 +23,6 @@
***** END LICENSE BLOCK *****
*/
/**
* Base class for elements that host a vertical stack of [data-pane] sections
* controlled by an <item-pane-sidenav>.
@ -40,8 +39,7 @@
* render of following panes, etc.) can override the _beforeScrollToPane() and
* _afterScrollToPane() hooks.
*/
// eslint-disable-next-line no-unused-vars
class ItemPaneContainerBase extends XULElementBase {
export class ItemPaneContainerBase extends XULElementBase {
_paneParent = null;
connectedCallback() {

View file

@ -23,162 +23,14 @@
***** END LICENSE BLOCK *****
*/
class ItemPaneSectionElementBase extends XULElementBase {
get item() {
return this._item;
}
set item(item) {
this._item = item;
if (this._handleItemChange) this._handleItemChange();
}
get editable() {
return this._editable;
}
set editable(editable) {
this._editable = editable;
this.toggleAttribute('readonly', !editable);
}
get tabID() {
return this._tabID;
}
set tabID(tabID) {
this._tabID = tabID;
}
get tabType() {
return this._tabType;
}
set tabType(tabType) {
this._tabType = tabType;
this.setAttribute('tabType', tabType);
}
get collectionTreeRow() {
return this._collectionTreeRow;
}
set collectionTreeRow(collectionTreeRow) {
this._collectionTreeRow = collectionTreeRow;
}
_syncRenderPending = false;
_asyncRenderPending = false;
/** Controlled by parent element */
skipRender = false;
get open() {
return this._section?.open || false;
}
set open(val) {
if (this._section) {
this._section.open = val;
}
}
get collapsible() {
return this._section.collapsible;
}
set collapsible(val) {
this._section.collapsible = !!val;
}
connectedCallback() {
super.connectedCallback();
if (!this.render && !this.asyncRender) {
Zotero.warn("Pane section must have method render or asyncRender.");
}
}
disconnectedCallback() {
super.disconnectedCallback();
if (this._section) {
this._section.removeEventListener("toggle", this._handleSectionToggle);
this._section = null;
}
this._resetRenderedFlags();
}
initCollapsibleSection() {
this._section = this.querySelector('collapsible-section');
if (this._section) {
this._section.addEventListener("toggle", this._handleSectionToggle);
}
}
_handleSectionToggle = async (event) => {
if (event.target !== this._section || !this._section.open) {
return;
}
await this._forceRenderAll();
};
get _renderDependencies() {
return [this._tabID, this._item?.id];
}
/**
* @param {"sync" | "async"} [type]
* @returns {boolean}
*/
_isAlreadyRendered(type = "sync") {
let key = `_${type}RenderDependencies`;
let pendingKey = `_${type}RenderPending`;
let itemIDKey = `_${type}RenderItemID`;
let oldDependencies = this[key];
let newDependencies = this._renderDependencies;
let isPending = this[pendingKey];
let isRendered = Zotero.Utilities.arrayEquals(oldDependencies, newDependencies);
if (this.skipRender) {
if (!isRendered) {
this[pendingKey] = true;
}
// Skip render
return true;
}
if (!isPending && isRendered) {
return true;
}
this[key] = newDependencies;
this[pendingKey] = false;
this[itemIDKey] = this.item?.id;
return false;
}
_resetRenderedFlags() {
// Clear cached flags to allow re-rendering
delete this._syncRenderDependencies;
delete this._syncRenderItemID;
delete this._asyncRenderDependencies;
delete this._asyncRenderItemID;
}
async _forceRenderAll() {
this._resetRenderedFlags();
if (this.hidden || this.skipRender) {
this._syncRenderPending = true;
this._asyncRenderPending = true;
return;
}
if (this.render) this.render();
if (this.asyncRender) await this.asyncRender();
}
}
"use strict";
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class ItemPaneCustomSection extends ItemPaneSectionElementBase {
_hooks = {};

View file

@ -26,6 +26,11 @@
"use strict";
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
const PREF_HEADER_MODE = 'itemPaneHeader';
const PREF_BIB_ENTRY_STYLE = 'itemPaneHeader.bibEntry.style';
const PREF_BIB_ENTRY_LOCALE = 'itemPaneHeader.bibEntry.locale';

View file

@ -0,0 +1,178 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2024 Corporation for Digital Scholarship
Vienna, Virginia, USA
https://www.zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
*/
export class ItemPaneSectionElementBase extends XULElementBase {
get item() {
return this._item;
}
set item(item) {
this._item = item;
if (this._handleItemChange) this._handleItemChange();
}
get editable() {
return this._editable;
}
set editable(editable) {
this._editable = editable;
this.toggleAttribute('readonly', !editable);
}
get tabID() {
return this._tabID;
}
set tabID(tabID) {
this._tabID = tabID;
}
get tabType() {
return this._tabType;
}
set tabType(tabType) {
this._tabType = tabType;
this.setAttribute('tabType', tabType);
}
get collectionTreeRow() {
return this._collectionTreeRow;
}
set collectionTreeRow(collectionTreeRow) {
this._collectionTreeRow = collectionTreeRow;
}
_syncRenderPending = false;
_asyncRenderPending = false;
/** Controlled by parent element */
skipRender = false;
get open() {
return this._section?.open || false;
}
set open(val) {
if (this._section) {
this._section.open = val;
}
}
get collapsible() {
return this._section.collapsible;
}
set collapsible(val) {
this._section.collapsible = !!val;
}
connectedCallback() {
super.connectedCallback();
if (!this.render && !this.asyncRender) {
Zotero.warn("Pane section must have method render or asyncRender.");
}
}
disconnectedCallback() {
super.disconnectedCallback();
if (this._section) {
this._section.removeEventListener("toggle", this._handleSectionToggle);
this._section = null;
}
this._resetRenderedFlags();
}
initCollapsibleSection() {
this._section = this.querySelector('collapsible-section');
if (this._section) {
this._section.addEventListener("toggle", this._handleSectionToggle);
}
}
_handleSectionToggle = async (event) => {
if (event.target !== this._section || !this._section.open) {
return;
}
await this._forceRenderAll();
};
get _renderDependencies() {
return [this._tabID, this._item?.id];
}
/**
* @param {"sync" | "async"} [type]
* @returns {boolean}
*/
_isAlreadyRendered(type = "sync") {
let key = `_${type}RenderDependencies`;
let pendingKey = `_${type}RenderPending`;
let itemIDKey = `_${type}RenderItemID`;
let oldDependencies = this[key];
let newDependencies = this._renderDependencies;
let isPending = this[pendingKey];
let isRendered = Zotero.Utilities.arrayEquals(oldDependencies, newDependencies);
if (this.skipRender) {
if (!isRendered) {
this[pendingKey] = true;
}
// Skip render
return true;
}
if (!isPending && isRendered) {
return true;
}
this[key] = newDependencies;
this[pendingKey] = false;
this[itemIDKey] = this.item?.id;
return false;
}
_resetRenderedFlags() {
// Clear cached flags to allow re-rendering
delete this._syncRenderDependencies;
delete this._syncRenderItemID;
delete this._asyncRenderDependencies;
delete this._asyncRenderItemID;
}
async _forceRenderAll() {
this._resetRenderedFlags();
if (this.hidden || this.skipRender) {
this._syncRenderPending = true;
this._asyncRenderPending = true;
return;
}
if (this.render) this.render();
if (this.asyncRender) await this.asyncRender();
}
}

View file

@ -28,6 +28,11 @@
import { getCSSIcon } from 'components/icons';
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class LibrariesCollectionsBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-libraries-collections" data-pane="libraries-collections" extra-buttons="add">

View file

@ -25,6 +25,10 @@
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
let { countWords } = ChromeUtils.importESModule("resource://zotero/allfaz.mjs").default;
class NoteBox extends ItemPaneSectionElementBase {

View file

@ -28,6 +28,11 @@
import { getCSSItemTypeIcon } from 'components/icons';
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class NotesBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-notes" data-pane="notes" extra-buttons="add">

View file

@ -28,6 +28,11 @@
import { getCSSItemTypeIcon } from 'components/icons';
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class RelatedBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-related" data-pane="related" extra-buttons="add">

View file

@ -26,6 +26,11 @@
"use strict";
{
const { ItemPaneSectionElementBase } = ChromeUtils.importESModule(
"chrome://zotero/content/elements/itemPaneSectionElementBase.mjs",
{ global: "current" }
);
class TagsBox extends ItemPaneSectionElementBase {
content = MozXULElement.parseXULToFragment(`
<collapsible-section data-l10n-id="section-tags" data-pane="tags" extra-buttons="add">

View file

@ -47,8 +47,6 @@ export default [
XULElementBase: "readonly",
XULElementMixin: "readonly",
XULTextElement: "readonly",
ItemPaneSectionElementBase: "readonly",
ItemPaneContainerBase: "readonly",
Cu: "readonly",
ChromeWorker: "readonly",
Localization: "readonly",