add: utils
This commit is contained in:
		
							parent
							
								
									7de5e38d81
								
							
						
					
					
						commit
						6f752cd451
					
				@ -35,6 +35,6 @@
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/node": "^18.7.20",
 | 
			
		||||
    "release-it": "^14.14.0",
 | 
			
		||||
    "zotero-types": "^0.0.7"
 | 
			
		||||
    "zotero-types": "^0.0.8"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								src/addon.ts
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/addon.ts
									
									
									
									
									
								
							@ -1,13 +1,14 @@
 | 
			
		||||
import AddonEvents from "./events";
 | 
			
		||||
import AddonPrefs from "./prefs";
 | 
			
		||||
import AddonUtils from "./utils";
 | 
			
		||||
import AddonViews from "./views";
 | 
			
		||||
 | 
			
		||||
const { addonName } = require("../package.json");
 | 
			
		||||
 | 
			
		||||
class Addon {
 | 
			
		||||
  public Zotero: _ZoteroConstructable;
 | 
			
		||||
  public events: AddonEvents;
 | 
			
		||||
  public views: AddonViews;
 | 
			
		||||
  public prefs: AddonPrefs;
 | 
			
		||||
  public utils: AddonUtils;
 | 
			
		||||
  // root path to access the resources
 | 
			
		||||
  public rootURI: string;
 | 
			
		||||
 | 
			
