Skip to content

Commit

Permalink
Dynamically import react-dom in overlay to fix PID row text input bug
Browse files Browse the repository at this point in the history
Was getting error`activeElement.detachEvent is not a function`
  • Loading branch information
Dominic-DallOsto committed Aug 26, 2024
1 parent 6e2018e commit f1792e7
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 60 deletions.
15 changes: 10 additions & 5 deletions src/cita/zoteroOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import LCN from "./localCitationNetwork";
import OCI from "../oci";
import OpenCitations from "./opencitations";
import * as React from "react";
// https://react.dev/blog/2022/03/08/react-18-upgrade-guide#updates-to-client-rendering-apis
import { Root, createRoot } from "react-dom/client";
import SourceItemWrapper from "./sourceItemWrapper";
import WikiciteChrome from "./wikiciteChrome";
import Wikidata from "./wikidata";
Expand Down Expand Up @@ -561,10 +559,15 @@ class ZoteroOverlay {
// Item pane functions
/******************************************/
// Create XUL for Zotero item pane
citationsPane() {
async citationsPane() {
// import react-dom dynamically otherwise it's imported before window is defined
// and we get errors like https://github.com/capricorn86/happy-dom/issues/534
// when clicking on text inputs in PID rows
const { createRoot } = await import("react-dom/client");
// todo: remove when unloading
const citationBoxRoots: {
[id: string]: Root;
// todo: how do I get the Root type from the dynamically imported react-dom?
[id: string]: any;
} = {};
Zotero.ItemPaneManager.registerSection({
paneID: "zotero-editpane-citations-tab",
Expand Down Expand Up @@ -594,7 +597,9 @@ class ZoteroOverlay {
// Use Fluent for localization
// As mentioned in https://groups.google.com/g/zotero-dev/c/wirqnj_EQUQ/m/ud3k0SpMAAAJ
// As seen in https://github.com/zotero/make-it-red/blob/5a7ee1be2f147a327220c1e5a4129d6c6169999c/src-2.0/make-it-red.js#L33
window.MozXULElement.insertFTLIfNeeded(`${config.addonRef}-addon.ftl`);
window.MozXULElement.insertFTLIfNeeded(
`${config.addonRef}-addon.ftl`,
);

if (!item.isRegularItem()) {
return;
Expand Down
61 changes: 6 additions & 55 deletions src/components/pidRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import * as React from "react";
import { useEffect, useRef, useState } from "react";
import * as PropTypes from "prop-types";
// import Editable from "zotero@components/editable";
import ItemWrapper from "../cita/itemWrapper";

function PIDRow(props: {
Expand All @@ -12,8 +11,6 @@ function PIDRow(props: {
type: PIDType;
validate: (type: PIDType, value: string) => boolean;
}) {
const textboxRef = useRef(null);
const [selected, setSelected] = useState(false);
const [value, setValue] = useState(props.item.getPID(props.type));
const [url, setUrl] = useState(props.item.getPidUrl(props.type));

Expand All @@ -25,17 +22,9 @@ function PIDRow(props: {
setUrl(props.item.getPidUrl(props.type));
}, [props.type, value]);

function handleCancel() {
setSelected(false);
}

function handleCommit(newPid: string, hasChanged: boolean) {
if (hasChanged) {
if (
newPid &&
props.validate &&
!props.validate(props.type, newPid)
) {
function handleCommit(newPid: string) {
if (newPid != value) {
if (props.validate && !props.validate(props.type, newPid)) {
return;
}
props.item.setPID(props.type, newPid, props.autosave);
Expand All @@ -44,14 +33,6 @@ function PIDRow(props: {
// but second time (via props.item) might take some time
setValue(props.item.getPID(props.type));
}
setSelected(false);
}

function handleEdit() {
if (!props.editable) {
return;
}
setSelected(true);
}

async function onFetch() {
Expand All @@ -69,43 +50,13 @@ function PIDRow(props: {
{props.type.toUpperCase()}
</label>
<div className="editable-container">
{/* Causes a warning, because Input uses componentWillReceiveProps
which has been renamed and is not recommended. But won't show
in non-strict mode because Zotero devs renamed it to UNSAFE_*/}
{/* <Editable */}
{/* fix: replaced Editable with input until we work out how to import zotero components */}

This comment has been minimized.

Copy link
@diegodlh

diegodlh Sep 10, 2024

Owner

Hey, @Dominic-DallOsto! Would there be an advantage of using Zotero's Editable component? Would it make sense to remind ourselves to try and switch to it if we find out how to import Zotero components? Maybe leave this comment here or open a new task?

This comment has been minimized.

Copy link
@Dominic-DallOsto

Dominic-DallOsto Sep 17, 2024

Author Collaborator

Yeah, I'm not sure. In principle this shouldn't be that complicated - we just want an input where the user can enter the QID / DOI / et c. so I don't know if the Editable component is essential.

On the other hand, there seem to be a few bugs that you found with the PID rows still. Maybe if we can't get them easily ironed out, it'd be worth trying to switch back to using the Editable component. But otherwise, I think we can get a normal input to do everything we want?

<input
type="text"
// There is a bug in Zotero's React Input component
// Its handleChange event is waiting for an options
// parameter from the child input element's onChange
// event. This is provided by the custom input element
// Autosuggest, but not by the regular HTML input.
// This doesn't happen with TextArea, because its
// handleChange doesn't expect an options parameter.
// autoComplete={true}
// For the autoComplete workaround to work above,
// a getSuggestions function must be provided.
// Have it return an empty suggestions array.
// getSuggestions={(): any => []}
// ...and a ref too
// ref={textboxRef}
// autoFocus
className={
props.editable && !selected ? "zotero-clicky" : ""
}
// isActive={selected}
// isReadOnly={!props.editable}
className={props.editable ? "zotero-clicky" : ""}
readOnly={!props.editable}
// onAbort={handleCancel}
// onCancel={handleCancel}
// onClick={handleEdit}
// onCommit={handleCommit}
// onFocus={handleEdit}
// onPaste={handlePaste} // what happens if I paste multiline?
// selectOnFocus={true}

defaultValue={value || ""}
// when the input loses focus, update the item's PID
onBlur={(event) => handleCommit(event.target.value)}
/>
</div>
<button onClick={() => onFetch()}>
Expand Down

0 comments on commit f1792e7

Please sign in to comment.