Skip to content

Commit

Permalink
Add experimental support for hydrating from static
Browse files Browse the repository at this point in the history
* Also tweaked citeproc-wrapper so that CSL/Driver can be optionally
  provided to the constructor.
  • Loading branch information
tnajdek committed Jul 30, 2021
1 parent 828ce9a commit 90d8b9b
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 23 deletions.
6 changes: 4 additions & 2 deletions src/js/bib-component.jsx
Expand Up @@ -28,12 +28,14 @@ ErrorBoundary.propTypes = {
class ZoteroBibComponent extends React.Component {
render() {
return (
<ErrorBoundary><Container config = { this.props.config } /></ErrorBoundary>
<ErrorBoundary><Container {...this.props } /></ErrorBoundary>
);
}

static init(domEl, config={}) {
ReactDOM.render(<ZoteroBibComponent config={ config } />, domEl);
'hydrateItemsCount' in domEl.dataset ?
ReactDOM.hydrate(<ZoteroBibComponent hydrateItemsCount={ domEl.dataset.hydrateItemsCount } config={ config } />, domEl) :
ReactDOM.render(<ZoteroBibComponent config={ config } />, domEl);
}

static propTypes = {
Expand Down
16 changes: 10 additions & 6 deletions src/js/citeproc-wrapper.js
Expand Up @@ -358,23 +358,27 @@ const getCiteprocRSLoader = async () => {
});
}

CiteprocWrapper.new = async ({ style, format = 'html', lang = null, wrap_url_and_doi = false }, useLegacy = null) => {
CiteprocWrapper.new = async ({ style, format = 'html', lang = null, wrap_url_and_doi = false }, useLegacy = null, DriverORCSL = null) => {
lang = lang ? lang : window ? window.navigator.userLanguage || window.navigator.language : null;
useLegacy = useLegacy === null ? !isWasmSupported : useLegacy;

try {
if(useLegacy) {
const CSL = await getCSL();
const CSL = DriverORCSL ?? await getCSL();
if(format === 'plain') {
format = 'text';
}
return new CiteprocWrapper(true, CSL, { style, format, lang, wrap_url_and_doi });
} else {
if(!Driver) {
const citeprocLoader = await getCiteprocRSLoader();
const { init, CreateDriver } = await citeprocLoader();
Driver = CreateDriver;
await init();
if(DriverORCSL) {
Driver = DriverORCSL;
} else {
const citeprocLoader = await getCiteprocRSLoader();
const { init, CreateDriver } = await citeprocLoader();
Driver = CreateDriver;
await init();
}
}
const fetcher = new Fetcher();
// NOTE: wrap_url_and_doi is not supported in citeproc rs (yet?)
Expand Down
11 changes: 9 additions & 2 deletions src/js/components/bibliography.jsx
Expand Up @@ -186,9 +186,16 @@ const Bibliography = props => {
<React.Fragment>
{ isReadOnly ? (
<React.Fragment>
<div className="bibliography read-only" dangerouslySetInnerHTML={ { __html: bibliographyRendered } } />
<div
suppressHydrationWarning={ true }
className="bibliography read-only"
dangerouslySetInnerHTML={ { __html: bibliographyRendered } }
/>
{ bibliography.items.map(renderedItem => (
<script key={ renderedItem.id } type="application/vnd.zotero.data+json">
<script
suppressHydrationWarning={ true }
key={ renderedItem.id }
type="application/vnd.zotero.data+json">
{ JSON.stringify(bibliography.lookup[renderedItem.id]) }
</script>
)) }
Expand Down
21 changes: 12 additions & 9 deletions src/js/components/bibliographySection.jsx
Expand Up @@ -13,7 +13,8 @@ import StyleSelector from './style-selector';
import { pick } from '../immutable'

const BibliographySection = props => {
const { bibliography, isReadOnly, isReady, localCitationsCount, onOverride, onTitleChanged, title } = props;
const { bibliography, isReadOnly, isReady, hydrateItemsCount, isHydrated, localCitationsCount,
onOverride, onTitleChanged, title } = props;
const [isConfirmingOverride, setIsConfirmingOverride] = useState(false);
const [isEditingTitle, setIsEditingTitle] = useState(false);

Expand Down Expand Up @@ -51,10 +52,10 @@ const BibliographySection = props => {
return (
<section
className={ cx('section', 'section-bibliography',
{ 'loading': !isReady, 'empty': isReady && bibliography.items.length === 0 })
{ 'loading': !isReady && !isHydrated, 'empty': isReady && bibliography.items.length === 0 })
}
>
<div className="container">
<div className="container" suppressHydrationWarning={ true }>
{ (isReady && bibliography.items.length === 0) ? (
<React.Fragment>
<img className="empty-bibliography" src="static/images/empty-bibliography.svg" width="320" height="200" />
Expand Down Expand Up @@ -93,17 +94,19 @@ const BibliographySection = props => {
!isReadOnly && <StyleSelector { ...pick(props, ['citationStyle', 'citationStyles', 'onCitationStyleChanged']) } />
}
{
isReady ? <Bibliography { ...pick(props, ['isNoteStyle',
'isNumericStyle', 'isReadOnly', 'bibliography',
'onCitationCopyDialogOpen', 'onDeleteEntry', 'onEditorOpen',
'styleHasBibliography'])} /> : (
(isReady || isHydrated) ? <Bibliography { ...pick(props,
['isNoteStyle', 'isNumericStyle', 'hydrateItemsCount', 'isHydrated', 'isReadOnly',
'bibliography', 'onCitationCopyDialogOpen', 'onDeleteEntry',
'onEditorOpen', 'styleHasBibliography'])} /> : (
<div className="spinner-container">
<Spinner />
</div>
)
}
{
!isReadOnly && isReady && <DeleteAllButton { ...pick(props, ['bibliography', 'onDeleteCitations']) } />
!isReadOnly && (isReady || isHydrated) && (
<DeleteAllButton { ...pick(props, ['bibliography', 'onDeleteCitations']) } />
)
}
<Confirmation
isOpen={ isReadOnly && isConfirmingOverride }
Expand All @@ -119,7 +122,7 @@ const BibliographySection = props => {
</React.Fragment>
)
}
{ (isReady && isReadOnly) && (
{ ((isReady || isHydrated) && isReadOnly) && (
<Button
onClick={ handleEditBibliography }
className="btn-sm btn-outline-secondary">
Expand Down
12 changes: 11 additions & 1 deletion src/js/components/container.jsx
Expand Up @@ -142,6 +142,12 @@ const BibWebContainer = props => {
const [activeDialog, setActiveDialog] = useState(null);
const wasDataReady = usePrevious(isDataReady);
const isReadOnly = !!remoteId;
const hydrateItemsCount = props.hydrateItemsCount;
const isHydrated = typeof props.hydrateItemsCount !== 'undefined';

if(isHydrated && !isReadOnly) {
throw new Error(`BibWebContainer bootstrapped incorrectly. RemoteID must be present to hydrate. Path: ${window.location.pathname}`);
}

const [state, dispatch] = useReducer(reducer, {
selected: undefined,
Expand All @@ -153,7 +159,9 @@ const BibWebContainer = props => {
isUppercaseSubtitlesStyle: undefined,
isSentenceCaseStyle: undefined,
isConfirmed: undefined,
bibliography: { items: [], meta: null, lookup: {} },
bibliography: isHydrated ?
{ items: Array(hydrateItemsCount).fill().map((_, id) => ({ id, value: '' })), meta: null, lookup: {} } :
{ items: [], meta: null, lookup: {} },
bibliographyNeedsRefresh: false,
bibliographyNeedsRebuild: false,
isCiteprocReady: false,
Expand Down Expand Up @@ -1102,10 +1110,12 @@ const BibWebContainer = props => {
citationStyle = { state.selected }
citationStyles = { citationStyles }
editorItem = { editorItem }
hydrateItemsCount={ hydrateItemsCount }
identifier = { identifier }
isNoteStyle = { state.isNoteStyle }
isNumericStyle = { state.isNumericStyle }
isReadOnly={ isReadOnly }
isHydrated={ isHydrated }
isReady={ isReady }
isStylesDataLoading = { isStylesDataLoading }
isTranslating={ isTranslating }
Expand Down
7 changes: 4 additions & 3 deletions src/js/components/zbib.jsx
Expand Up @@ -74,9 +74,10 @@ class ZBib extends React.PureComponent {
)}
<BibliographySection { ...pick(this.props, ['bibliography', 'isReadOnly',
'isReady', 'localCitationsCount', 'onOverride', 'onTitleChanged', 'title',
'citationStyle', 'citationStyles', 'onCitationStyleChanged', 'isNoteStyle',
'isNumericStyle', 'onCitationCopyDialogOpen', 'onDeleteEntry',
'onDeleteCitations', 'onEditorOpen', 'styleHasBibliography']) }
'citationStyle', 'citationStyles', 'onCitationStyleChanged', 'isHydrated',
'isNoteStyle', 'isNumericStyle', 'onCitationCopyDialogOpen',
'onDeleteEntry', 'onDeleteCitations', 'onEditorOpen',
'styleHasBibliography']) }
/>
{
<section className="section section-export">
Expand Down

0 comments on commit 90d8b9b

Please sign in to comment.