		||||
@ -15,32 +16,8 @@ class Addon {
 | 
			
		||||
    this.events = new AddonEvents(this);
 | 
			
		||||
    this.views = new AddonViews(this);
 | 
			
		||||
    this.prefs = new AddonPrefs(this);
 | 
			
		||||
    this.utils = new AddonUtils(this);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getZotero(): _ZoteroConstructable {
 | 
			
		||||
  if (typeof Zotero === "undefined") {
 | 
			
		||||
    return Components.classes["@zotero.org/Zotero;1"].getService(
 | 
			
		||||
      Components.interfaces.nsISupports
 | 
			
		||||
    ).wrappedJSObject;
 | 
			
		||||
  }
 | 
			
		||||
  return Zotero;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function isZotero7(): boolean {
 | 
			
		||||
  return Zotero.platformMajorVersion >= 102;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createXULElement(doc: Document, type: string): XUL.Element {
 | 
			
		||||
  if (isZotero7()) {
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    return doc.createXULElement(type);
 | 
			
		||||
  } else {
 | 
			
		||||
    return doc.createElementNS(
 | 
			
		||||
      "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
 | 
			
		||||
      type
 | 
			
		||||
    ) as XUL.Element;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { addonName, Addon, getZotero, isZotero7, createXULElement };
 | 
			
		||||
export default Addon;
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import { Addon, addonName, getZotero } from "./addon";
 | 
			
		||||
import Addon from "./addon";
 | 
			
		||||
import AddonModule from "./module";
 | 
			
		||||
import { addonName } from "../package.json";
 | 
			
		||||
 | 
			
		||||
class AddonEvents extends AddonModule {
 | 
			
		||||
  private notifierCallback: any;
 | 
			
		||||
@ -27,8 +28,8 @@ class AddonEvents extends AddonModule {
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async onInit() {
 | 
			
		||||
    const Zotero = getZotero();
 | 
			
		||||
  public async onInit(_Zotero: _ZoteroConstructable) {
 | 
			
		||||
    this._Addon.Zotero = _Zotero;
 | 
			
		||||
    // This function is the setup code of the addon
 | 
			
		||||
    Zotero.debug(`${addonName}: init called`);
 | 
			
		||||
    // alert(112233);
 | 
			
		||||
@ -70,7 +71,7 @@ class AddonEvents extends AddonModule {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public onUnInit(): void {
 | 
			
		||||
    const Zotero = getZotero();
 | 
			
		||||
    const Zotero = this._Addon.Zotero;
 | 
			
		||||
    Zotero.debug(`${addonName}: uninit called`);
 | 
			
		||||
    //  Remove elements and do clean up
 | 
			
		||||
    this._Addon.views.unInitViews();
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
import { Addon, getZotero } from "./addon";
 | 
			
		||||
import Addon from "./addon";
 | 
			
		||||
 | 
			
		||||
const Zotero = getZotero();
 | 
			
		||||
const Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
 | 
			
		||||
  Components.interfaces.nsISupports
 | 
			
		||||
).wrappedJSObject;
 | 
			
		||||
 | 
			
		||||
if (!Zotero.AddonTemplate) {
 | 
			
		||||
  Zotero.AddonTemplate = new Addon();
 | 
			
		||||
  Zotero.AddonTemplate.events.onInit();
 | 
			
		||||
  Zotero.AddonTemplate.events.onInit(Zotero);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
import Addon from "./addon";
 | 
			
		||||
 | 
			
		||||
class AddonModule {
 | 
			
		||||
  protected _Addon: any;
 | 
			
		||||
  constructor(parent: any) {
 | 
			
		||||
  protected _Addon: Addon;
 | 
			
		||||
  constructor(parent: Addon) {
 | 
			
		||||
    this._Addon = parent;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										335
									
								
								src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								src/utils.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,335 @@
 | 
			
		||||
import Addon from "./addon";
 | 
			
		||||
import AddonModule from "./module";
 | 
			
		||||
 | 
			
		||||
class AddonUtils extends AddonModule {
 | 
			
		||||
  public Compat: ZoteroCompat;
 | 
			
		||||
  public Tool: ZoteroTool;
 | 
			
		||||
  public UI: ZoteroUI;
 | 
			
		||||
 | 
			
		||||
  constructor(parent: Addon) {
 | 
			
		||||
    super(parent);
 | 
			
		||||
    this.Compat = {
 | 
			
		||||
      // Get Zotero instance
 | 
			
		||||
      getZotero: () => {
 | 
			
		||||
        if (typeof Zotero === "undefined") {
 | 
			
		||||
          return Components.classes["@zotero.org/Zotero;1"].getService(
 | 
			
		||||
            Components.interfaces.nsISupports
 | 
			
		||||
          ).wrappedJSObject;
 | 
			
		||||
        }
 | 
			
		||||
        return Zotero;
 | 
			
		||||
      },
 | 
			
		||||
      // Check if it's running on Zotero 7 (Firefox 102)
 | 
			
		||||
      isZotero7: () => Zotero.platformMajorVersion >= 102,
 | 
			
		||||
      // Firefox 102 support DOMParser natively
 | 
			
		||||
      getDOMParser: () =>
 | 
			
		||||
        this.Compat.isZotero7()
 | 
			
		||||
          ? new DOMParser()
 | 
			
		||||
          : Components.classes[
 | 
			
		||||
              "@mozilla.org/xmlextras/domparser;1"
 | 
			
		||||
            ].createInstance(Components.interfaces.nsIDOMParser),
 | 
			
		||||
      // create XUL element
 | 
			
		||||
      createXULElement: (doc: Document, type: string) => {
 | 
			
		||||
        if (this.Compat.isZotero7()) {
 | 
			
		||||
          // @ts-ignore
 | 
			
		||||
          return doc.createXULElement(type);
 | 
			
		||||
        } else {
 | 
			
		||||
          return doc.createElementNS(
 | 
			
		||||
            "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
 | 
			
		||||
            type
 | 
			
		||||
          ) as XUL.Element;
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
    this.Tool = {
 | 
			
		||||
      getCopyHelper: () => new CopyHelper(),
 | 
			
		||||
      openFilePicker: (
 | 
			
		||||
        title: string,
 | 
			
		||||
        mode: "open" | "save" | "folder",
 | 
			
		||||
        filters?: [string, string][],
 | 
			
		||||
        suggestion?: string
 | 
			
		||||
      ) => {
 | 
			
		||||
        const fp = Components.classes[
 | 
			
		||||
          "@mozilla.org/filepicker;1"
 | 
			
		||||
        ].createInstance(Components.interfaces.nsIFilePicker);
 | 
			
		||||
 | 
			
		||||
        if (suggestion) fp.defaultString = suggestion;
 | 
			
		||||
 | 
			
		||||
        mode = {
 | 
			
		||||
          open: Components.interfaces.nsIFilePicker.modeOpen,
 | 
			
		||||
          save: Components.interfaces.nsIFilePicker.modeSave,
 | 
			
		||||
          folder: Components.interfaces.nsIFilePicker.modeGetFolder,
 | 
			
		||||
        }[mode];
 | 
			
		||||
 | 
			
		||||
        fp.init(window, title, mode);
 | 
			
		||||
 | 
			
		||||
        for (const [label, ext] of filters || []) {
 | 
			
		||||
          fp.appendFilter(label, ext);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-unsafe-return
 | 
			
		||||
        return new Promise((resolve) => {
 | 
			
		||||
          fp.open((userChoice) => {
 | 
			
		||||
            switch (userChoice) {
 | 
			
		||||
              case Components.interfaces.nsIFilePicker.returnOK:
 | 
			
		||||
              case Components.interfaces.nsIFilePicker.returnReplace:
 | 
			
		||||
                resolve(fp.file.path);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
              default: // aka returnCancel
 | 
			
		||||
                resolve("");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      },
 | 
			
		||||
      log: (...data: any[]) => {
 | 
			
		||||
        try {
 | 
			
		||||
          this._Addon.Zotero.getMainWindow().console.log(data);
 | 
			
		||||
          for (const d of data) {
 | 
			
		||||
            this._Addon.Zotero.debug(d);
 | 
			
		||||
          }
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          this._Addon.Zotero.debug(e);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
    this.UI = {
 | 
			
		||||
      createElement: (
 | 
			
		||||
        doc: Document,
 | 
			
		||||
        tagName: string,
 | 
			
		||||
        namespace: "html" | "svg" | "xul" = "html"
 | 
			
		||||
      ) => {
 | 
			
		||||
        namespace = namespace || "html";
 | 
			
		||||
        const namespaces = {
 | 
			
		||||
          html: "http://www.w3.org/1999/xhtml",
 | 
			
		||||
          svg: "http://www.w3.org/2000/svg",
 | 
			
		||||
        };
 | 
			
		||||
        if (tagName === "fragment") {
 | 
			
		||||
          return doc.createDocumentFragment();
 | 
			
		||||
        } else if (namespace === "xul") {
 | 
			
		||||
          return this.Compat.createXULElement(doc, tagName);
 | 
			
		||||
        } else {
 | 
			
		||||
          return doc.createElementNS(namespaces[namespace], tagName) as
 | 
			
		||||
            | HTMLElement
 | 
			
		||||
            | SVGAElement;
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      creatElementsFromJSON: (doc: Document, options: ElementOptions) => {
 | 
			
		||||
        this.Tool.log(options);
 | 
			
		||||
        if (
 | 
			
		||||
          options.id &&
 | 
			
		||||
          (options.checkExistanceParent
 | 
			
		||||
            ? options.checkExistanceParent
 | 
			
		||||
            : doc
 | 
			
		||||
          ).querySelector(`#${options.id}`)
 | 
			
		||||
        ) {
 | 
			
		||||
          if (options.ignoreIfExists) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
          }
 | 
			
		||||
          if (options.removeIfExists) {
 | 
			
		||||
            doc.querySelector(`#${options.id}`).remove();
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (options.customCheck && !options.customCheck()) {
 | 
			
		||||
          return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        const element = this.UI.createElement(
 | 
			
		||||
          doc,
 | 
			
		||||
          options.tag,
 | 
			
		||||
          options.namespace
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let _DocumentFragment: typeof DocumentFragment;
 | 
			
		||||
        if (typeof DocumentFragment === "undefined") {
 | 
			
		||||
          _DocumentFragment = (doc as any).ownerGlobal.DocumentFragment;
 | 
			
		||||
        } else {
 | 
			
		||||
          _DocumentFragment = DocumentFragment;
 | 
			
		||||
        }
 | 
			
		||||
        if (!(element instanceof _DocumentFragment)) {
 | 
			
		||||
          if (options.id) {
 | 
			
		||||
            element.id = options.id;
 | 
			
		||||
          }
 | 
			
		||||
          if (options.styles && Object.keys(options.styles).length) {
 | 
			
		||||
            Object.keys(options.styles).forEach((k) => {
 | 
			
		||||
              const v = options.styles[k];
 | 
			
		||||
              typeof v !== "undefined" && (element.style[k] = v);
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          if (
 | 
			
		||||
            options.directAttributes &&
 | 
			
		||||
            Object.keys(options.directAttributes).length
 | 
			
		||||
          ) {
 | 
			
		||||
            Object.keys(options.directAttributes).forEach((k) => {
 | 
			
		||||
              const v = options.directAttributes[k];
 | 
			
		||||
              typeof v !== "undefined" && (element[k] = v);
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          if (options.attributes && Object.keys(options.attributes).length) {
 | 
			
		||||
            Object.keys(options.attributes).forEach((k) => {
 | 
			
		||||
              const v = options.attributes[k];
 | 
			
		||||
              typeof v !== "undefined" && element.setAttribute(k, String(v));
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          if (options.listeners?.length) {
 | 
			
		||||
            options.listeners.forEach(([type, cbk, option]) => {
 | 
			
		||||
              typeof cbk !== "undefined" &&
 | 
			
		||||
                element.addEventListener(type, cbk, option);
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (options.subElementOptions?.length) {
 | 
			
		||||
          const subElements = options.subElementOptions
 | 
			
		||||
            .map((_options) => this.UI.creatElementsFromJSON(doc, _options))
 | 
			
		||||
            .filter((e) => e);
 | 
			
		||||
          element.append(...subElements);
 | 
			
		||||
        }
 | 
			
		||||
        return element;
 | 
			
		||||
      },
 | 
			
		||||
      defaultMenuPopupSelectors: {
 | 
			
		||||
        menuFile: "#menu_FilePopup",
 | 
			
		||||
        menuEdit: "#menu_EditPopup",
 | 
			
		||||
        menuView: "#menu_viewPopup",
 | 
			
		||||
        menuGo: "#menu_goPopup",
 | 
			
		||||
        menuTools: "#menu_ToolsPopup",
 | 
			
		||||
        menuHelp: "#menu_HelpPopup",
 | 
			
		||||
        collection: "#zotero-collectionmenu",
 | 
			
		||||
        item: "#zotero-itemmenu",
 | 
			
		||||
      },
 | 
			
		||||
      insertMenuItem: (
 | 
			
		||||
        menuPopup: XUL.Menupopup | string,
 | 
			
		||||
        options: MenuitemOptions,
 | 
			
		||||
        insertPosition: "before" | "after" = "after",
 | 
			
		||||
        anchorElement: XUL.Element = undefined
 | 
			
		||||
      ) => {
 | 
			
		||||
        const Zotero = this.Compat.getZotero();
 | 
			
		||||
        let popup: XUL.Menupopup;
 | 
			
		||||
        if (typeof menuPopup === "string") {
 | 
			
		||||
          if (
 | 
			
		||||
            !Object.keys(this.UI.defaultMenuPopupSelectors).includes(menuPopup)
 | 
			
		||||
          ) {
 | 
			
		||||
            return false;
 | 
			
		||||
          } else {
 | 
			
		||||
            popup = (Zotero.getMainWindow() as Window).document.querySelector(
 | 
			
		||||
              this.UI.defaultMenuPopupSelectors[menuPopup]
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          popup = menuPopup;
 | 
			
		||||
        }
 | 
			
		||||
        if (!popup) {
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
        const doc: Document = popup.ownerDocument;
 | 
			
		||||
        const generateElementOptions = (
 | 
			
		||||
          menuitemOption: MenuitemOptions
 | 
			
		||||
        ): ElementOptions => {
 | 
			
		||||
          let elementOption: ElementOptions = {
 | 
			
		||||
            tag: menuitemOption.tag,
 | 
			
		||||
            id: menuitemOption.id,
 | 
			
		||||
            namespace: "xul",
 | 
			
		||||
            attributes: {
 | 
			
		||||
              label: menuitemOption.label,
 | 
			
		||||
              hidden: Boolean(menuitemOption.hidden),
 | 
			
		||||
              disaled: Boolean(menuitemOption.disabled),
 | 
			
		||||
              class: menuitemOption.class || "",
 | 
			
		||||
              oncommand: menuitemOption.oncommand,
 | 
			
		||||
            },
 | 
			
		||||
            styles: menuitemOption.styles || {},
 | 
			
		||||
            listeners: [["command", menuitemOption.commandListener]],
 | 
			
		||||
            subElementOptions: [],
 | 
			
		||||
          };
 | 
			
		||||
          if (menuitemOption.icon) {
 | 
			
		||||
            elementOption.attributes["class"] += " menuitem-iconic";
 | 
			
		||||
            elementOption.styles[
 | 
			
		||||
              "list-style-image"
 | 
			
		||||
            ] = `url(${menuitemOption.icon})`;
 | 
			
		||||
          }
 | 
			
		||||
          if (menuitemOption.tag === "menu") {
 | 
			
		||||
            elementOption.subElementOptions.push({
 | 
			
		||||
              tag: "menupopup",
 | 
			
		||||
              id: menuitemOption.popupId,
 | 
			
		||||
              namespace: "xul",
 | 
			
		||||
              attributes: { onpopupshowing: menuitemOption.onpopupshowing },
 | 
			
		||||
              subElementOptions: menuitemOption.subElementOptions.map(
 | 
			
		||||
                generateElementOptions
 | 
			
		||||
              ),
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          return elementOption;
 | 
			
		||||
        };
 | 
			
		||||
        const menuItem = this.UI.creatElementsFromJSON(
 | 
			
		||||
          doc,
 | 
			
		||||
          generateElementOptions(options)
 | 
			
		||||
        );
 | 
			
		||||
        if (!anchorElement) {
 | 
			
		||||
          anchorElement = (
 | 
			
		||||
            insertPosition === "after"
 | 
			
		||||
              ? popup.lastElementChild
 | 
			
		||||
              : popup.firstElementChild
 | 
			
		||||
          ) as XUL.Element;
 | 
			
		||||
        }
 | 
			
		||||
        anchorElement[insertPosition](menuItem);
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CopyHelper {
 | 
			
		||||
  private transferable: any;
 | 
			
		||||
  private clipboardService: any;
 | 
			
		||||
 | 
			
		||||
  constructor() {
 | 
			
		||||
    this.transferable = Components.classes[
 | 
			
		||||
      "@mozilla.org/widget/transferable;1"
 | 
			
		||||
    ].createInstance(Components.interfaces.nsITransferable);
 | 
			
		||||
    this.clipboardService = Components.classes[
 | 
			
		||||
      "@mozilla.org/widget/clipboard;1"
 | 
			
		||||
    ].getService(Components.interfaces.nsIClipboard);
 | 
			
		||||
    this.transferable.init(null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public addText(source: string, type: "text/html" | "text/unicode") {
 | 
			
		||||
    const str = Components.classes[
 | 
			
		||||
      "@mozilla.org/supports-string;1"
 | 
			
		||||
    ].createInstance(Components.interfaces.nsISupportsString);
 | 
			
		||||
    str.data = source;
 | 
			
		||||
    this.transferable.addDataFlavor(type);
 | 
			
		||||
    this.transferable.setTransferData(type, str, source.length * 2);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public addImage(source: string) {
 | 
			
		||||
    let parts = source.split(",");
 | 
			
		||||
    if (!parts[0].includes("base64")) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    let mime = parts[0].match(/:(.*?);/)[1];
 | 
			
		||||
    let bstr = atob(parts[1]);
 | 
			
		||||
    let n = bstr.length;
 | 
			
		||||
    let u8arr = new Uint8Array(n);
 | 
			
		||||
    while (n--) {
 | 
			
		||||
      u8arr[n] = bstr.charCodeAt(n);
 | 
			
		||||
    }
 | 
			
		||||
    let imgTools = Components.classes["@mozilla.org/image/tools;1"].getService(
 | 
			
		||||
      Components.interfaces.imgITools
 | 
			
		||||
    );
 | 
			
		||||
    let imgPtr = Components.classes[
 | 
			
		||||
      "@mozilla.org/supports-interface-pointer;1"
 | 
			
		||||
    ].createInstance(Components.interfaces.nsISupportsInterfacePointer);
 | 
			
		||||
    imgPtr.data = imgTools.decodeImageFromArrayBuffer(u8arr.buffer, mime);
 | 
			
		||||
    this.transferable.addDataFlavor(mime);
 | 
			
		||||
    this.transferable.setTransferData(mime, imgPtr, 0);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public copy() {
 | 
			
		||||
    this.clipboardService.setData(
 | 
			
		||||
      this.transferable,
 | 
			
		||||
      null,
 | 
			
		||||
      Components.interfaces.nsIClipboard.kGlobalClipboard
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AddonUtils;
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "module": "commonjs",
 | 
			
		||||
    "target": "es6",
 | 
			
		||||
    "resolveJsonModule": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": [
 | 
			
		||||
    "src",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								typing/global.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								typing/global.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
declare interface ZoteroCompat {
 | 
			
		||||
  getZotero: () => _ZoteroConstructable;
 | 
			
		||||
  isZotero7: () => boolean;
 | 
			
		||||
  getDOMParser: () => DOMParser;
 | 
			
		||||
  createXULElement: (doc: Document, type: string) => XUL.Element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare interface ZoteroTool {
 | 
			
		||||
  getCopyHelper: () => CopyHelper;
 | 
			
		||||
  openFilePicker: (
 | 
			
		||||
    title: string,
 | 
			
		||||
    mode: "open" | "save" | "folder",
 | 
			
		||||
    filters?: [string, string][],
 | 
			
		||||
    suggestion?: string
 | 
			
		||||
  ) => Promise<string>;
 | 
			
		||||
  log: (...data: any[]) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare interface ZoteroUI {
 | 
			
		||||
  createElement: (
 | 
			
		||||
    doc: Document,
 | 
			
		||||
    tagName: string,
 | 
			
		||||
    namespace: "html" | "svg" | "xul"
 | 
			
		||||
  ) => XUL.Element | DocumentFragment | HTMLElement | SVGAElement;
 | 
			
		||||
  creatElementsFromJSON: (
 | 
			
		||||
    doc: Document,
 | 
			
		||||
    options: ElementOptions
 | 
			
		||||
  ) => XUL.Element | DocumentFragment | HTMLElement | SVGAElement;
 | 
			
		||||
  defaultMenuPopupSelectors: {
 | 
			
		||||
    [key: string]: string;
 | 
			
		||||
  };
 | 
			
		||||
  insertMenuItem: (
 | 
			
		||||
    menuPopup: XUL.Menupopup | string,
 | 
			
		||||
    options: MenuitemOptions,
 | 
			
		||||
    insertPosition?: "before" | "after",
 | 
			
		||||
    anchorElement?: XUL.Element
 | 
			
		||||
  ) => boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare interface ElementOptions {
 | 
			
		||||
  tag: string;
 | 
			
		||||
  id?: string;
 | 
			
		||||
  namespace?: "html" | "svg" | "xul";
 | 
			
		||||
  styles?: { [key: string]: string };
 | 
			
		||||
  directAttributes?: { [key: string]: string | boolean | number };
 | 
			
		||||
  attributes?: { [key: string]: string | boolean | number };
 | 
			
		||||
  listeners?: Array<
 | 
			
		||||
    | [
 | 
			
		||||
        string,
 | 
			
		||||
        EventListenerOrEventListenerObject,
 | 
			
		||||
        boolean | AddEventListenerOptions
 | 
			
		||||
      ]
 | 
			
		||||
    | [string, EventListenerOrEventListenerObject]
 | 
			
		||||
  >;
 | 
			
		||||
  checkExistanceParent?: HTMLElement;
 | 
			
		||||
  ignoreIfExists?: boolean;
 | 
			
		||||
  removeIfExists?: boolean;
 | 
			
		||||
  customCheck?: () => boolean;
 | 
			
		||||
  subElementOptions?: Array<ElementOptions>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare interface MenuitemOptions {
 | 
			
		||||
  tag: "menuitem" | "menu";
 | 
			
		||||
  id?: string;
 | 
			
		||||
  label: string;
 | 
			
		||||
  // data url (chrome://xxx.png) or base64 url (data:image/png;base64,xxx)
 | 
			
		||||
  icon?: string;
 | 
			
		||||
  class?: string;
 | 
			
		||||
  styles?: { [key: string]: string };
 | 
			
		||||
  hidden?: boolean;
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
  oncommand?: string;
 | 
			
		||||
  commandListener?: EventListenerOrEventListenerObject;
 | 
			
		||||
  // Attributes below are used when type === "menu"
 | 
			
		||||
  popupId?: string;
 | 
			
		||||
  onpopupshowing?: string;
 | 
			
		||||
  subElementOptions?: Array<MenuitemOptions>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare class CopyHelper {
 | 
			
		||||
  addText: (source: string, type: "text/html" | "text/unicode") => CopyHelper;
 | 
			
		||||
  addImage: (source: string) => CopyHelper;
 | 
			
		||||
  copy: () => void;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user